diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..6f41a5f --- /dev/null +++ b/build.sh @@ -0,0 +1,13 @@ +#!/bin/bash +red=`tput setaf 1` +green=`tput setaf 2` +reset=`tput sgr0` + +echo "Building ${green}contact_printer${reset} project..." +#build OpenSCAD models + +while read m; do + echo $m +done < models.txt + +#run client tests? diff --git a/clients/electron_app/.gitignore b/clients/electron_app/.gitignore new file mode 100644 index 0000000..6907f0e --- /dev/null +++ b/clients/electron_app/.gitignore @@ -0,0 +1,2 @@ +node_modules/* +data/*.json diff --git a/clients/electron_app/css/app.css b/clients/electron_app/css/app.css new file mode 100644 index 0000000..fcf42df --- /dev/null +++ b/clients/electron_app/css/app.css @@ -0,0 +1,18 @@ +footer{ + position:fixed; + bottom:0; + left:0; + right:0; +} +.window-content{ + background:#2f2f2f; + height:100%; + display:block; +} +progress{ + width: 95%; + margin-left: 2.5%; +} +#buttons{ + margin: 5%; +} \ No newline at end of file diff --git a/clients/electron_app/css/photon.css b/clients/electron_app/css/photon.css new file mode 100644 index 0000000..df5b944 --- /dev/null +++ b/clients/electron_app/css/photon.css @@ -0,0 +1,2354 @@ +/*! + * ===================================================== + * Photon v0.1.2 + * Copyright 2016 Connor Sears + * Licensed under MIT (https://github.com/connors/proton/blob/master/LICENSE) + * + * v0.1.2 designed by @connors. + * ===================================================== + */ + +@charset "UTF-8"; +audio, +canvas, +progress, +video { + vertical-align: baseline; +} + +audio:not([controls]) { + display: none; +} + +a:active, +a:hover { + outline: 0; +} + +abbr[title] { + border-bottom: 1px dotted; +} + +b, +strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +small { + font-size: 80%; +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +pre { + overflow: auto; +} + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +input[type="search"] { + -webkit-appearance: textfield; + box-sizing: content-box; +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +legend { + border: 0; + padding: 0; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +* { + cursor: default; + -webkit-user-select: none; +} + +input, +textarea { + -webkit-user-select: text; +} + +form, +input, +optgroup, +select, +textarea { + -webkit-user-select: text; + -webkit-app-region: no-drag; +} + +* { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +html { + height: 100%; + width: 100%; + overflow: hidden; +} + +body { + height: 100%; + padding: 0; + margin: 0; + font-family: system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", Helvetica, "Segoe UI", sans-serif; + font-size: 13px; + line-height: 1.6; + color: #333; + background-color: transparent; +} + +hr { + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 20px; + margin-bottom: 10px; + font-weight: 500; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +h1 { + font-size: 36px; +} + +h2 { + font-size: 30px; +} + +h3 { + font-size: 24px; +} + +h4 { + font-size: 18px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 12px; +} + +.window { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + flex-direction: column; + background-color: #fff; +} + +.window-content { + position: relative; + overflow-y: auto; + display: flex; + flex: 1; +} + +.selectable-text { + cursor: text; + -webkit-user-select: text; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.text-left { + text-align: left; +} + +.pull-left { + float: left; +} + +.pull-right { + float: right; +} + +.padded { + padding: 10px; +} + +.padded-less { + padding: 5px; +} + +.padded-more { + padding: 20px; +} + +.padded-vertically { + padding-top: 10px; + padding-bottom: 10px; +} + +.padded-vertically-less { + padding-top: 5px; + padding-bottom: 5px; +} + +.padded-vertically-more { + padding-top: 20px; + padding-bottom: 20px; +} + +.padded-horizontally { + padding-right: 10px; + padding-left: 10px; +} + +.padded-horizontally-less { + padding-right: 5px; + padding-left: 5px; +} + +.padded-horizontally-more { + padding-right: 20px; + padding-left: 20px; +} + +.padded-top { + padding-top: 10px; +} + +.padded-top-less { + padding-top: 5px; +} + +.padded-top-more { + padding-top: 20px; +} + +.padded-bottom { + padding-bottom: 10px; +} + +.padded-bottom-less { + padding-bottom: 5px; +} + +.padded-bottom-more { + padding-bottom: 20px; +} + +.sidebar { + background-color: #f5f5f4; +} + +.draggable { + -webkit-app-region: drag; +} + +.not-draggable { + -webkit-app-region: no-drag; +} + +.clearfix:before, .clearfix:after { + display: table; + content: " "; +} +.clearfix:after { + clear: both; +} + +.btn { + display: inline-block; + padding: 3px 8px; + margin-bottom: 0; + font-size: 12px; + line-height: 1.4; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: default; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06); + -webkit-app-region: no-drag; +} +.btn:focus { + outline: none; + box-shadow: none; +} + +.btn-mini { + padding: 2px 6px; +} + +.btn-large { + padding: 6px 12px; +} + +.btn-form { + padding-right: 20px; + padding-left: 20px; +} + +.btn-default { + color: #333; + border-top-color: #c2c0c2; + border-right-color: #c2c0c2; + border-bottom-color: #a19fa1; + border-left-color: #c2c0c2; + background-color: #fcfcfc; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fcfcfc), color-stop(100%, #f1f1f1)); + background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%); + background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%); +} +.btn-default:active { + background-color: #ddd; + background-image: none; +} + +.btn-primary, +.btn-positive, +.btn-negative, +.btn-warning { + color: #fff; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +.btn-primary { + border-color: #388df8; + border-bottom-color: #0866dc; + background-color: #6eb4f7; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6eb4f7), color-stop(100%, #1a82fb)); + background-image: -webkit-linear-gradient(top, #6eb4f7 0%, #1a82fb 100%); + background-image: linear-gradient(to bottom, #6eb4f7 0%, #1a82fb 100%); +} +.btn-primary:active { + background-color: #3e9bf4; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3e9bf4), color-stop(100%, #0469de)); + background-image: -webkit-linear-gradient(top, #3e9bf4 0%, #0469de 100%); + background-image: linear-gradient(to bottom, #3e9bf4 0%, #0469de 100%); +} + +.btn-positive { + border-color: #29a03b; + border-bottom-color: #248b34; + background-color: #5bd46d; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bd46d), color-stop(100%, #29a03b)); + background-image: -webkit-linear-gradient(top, #5bd46d 0%, #29a03b 100%); + background-image: linear-gradient(to bottom, #5bd46d 0%, #29a03b 100%); +} +.btn-positive:active { + background-color: #34c84a; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #34c84a), color-stop(100%, #248b34)); + background-image: -webkit-linear-gradient(top, #34c84a 0%, #248b34 100%); + background-image: linear-gradient(to bottom, #34c84a 0%, #248b34 100%); +} + +.btn-negative { + border-color: #fb2f29; + border-bottom-color: #fb1710; + background-color: #fd918d; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fd918d), color-stop(100%, #fb2f29)); + background-image: -webkit-linear-gradient(top, #fd918d 0%, #fb2f29 100%); + background-image: linear-gradient(to bottom, #fd918d 0%, #fb2f29 100%); +} +.btn-negative:active { + background-color: #fc605b; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fc605b), color-stop(100%, #fb1710)); + background-image: -webkit-linear-gradient(top, #fc605b 0%, #fb1710 100%); + background-image: linear-gradient(to bottom, #fc605b 0%, #fb1710 100%); +} + +.btn-warning { + border-color: #fcaa0e; + border-bottom-color: #ee9d02; + background-color: #fece72; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fece72), color-stop(100%, #fcaa0e)); + background-image: -webkit-linear-gradient(top, #fece72 0%, #fcaa0e 100%); + background-image: linear-gradient(to bottom, #fece72 0%, #fcaa0e 100%); +} +.btn-warning:active { + background-color: #fdbc40; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fdbc40), color-stop(100%, #ee9d02)); + background-image: -webkit-linear-gradient(top, #fdbc40 0%, #ee9d02 100%); + background-image: linear-gradient(to bottom, #fdbc40 0%, #ee9d02 100%); +} + +.btn .icon { + float: left; + width: 14px; + height: 14px; + margin-top: 1px; + margin-bottom: 1px; + color: #737475; + font-size: 14px; + line-height: 1; +} + +.btn .icon-text { + margin-right: 5px; +} + +.btn-dropdown:after { + font-family: "photon-entypo"; + margin-left: 5px; + content: '\e873'; +} + +.btn-group { + position: relative; + display: inline-block; + vertical-align: middle; + -webkit-app-region: no-drag; +} +.btn-group .btn { + position: relative; + float: left; +} +.btn-group .btn:focus, .btn-group .btn:active { + z-index: 2; +} +.btn-group .btn.active { + z-index: 3; +} + +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-group > .btn:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group .btn + .btn { + border-left: 1px solid #c2c0c2; +} +.btn-group .btn + .btn.active { + border-left: 0; +} +.btn-group .active { + color: #fff; + border: 1px solid transparent; + background-color: #6d6c6d; + background-image: none; +} +.btn-group .active .icon { + color: #fff; +} + +.toolbar { + min-height: 22px; + box-shadow: inset 0 1px 0 #f5f4f5; + background-color: #e8e6e8; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e8e6e8), color-stop(100%, #d1cfd1)); + background-image: -webkit-linear-gradient(top, #e8e6e8 0%, #d1cfd1 100%); + background-image: linear-gradient(to bottom, #e8e6e8 0%, #d1cfd1 100%); +} +.toolbar:before, .toolbar:after { + display: table; + content: " "; +} +.toolbar:after { + clear: both; +} + +.toolbar-header { + border-bottom: 1px solid #c2c0c2; +} +.toolbar-header .title { + margin-top: 1px; +} + +.toolbar-footer { + border-top: 1px solid #c2c0c2; + -webkit-app-region: drag; +} + +.title { + margin: 0; + font-size: 12px; + font-weight: 400; + text-align: center; + color: #555; + cursor: default; +} + +.toolbar-borderless { + border-top: 0; + border-bottom: 0; +} + +.toolbar-actions { + margin-top: 4px; + margin-bottom: 3px; + padding-right: 3px; + padding-left: 3px; + padding-bottom: 3px; + -webkit-app-region: drag; +} +.toolbar-actions:before, .toolbar-actions:after { + display: table; + content: " "; +} +.toolbar-actions:after { + clear: both; +} +.toolbar-actions > .btn, +.toolbar-actions > .btn-group { + margin-left: 4px; + margin-right: 4px; +} + +label { + display: inline-block; + font-size: 13px; + margin-bottom: 5px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +input[type="search"] { + box-sizing: border-box; +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + line-height: normal; +} + +.form-control { + display: inline-block; + width: 100%; + min-height: 25px; + padding: 5px 10px; + font-size: 13px; + line-height: 1.6; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + outline: none; +} +.form-control:focus { + border-color: #6db3fd; + box-shadow: 0 0 0 3px #6db3fd; +} + +textarea { + height: auto; +} + +.form-group { + margin-bottom: 10px; +} + +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; +} + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px; +} + +.form-actions .btn { + margin-right: 10px; +} +.form-actions .btn:last-child { + margin-right: 0; +} + +.pane-group { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; +} + +.pane { + position: relative; + overflow-y: auto; + flex: 1; + border-left: 1px solid #ddd; +} +.pane:first-child { + border-left: 0; +} + +.pane-sm { + max-width: 220px; + min-width: 150px; +} + +.pane-mini { + width: 80px; + flex: none; +} + +.pane-one-fourth { + width: 25%; + flex: none; +} + +.pane-one-third { + width: 33.3%; + flex: none; +} + +img { + -webkit-user-drag: text; +} + +.img-circle { + border-radius: 50%; +} + +.img-rounded { + border-radius: 4px; +} + +.list-group { + width: 100%; + list-style: none; + margin: 0; + padding: 0; +} +.list-group * { + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.list-group-item { + padding: 10px; + font-size: 12px; + color: #414142; + border-top: 1px solid #ddd; +} +.list-group-item:first-child { + border-top: 0; +} +.list-group-item.active, .list-group-item.selected { + color: #fff; + background-color: #116cd6; +} + +.list-group-header { + padding: 10px; +} + +.media-object { + margin-top: 3px; +} + +.media-object.pull-left { + margin-right: 10px; +} + +.media-object.pull-right { + margin-left: 10px; +} + +.media-body { + overflow: hidden; +} + +.nav-group { + font-size: 14px; +} + +.nav-group-item { + padding: 2px 10px 2px 25px; + display: block; + color: #333; + text-decoration: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.nav-group-item:active, .nav-group-item.active { + background-color: #dcdfe1; +} +.nav-group-item .icon { + width: 19px; + height: 18px; + float: left; + color: #737475; + margin-top: -3px; + margin-right: 7px; + font-size: 18px; + text-align: center; +} + +.nav-group-title { + margin: 0; + padding: 10px 10px 2px; + font-size: 12px; + font-weight: 500; + color: #666666; +} + +@font-face { + font-family: "photon-entypo"; + src: url("../fonts/photon-entypo.eot"); + src: url("../fonts/photon-entypo.eot?#iefix") format("eot"), url("../fonts/photon-entypo.woff") format("woff"), url("../fonts/photon-entypo.ttf") format("truetype"); + font-weight: normal; + font-style: normal; +} +.icon:before { + position: relative; + display: inline-block; + font-family: "photon-entypo"; + speak: none; + font-size: 100%; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-note:before { + content: '\e800'; +} + +/* '' */ +.icon-note-beamed:before { + content: '\e801'; +} + +/* '' */ +.icon-music:before { + content: '\e802'; +} + +/* '' */ +.icon-search:before { + content: '\e803'; +} + +/* '' */ +.icon-flashlight:before { + content: '\e804'; +} + +/* '' */ +.icon-mail:before { + content: '\e805'; +} + +/* '' */ +.icon-heart:before { + content: '\e806'; +} + +/* '' */ +.icon-heart-empty:before { + content: '\e807'; +} + +/* '' */ +.icon-star:before { + content: '\e808'; +} + +/* '' */ +.icon-star-empty:before { + content: '\e809'; +} + +/* '' */ +.icon-user:before { + content: '\e80a'; +} + +/* '' */ +.icon-users:before { + content: '\e80b'; +} + +/* '' */ +.icon-user-add:before { + content: '\e80c'; +} + +/* '' */ +.icon-video:before { + content: '\e80d'; +} + +/* '' */ +.icon-picture:before { + content: '\e80e'; +} + +/* '' */ +.icon-camera:before { + content: '\e80f'; +} + +/* '' */ +.icon-layout:before { + content: '\e810'; +} + +/* '' */ +.icon-menu:before { + content: '\e811'; +} + +/* '' */ +.icon-check:before { + content: '\e812'; +} + +/* '' */ +.icon-cancel:before { + content: '\e813'; +} + +/* '' */ +.icon-cancel-circled:before { + content: '\e814'; +} + +/* '' */ +.icon-cancel-squared:before { + content: '\e815'; +} + +/* '' */ +.icon-plus:before { + content: '\e816'; +} + +/* '' */ +.icon-plus-circled:before { + content: '\e817'; +} + +/* '' */ +.icon-plus-squared:before { + content: '\e818'; +} + +/* '' */ +.icon-minus:before { + content: '\e819'; +} + +/* '' */ +.icon-minus-circled:before { + content: '\e81a'; +} + +/* '' */ +.icon-minus-squared:before { + content: '\e81b'; +} + +/* '' */ +.icon-help:before { + content: '\e81c'; +} + +/* '' */ +.icon-help-circled:before { + content: '\e81d'; +} + +/* '' */ +.icon-info:before { + content: '\e81e'; +} + +/* '' */ +.icon-info-circled:before { + content: '\e81f'; +} + +/* '' */ +.icon-back:before { + content: '\e820'; +} + +/* '' */ +.icon-home:before { + content: '\e821'; +} + +/* '' */ +.icon-link:before { + content: '\e822'; +} + +/* '' */ +.icon-attach:before { + content: '\e823'; +} + +/* '' */ +.icon-lock:before { + content: '\e824'; +} + +/* '' */ +.icon-lock-open:before { + content: '\e825'; +} + +/* '' */ +.icon-eye:before { + content: '\e826'; +} + +/* '' */ +.icon-tag:before { + content: '\e827'; +} + +/* '' */ +.icon-bookmark:before { + content: '\e828'; +} + +/* '' */ +.icon-bookmarks:before { + content: '\e829'; +} + +/* '' */ +.icon-flag:before { + content: '\e82a'; +} + +/* '' */ +.icon-thumbs-up:before { + content: '\e82b'; +} + +/* '' */ +.icon-thumbs-down:before { + content: '\e82c'; +} + +/* '' */ +.icon-download:before { + content: '\e82d'; +} + +/* '' */ +.icon-upload:before { + content: '\e82e'; +} + +/* '' */ +.icon-upload-cloud:before { + content: '\e82f'; +} + +/* '' */ +.icon-reply:before { + content: '\e830'; +} + +/* '' */ +.icon-reply-all:before { + content: '\e831'; +} + +/* '' */ +.icon-forward:before { + content: '\e832'; +} + +/* '' */ +.icon-quote:before { + content: '\e833'; +} + +/* '' */ +.icon-code:before { + content: '\e834'; +} + +/* '' */ +.icon-export:before { + content: '\e835'; +} + +/* '' */ +.icon-pencil:before { + content: '\e836'; +} + +/* '' */ +.icon-feather:before { + content: '\e837'; +} + +/* '' */ +.icon-print:before { + content: '\e838'; +} + +/* '' */ +.icon-retweet:before { + content: '\e839'; +} + +/* '' */ +.icon-keyboard:before { + content: '\e83a'; +} + +/* '' */ +.icon-comment:before { + content: '\e83b'; +} + +/* '' */ +.icon-chat:before { + content: '\e83c'; +} + +/* '' */ +.icon-bell:before { + content: '\e83d'; +} + +/* '' */ +.icon-attention:before { + content: '\e83e'; +} + +/* '' */ +.icon-alert:before { + content: '\e83f'; +} + +/* '' */ +.icon-vcard:before { + content: '\e840'; +} + +/* '' */ +.icon-address:before { + content: '\e841'; +} + +/* '' */ +.icon-location:before { + content: '\e842'; +} + +/* '' */ +.icon-map:before { + content: '\e843'; +} + +/* '' */ +.icon-direction:before { + content: '\e844'; +} + +/* '' */ +.icon-compass:before { + content: '\e845'; +} + +/* '' */ +.icon-cup:before { + content: '\e846'; +} + +/* '' */ +.icon-trash:before { + content: '\e847'; +} + +/* '' */ +.icon-doc:before { + content: '\e848'; +} + +/* '' */ +.icon-docs:before { + content: '\e849'; +} + +/* '' */ +.icon-doc-landscape:before { + content: '\e84a'; +} + +/* '' */ +.icon-doc-text:before { + content: '\e84b'; +} + +/* '' */ +.icon-doc-text-inv:before { + content: '\e84c'; +} + +/* '' */ +.icon-newspaper:before { + content: '\e84d'; +} + +/* '' */ +.icon-book-open:before { + content: '\e84e'; +} + +/* '' */ +.icon-book:before { + content: '\e84f'; +} + +/* '' */ +.icon-folder:before { + content: '\e850'; +} + +/* '' */ +.icon-archive:before { + content: '\e851'; +} + +/* '' */ +.icon-box:before { + content: '\e852'; +} + +/* '' */ +.icon-rss:before { + content: '\e853'; +} + +/* '' */ +.icon-phone:before { + content: '\e854'; +} + +/* '' */ +.icon-cog:before { + content: '\e855'; +} + +/* '' */ +.icon-tools:before { + content: '\e856'; +} + +/* '' */ +.icon-share:before { + content: '\e857'; +} + +/* '' */ +.icon-shareable:before { + content: '\e858'; +} + +/* '' */ +.icon-basket:before { + content: '\e859'; +} + +/* '' */ +.icon-bag:before { + content: '\e85a'; +} + +/* '' */ +.icon-calendar:before { + content: '\e85b'; +} + +/* '' */ +.icon-login:before { + content: '\e85c'; +} + +/* '' */ +.icon-logout:before { + content: '\e85d'; +} + +/* '' */ +.icon-mic:before { + content: '\e85e'; +} + +/* '' */ +.icon-mute:before { + content: '\e85f'; +} + +/* '' */ +.icon-sound:before { + content: '\e860'; +} + +/* '' */ +.icon-volume:before { + content: '\e861'; +} + +/* '' */ +.icon-clock:before { + content: '\e862'; +} + +/* '' */ +.icon-hourglass:before { + content: '\e863'; +} + +/* '' */ +.icon-lamp:before { + content: '\e864'; +} + +/* '' */ +.icon-light-down:before { + content: '\e865'; +} + +/* '' */ +.icon-light-up:before { + content: '\e866'; +} + +/* '' */ +.icon-adjust:before { + content: '\e867'; +} + +/* '' */ +.icon-block:before { + content: '\e868'; +} + +/* '' */ +.icon-resize-full:before { + content: '\e869'; +} + +/* '' */ +.icon-resize-small:before { + content: '\e86a'; +} + +/* '' */ +.icon-popup:before { + content: '\e86b'; +} + +/* '' */ +.icon-publish:before { + content: '\e86c'; +} + +/* '' */ +.icon-window:before { + content: '\e86d'; +} + +/* '' */ +.icon-arrow-combo:before { + content: '\e86e'; +} + +/* '' */ +.icon-down-circled:before { + content: '\e86f'; +} + +/* '' */ +.icon-left-circled:before { + content: '\e870'; +} + +/* '' */ +.icon-right-circled:before { + content: '\e871'; +} + +/* '' */ +.icon-up-circled:before { + content: '\e872'; +} + +/* '' */ +.icon-down-open:before { + content: '\e873'; +} + +/* '' */ +.icon-left-open:before { + content: '\e874'; +} + +/* '' */ +.icon-right-open:before { + content: '\e875'; +} + +/* '' */ +.icon-up-open:before { + content: '\e876'; +} + +/* '' */ +.icon-down-open-mini:before { + content: '\e877'; +} + +/* '' */ +.icon-left-open-mini:before { + content: '\e878'; +} + +/* '' */ +.icon-right-open-mini:before { + content: '\e879'; +} + +/* '' */ +.icon-up-open-mini:before { + content: '\e87a'; +} + +/* '' */ +.icon-down-open-big:before { + content: '\e87b'; +} + +/* '' */ +.icon-left-open-big:before { + content: '\e87c'; +} + +/* '' */ +.icon-right-open-big:before { + content: '\e87d'; +} + +/* '' */ +.icon-up-open-big:before { + content: '\e87e'; +} + +/* '' */ +.icon-down:before { + content: '\e87f'; +} + +/* '' */ +.icon-left:before { + content: '\e880'; +} + +/* '' */ +.icon-right:before { + content: '\e881'; +} + +/* '' */ +.icon-up:before { + content: '\e882'; +} + +/* '' */ +.icon-down-dir:before { + content: '\e883'; +} + +/* '' */ +.icon-left-dir:before { + content: '\e884'; +} + +/* '' */ +.icon-right-dir:before { + content: '\e885'; +} + +/* '' */ +.icon-up-dir:before { + content: '\e886'; +} + +/* '' */ +.icon-down-bold:before { + content: '\e887'; +} + +/* '' */ +.icon-left-bold:before { + content: '\e888'; +} + +/* '' */ +.icon-right-bold:before { + content: '\e889'; +} + +/* '' */ +.icon-up-bold:before { + content: '\e88a'; +} + +/* '' */ +.icon-down-thin:before { + content: '\e88b'; +} + +/* '' */ +.icon-left-thin:before { + content: '\e88c'; +} + +/* '' */ +.icon-right-thin:before { + content: '\e88d'; +} + +/* '' */ +.icon-up-thin:before { + content: '\e88e'; +} + +/* '' */ +.icon-ccw:before { + content: '\e88f'; +} + +/* '' */ +.icon-cw:before { + content: '\e890'; +} + +/* '' */ +.icon-arrows-ccw:before { + content: '\e891'; +} + +/* '' */ +.icon-level-down:before { + content: '\e892'; +} + +/* '' */ +.icon-level-up:before { + content: '\e893'; +} + +/* '' */ +.icon-shuffle:before { + content: '\e894'; +} + +/* '' */ +.icon-loop:before { + content: '\e895'; +} + +/* '' */ +.icon-switch:before { + content: '\e896'; +} + +/* '' */ +.icon-play:before { + content: '\e897'; +} + +/* '' */ +.icon-stop:before { + content: '\e898'; +} + +/* '' */ +.icon-pause:before { + content: '\e899'; +} + +/* '' */ +.icon-record:before { + content: '\e89a'; +} + +/* '' */ +.icon-to-end:before { + content: '\e89b'; +} + +/* '' */ +.icon-to-start:before { + content: '\e89c'; +} + +/* '' */ +.icon-fast-forward:before { + content: '\e89d'; +} + +/* '' */ +.icon-fast-backward:before { + content: '\e89e'; +} + +/* '' */ +.icon-progress-0:before { + content: '\e89f'; +} + +/* '' */ +.icon-progress-1:before { + content: '\e8a0'; +} + +/* '' */ +.icon-progress-2:before { + content: '\e8a1'; +} + +/* '' */ +.icon-progress-3:before { + content: '\e8a2'; +} + +/* '' */ +.icon-target:before { + content: '\e8a3'; +} + +/* '' */ +.icon-palette:before { + content: '\e8a4'; +} + +/* '' */ +.icon-list:before { + content: '\e8a5'; +} + +/* '' */ +.icon-list-add:before { + content: '\e8a6'; +} + +/* '' */ +.icon-signal:before { + content: '\e8a7'; +} + +/* '' */ +.icon-trophy:before { + content: '\e8a8'; +} + +/* '' */ +.icon-battery:before { + content: '\e8a9'; +} + +/* '' */ +.icon-back-in-time:before { + content: '\e8aa'; +} + +/* '' */ +.icon-monitor:before { + content: '\e8ab'; +} + +/* '' */ +.icon-mobile:before { + content: '\e8ac'; +} + +/* '' */ +.icon-network:before { + content: '\e8ad'; +} + +/* '' */ +.icon-cd:before { + content: '\e8ae'; +} + +/* '' */ +.icon-inbox:before { + content: '\e8af'; +} + +/* '' */ +.icon-install:before { + content: '\e8b0'; +} + +/* '' */ +.icon-globe:before { + content: '\e8b1'; +} + +/* '' */ +.icon-cloud:before { + content: '\e8b2'; +} + +/* '' */ +.icon-cloud-thunder:before { + content: '\e8b3'; +} + +/* '' */ +.icon-flash:before { + content: '\e8b4'; +} + +/* '' */ +.icon-moon:before { + content: '\e8b5'; +} + +/* '' */ +.icon-flight:before { + content: '\e8b6'; +} + +/* '' */ +.icon-paper-plane:before { + content: '\e8b7'; +} + +/* '' */ +.icon-leaf:before { + content: '\e8b8'; +} + +/* '' */ +.icon-lifebuoy:before { + content: '\e8b9'; +} + +/* '' */ +.icon-mouse:before { + content: '\e8ba'; +} + +/* '' */ +.icon-briefcase:before { + content: '\e8bb'; +} + +/* '' */ +.icon-suitcase:before { + content: '\e8bc'; +} + +/* '' */ +.icon-dot:before { + content: '\e8bd'; +} + +/* '' */ +.icon-dot-2:before { + content: '\e8be'; +} + +/* '' */ +.icon-dot-3:before { + content: '\e8bf'; +} + +/* '' */ +.icon-brush:before { + content: '\e8c0'; +} + +/* '' */ +.icon-magnet:before { + content: '\e8c1'; +} + +/* '' */ +.icon-infinity:before { + content: '\e8c2'; +} + +/* '' */ +.icon-erase:before { + content: '\e8c3'; +} + +/* '' */ +.icon-chart-pie:before { + content: '\e8c4'; +} + +/* '' */ +.icon-chart-line:before { + content: '\e8c5'; +} + +/* '' */ +.icon-chart-bar:before { + content: '\e8c6'; +} + +/* '' */ +.icon-chart-area:before { + content: '\e8c7'; +} + +/* '' */ +.icon-tape:before { + content: '\e8c8'; +} + +/* '' */ +.icon-graduation-cap:before { + content: '\e8c9'; +} + +/* '' */ +.icon-language:before { + content: '\e8ca'; +} + +/* '' */ +.icon-ticket:before { + content: '\e8cb'; +} + +/* '' */ +.icon-water:before { + content: '\e8cc'; +} + +/* '' */ +.icon-droplet:before { + content: '\e8cd'; +} + +/* '' */ +.icon-air:before { + content: '\e8ce'; +} + +/* '' */ +.icon-credit-card:before { + content: '\e8cf'; +} + +/* '' */ +.icon-floppy:before { + content: '\e8d0'; +} + +/* '' */ +.icon-clipboard:before { + content: '\e8d1'; +} + +/* '' */ +.icon-megaphone:before { + content: '\e8d2'; +} + +/* '' */ +.icon-database:before { + content: '\e8d3'; +} + +/* '' */ +.icon-drive:before { + content: '\e8d4'; +} + +/* '' */ +.icon-bucket:before { + content: '\e8d5'; +} + +/* '' */ +.icon-thermometer:before { + content: '\e8d6'; +} + +/* '' */ +.icon-key:before { + content: '\e8d7'; +} + +/* '' */ +.icon-flow-cascade:before { + content: '\e8d8'; +} + +/* '' */ +.icon-flow-branch:before { + content: '\e8d9'; +} + +/* '' */ +.icon-flow-tree:before { + content: '\e8da'; +} + +/* '' */ +.icon-flow-line:before { + content: '\e8db'; +} + +/* '' */ +.icon-flow-parallel:before { + content: '\e8dc'; +} + +/* '' */ +.icon-rocket:before { + content: '\e8dd'; +} + +/* '' */ +.icon-gauge:before { + content: '\e8de'; +} + +/* '' */ +.icon-traffic-cone:before { + content: '\e8df'; +} + +/* '' */ +.icon-cc:before { + content: '\e8e0'; +} + +/* '' */ +.icon-cc-by:before { + content: '\e8e1'; +} + +/* '' */ +.icon-cc-nc:before { + content: '\e8e2'; +} + +/* '' */ +.icon-cc-nc-eu:before { + content: '\e8e3'; +} + +/* '' */ +.icon-cc-nc-jp:before { + content: '\e8e4'; +} + +/* '' */ +.icon-cc-sa:before { + content: '\e8e5'; +} + +/* '' */ +.icon-cc-nd:before { + content: '\e8e6'; +} + +/* '' */ +.icon-cc-pd:before { + content: '\e8e7'; +} + +/* '' */ +.icon-cc-zero:before { + content: '\e8e8'; +} + +/* '' */ +.icon-cc-share:before { + content: '\e8e9'; +} + +/* '' */ +.icon-cc-remix:before { + content: '\e8ea'; +} + +/* '' */ +.icon-github:before { + content: '\e8eb'; +} + +/* '' */ +.icon-github-circled:before { + content: '\e8ec'; +} + +/* '' */ +.icon-flickr:before { + content: '\e8ed'; +} + +/* '' */ +.icon-flickr-circled:before { + content: '\e8ee'; +} + +/* '' */ +.icon-vimeo:before { + content: '\e8ef'; +} + +/* '' */ +.icon-vimeo-circled:before { + content: '\e8f0'; +} + +/* '' */ +.icon-twitter:before { + content: '\e8f1'; +} + +/* '' */ +.icon-twitter-circled:before { + content: '\e8f2'; +} + +/* '' */ +.icon-facebook:before { + content: '\e8f3'; +} + +/* '' */ +.icon-facebook-circled:before { + content: '\e8f4'; +} + +/* '' */ +.icon-facebook-squared:before { + content: '\e8f5'; +} + +/* '' */ +.icon-gplus:before { + content: '\e8f6'; +} + +/* '' */ +.icon-gplus-circled:before { + content: '\e8f7'; +} + +/* '' */ +.icon-pinterest:before { + content: '\e8f8'; +} + +/* '' */ +.icon-pinterest-circled:before { + content: '\e8f9'; +} + +/* '' */ +.icon-tumblr:before { + content: '\e8fa'; +} + +/* '' */ +.icon-tumblr-circled:before { + content: '\e8fb'; +} + +/* '' */ +.icon-linkedin:before { + content: '\e8fc'; +} + +/* '' */ +.icon-linkedin-circled:before { + content: '\e8fd'; +} + +/* '' */ +.icon-dribbble:before { + content: '\e8fe'; +} + +/* '' */ +.icon-dribbble-circled:before { + content: '\e8ff'; +} + +/* '' */ +.icon-stumbleupon:before { + content: '\e900'; +} + +/* '' */ +.icon-stumbleupon-circled:before { + content: '\e901'; +} + +/* '' */ +.icon-lastfm:before { + content: '\e902'; +} + +/* '' */ +.icon-lastfm-circled:before { + content: '\e903'; +} + +/* '' */ +.icon-rdio:before { + content: '\e904'; +} + +/* '' */ +.icon-rdio-circled:before { + content: '\e905'; +} + +/* '' */ +.icon-spotify:before { + content: '\e906'; +} + +/* '' */ +.icon-spotify-circled:before { + content: '\e907'; +} + +/* '' */ +.icon-qq:before { + content: '\e908'; +} + +/* '' */ +.icon-instagram:before { + content: '\e909'; +} + +/* '' */ +.icon-dropbox:before { + content: '\e90a'; +} + +/* '' */ +.icon-evernote:before { + content: '\e90b'; +} + +/* '' */ +.icon-flattr:before { + content: '\e90c'; +} + +/* '' */ +.icon-skype:before { + content: '\e90d'; +} + +/* '' */ +.icon-skype-circled:before { + content: '\e90e'; +} + +/* '' */ +.icon-renren:before { + content: '\e90f'; +} + +/* '' */ +.icon-sina-weibo:before { + content: '\e910'; +} + +/* '' */ +.icon-paypal:before { + content: '\e911'; +} + +/* '' */ +.icon-picasa:before { + content: '\e912'; +} + +/* '' */ +.icon-soundcloud:before { + content: '\e913'; +} + +/* '' */ +.icon-mixi:before { + content: '\e914'; +} + +/* '' */ +.icon-behance:before { + content: '\e915'; +} + +/* '' */ +.icon-google-circles:before { + content: '\e916'; +} + +/* '' */ +.icon-vkontakte:before { + content: '\e917'; +} + +/* '' */ +.icon-smashing:before { + content: '\e918'; +} + +/* '' */ +.icon-sweden:before { + content: '\e919'; +} + +/* '' */ +.icon-db-shape:before { + content: '\e91a'; +} + +/* '' */ +.icon-logo-db:before { + content: '\e91b'; +} + +/* '' */ +table { + width: 100%; + border: 0; + border-collapse: separate; + font-size: 12px; + text-align: left; +} + +thead { + background-color: #f5f5f4; +} + +tbody { + background-color: #fff; +} + +.table-striped tr:nth-child(even) { + background-color: #f5f5f4; +} + +tr:active, +.table-striped tr:active:nth-child(even) { + color: #fff; + background-color: #116cd6; +} + +thead tr:active { + color: #333; + background-color: #f5f5f4; +} + +th { + font-weight: normal; + border-right: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +th, +td { + padding: 2px 15px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +th:last-child, +td:last-child { + border-right: 0; +} + +.tab-group { + margin-top: -1px; + display: flex; + border-top: 1px solid #989698; + border-bottom: 1px solid #989698; +} + +.tab-item { + position: relative; + flex: 1; + padding: 3px; + font-size: 12px; + text-align: center; + border-left: 1px solid #989698; + background-color: #b8b6b8; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b8b6b8), color-stop(100%, #b0aeb0)); + background-image: -webkit-linear-gradient(top, #b8b6b8 0%, #b0aeb0 100%); + background-image: linear-gradient(to bottom, #b8b6b8 0%, #b0aeb0 100%); +} +.tab-item:first-child { + border-left: 0; +} +.tab-item.active { + background-color: #d4d2d4; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d4d2d4), color-stop(100%, #cccacc)); + background-image: -webkit-linear-gradient(top, #d4d2d4 0%, #cccacc 100%); + background-image: linear-gradient(to bottom, #d4d2d4 0%, #cccacc 100%); +} +.tab-item .icon-close-tab { + position: absolute; + top: 50%; + left: 5px; + width: 15px; + height: 15px; + font-size: 15px; + line-height: 15px; + text-align: center; + color: #666; + opacity: 0; + transition: opacity .1s linear, background-color .1s linear; + border-radius: 3px; + transform: translateY(-50%); + z-index: 10; +} +.tab-item:after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ""; + background-color: rgba(0, 0, 0, 0.08); + opacity: 0; + transition: opacity .1s linear; + z-index: 1; +} +.tab-item:hover:not(.active):after { + opacity: 1; +} +.tab-item:hover .icon-close-tab { + opacity: 1; +} +.tab-item .icon-close-tab:hover { + background-color: rgba(0, 0, 0, 0.08); +} + +.tab-item-fixed { + flex: none; + padding: 3px 10px; +} diff --git a/clients/electron_app/data/blank.txt b/clients/electron_app/data/blank.txt new file mode 100644 index 0000000..e69de29 diff --git a/clients/electron_app/dist/app.js b/clients/electron_app/dist/app.js new file mode 100644 index 0000000..14e0ba2 --- /dev/null +++ b/clients/electron_app/dist/app.js @@ -0,0 +1,44 @@ +/*jshint browser:true*/ +'use strict'; +const Fingerprint2 = require('./lib/fingerprint2.js'); +const ttm = require('./lib/talktomain.js'); + +var fp; + +var onReady = function () { + fp = new Fingerprint2().get((result, components) => { + console.log(result); + setTimeout(function () { + ttm.send('config', { fingerprint : result }); + }, 2000); + }); +}; + + +document.addEventListener('DOMContentLoaded', onReady); + + + +/*console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong" + +ipcRenderer.on('asynchronous-reply', (event, arg) => { + console.log(arg); // prints "pong" +}); + +ipcRenderer.send('asynchronous-message', 'ping'); + +function timeout(duration = 0) { + return new Promise((resolve, reject) => { + setTimeout(resolve, duration); + }) +} + +var p = timeout(1000).then(() => { + return timeout(2000); +}).then(() => { + throw new Error("hmm"); +}).catch(err => { + return Promise.all([timeout(100), timeout(200)]); +}) + +*/ \ No newline at end of file diff --git a/clients/electron_app/fonts/photon-entypo.eot b/clients/electron_app/fonts/photon-entypo.eot new file mode 100755 index 0000000..f70d126 Binary files /dev/null and b/clients/electron_app/fonts/photon-entypo.eot differ diff --git a/clients/electron_app/fonts/photon-entypo.svg b/clients/electron_app/fonts/photon-entypo.svg new file mode 100755 index 0000000..9256ea8 --- /dev/null +++ b/clients/electron_app/fonts/photon-entypo.svg @@ -0,0 +1,295 @@ + + + +Copyright (C) 2015 by original authors @ fontello.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/clients/electron_app/fonts/photon-entypo.ttf b/clients/electron_app/fonts/photon-entypo.ttf new file mode 100755 index 0000000..7f765b3 Binary files /dev/null and b/clients/electron_app/fonts/photon-entypo.ttf differ diff --git a/clients/electron_app/fonts/photon-entypo.woff b/clients/electron_app/fonts/photon-entypo.woff new file mode 100755 index 0000000..87860e5 Binary files /dev/null and b/clients/electron_app/fonts/photon-entypo.woff differ diff --git a/clients/electron_app/gulpfile.js b/clients/electron_app/gulpfile.js new file mode 100644 index 0000000..436dda2 --- /dev/null +++ b/clients/electron_app/gulpfile.js @@ -0,0 +1,27 @@ +'use strict'; + +const gulp = require('gulp'); +const concat = require('gulp-concat'); +const minify = require('gulp-minify'); +const files = [ + './index.js' +]; +const targetDir = './dist/'; +const targetFile = 'app.js'; +const minified = 'app.min.js'; + +gulp.task('default', () => {}); + +gulp.task('scripts', () => { + return gulp.src(files) + .pipe(concat(targetFile)) + .pipe(gulp.dest(targetDir)); +}); + +gulp.task('compress', ['scripts'], () => { + gulp.src(targetDir + targetFile) + .pipe(minify()) + .pipe(gulp.dest(targetDir)); +}); + +gulp.task('default', ['scripts']); \ No newline at end of file diff --git a/clients/electron_app/index.html b/clients/electron_app/index.html new file mode 100644 index 0000000..7ae3dab --- /dev/null +++ b/clients/electron_app/index.html @@ -0,0 +1,50 @@ + + + + Contact Printer + + + + + +
+
+
+ + Run +
+
+ + Settings +
+
+
+
+ We are using Node.js , + Chromium , + and Electron . +
+
+ +
+
+
+ +
+
+
+
+ + + +
+
+ + + \ No newline at end of file diff --git a/clients/electron_app/index.js b/clients/electron_app/index.js new file mode 100644 index 0000000..14e0ba2 --- /dev/null +++ b/clients/electron_app/index.js @@ -0,0 +1,44 @@ +/*jshint browser:true*/ +'use strict'; +const Fingerprint2 = require('./lib/fingerprint2.js'); +const ttm = require('./lib/talktomain.js'); + +var fp; + +var onReady = function () { + fp = new Fingerprint2().get((result, components) => { + console.log(result); + setTimeout(function () { + ttm.send('config', { fingerprint : result }); + }, 2000); + }); +}; + + +document.addEventListener('DOMContentLoaded', onReady); + + + +/*console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong" + +ipcRenderer.on('asynchronous-reply', (event, arg) => { + console.log(arg); // prints "pong" +}); + +ipcRenderer.send('asynchronous-message', 'ping'); + +function timeout(duration = 0) { + return new Promise((resolve, reject) => { + setTimeout(resolve, duration); + }) +} + +var p = timeout(1000).then(() => { + return timeout(2000); +}).then(() => { + throw new Error("hmm"); +}).catch(err => { + return Promise.all([timeout(100), timeout(200)]); +}) + +*/ \ No newline at end of file diff --git a/clients/electron_app/install.sh b/clients/electron_app/install.sh new file mode 100644 index 0000000..64217bb --- /dev/null +++ b/clients/electron_app/install.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +npm install +./node_modules/.bin/electron-rebuild --version=1.4.1 \ No newline at end of file diff --git a/clients/electron_app/lib/arduinoCom.js b/clients/electron_app/lib/arduinoCom.js new file mode 100644 index 0000000..810e930 --- /dev/null +++ b/clients/electron_app/lib/arduinoCom.js @@ -0,0 +1,74 @@ +'use strict'; + +const SerialPort = require('serialport'); +const parser = SerialPort.parsers.readline("\n"); +const delay = 15; +const baud = 57600; + +let waiting = false; +let waitCb; + +class arduinoCom { + constructor () { + this.port = {}; + this.path = ''; + + SerialPort.list((err, ports) => { + if (err) { + return console.error(err); + } + for (let i = 0; i < ports.length; i++) { + if ((ports[i].manufacturer + '').toLowerCase().indexOf('arduino') !== -1) { + this.path = ports[i].comName; + break; + } + } + if (this.path === '') { + return console.error('No arduino found'); + } + console.log(`Connecting to ${this.path}...`); + this.port = new SerialPort(this.path, { + baudRate: baud, + parser : parser, + autoOpen: false + }); + this.port.open((err) => { + if (err) { + return console.error(err); + } + console.log(`Connected to ${this.path} @ ${baud} baud`); + this.port.on('data', this.dataCb); + }); + }); + } + dataCb (data = '{}') { + data = JSON.parse(data); + if (waiting) { + waitCb(null, data); + waiting = false; + } + } + send (ch = 'z', callback = null, nowait = false) { + if (!waiting && !nowait) { + waitCb = callback; + waiting = true; + } else if (nowait) { + waiting = false; + if (callback !== null) { + return callback(null, {}); + } + } else { + return callback('Port is currently in use'); + } + setTimeout(() => { + this.port.write(ch); + }, delay); + return false; + } + close (callback) { + console.log('Closing ${this.path}'); + this.port.close(callback); + } +} + +module.exports = new arduinoCom(); \ No newline at end of file diff --git a/clients/electron_app/lib/config.js b/clients/electron_app/lib/config.js new file mode 100644 index 0000000..e10f916 --- /dev/null +++ b/clients/electron_app/lib/config.js @@ -0,0 +1,30 @@ +'use strict'; +const fs = require('fs'); + +class Config { + constructor () { + this.configPath = './data/config.json'; + if (fs.existsSync(this.configPath)) { + this.data = JSON.parse(fs.readFileSync(this.configPath, 'utf8')); + } else { + this.data = {}; + this.store(); + } + } + get (key) { + if (this.data[key]) { + return this.data[key]; + } else { + return null; + } + } + set (key, val) { + this.data[key] = val; + this.store(); + } + store () { + fs.writeFileSync(this.configPath, JSON.stringify(this.data), 'utf8'); + } +} + +module.exports = new Config(); \ No newline at end of file diff --git a/clients/electron_app/lib/fingerprint2.js b/clients/electron_app/lib/fingerprint2.js new file mode 100644 index 0000000..54c03d5 --- /dev/null +++ b/clients/electron_app/lib/fingerprint2.js @@ -0,0 +1,1319 @@ +/* +* Fingerprintjs2 1.4.4 - Modern & flexible browser fingerprint library v2 +* https://github.com/Valve/fingerprintjs2 +* Copyright (c) 2015 Valentin Vasilyev (valentin.vasilyev@outlook.com) +* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL VALENTIN VASILYEV BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +(function (name, context, definition) { + "use strict"; + if (typeof define === "function" && define.amd) { define(definition); } + else if (typeof module !== "undefined" && module.exports) { module.exports = definition(); } + else if (context.exports) { context.exports = definition(); } + else { context[name] = definition(); } +})("Fingerprint2", this, function() { + "use strict"; + // This will only be polyfilled for IE8 and older + // Taken from Mozilla MDC + if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function(searchElement, fromIndex) { + var k; + if (this == null) { + throw new TypeError("'this' is null or undefined"); + } + var O = Object(this); + var len = O.length >>> 0; + if (len === 0) { + return -1; + } + var n = +fromIndex || 0; + if (Math.abs(n) === Infinity) { + n = 0; + } + if (n >= len) { + return -1; + } + k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); + while (k < len) { + if (k in O && O[k] === searchElement) { + return k; + } + k++; + } + return -1; + }; + } + var Fingerprint2 = function(options) { + + if (!(this instanceof Fingerprint2)) { + return new Fingerprint2(options); + } + + var defaultOptions = { + swfContainerId: "fingerprintjs2", + swfPath: "flash/compiled/FontList.swf", + detectScreenOrientation: true, + sortPluginsFor: [/palemoon/i], + userDefinedFonts: [] + }; + this.options = this.extend(options, defaultOptions); + this.nativeForEach = Array.prototype.forEach; + this.nativeMap = Array.prototype.map; + }; + Fingerprint2.prototype = { + extend: function(source, target) { + if (source == null) { return target; } + for (var k in source) { + if(source[k] != null && target[k] !== source[k]) { + target[k] = source[k]; + } + } + return target; + }, + log: function(msg){ + if(window.console){ + console.log(msg); + } + }, + get: function(done){ + var keys = []; + keys = this.userAgentKey(keys); + keys = this.languageKey(keys); + keys = this.colorDepthKey(keys); + keys = this.pixelRatioKey(keys); + keys = this.hardwareConcurrencyKey(keys); + keys = this.screenResolutionKey(keys); + keys = this.availableScreenResolutionKey(keys); + keys = this.timezoneOffsetKey(keys); + keys = this.sessionStorageKey(keys); + keys = this.localStorageKey(keys); + keys = this.indexedDbKey(keys); + keys = this.addBehaviorKey(keys); + keys = this.openDatabaseKey(keys); + keys = this.cpuClassKey(keys); + keys = this.platformKey(keys); + keys = this.doNotTrackKey(keys); + keys = this.pluginsKey(keys); + keys = this.canvasKey(keys); + keys = this.webglKey(keys); + keys = this.adBlockKey(keys); + keys = this.hasLiedLanguagesKey(keys); + keys = this.hasLiedResolutionKey(keys); + keys = this.hasLiedOsKey(keys); + keys = this.hasLiedBrowserKey(keys); + keys = this.touchSupportKey(keys); + var that = this; + this.fontsKey(keys, function(newKeys){ + var values = []; + that.each(newKeys, function(pair) { + var value = pair.value; + if (typeof pair.value.join !== "undefined") { + value = pair.value.join(";"); + } + values.push(value); + }); + var murmur = that.x64hash128(values.join("~~~"), 31); + return done(murmur, newKeys); + }); + }, + userAgentKey: function(keys) { + if(!this.options.excludeUserAgent) { + keys.push({key: "user_agent", value: this.getUserAgent()}); + } + return keys; + }, + // for tests + getUserAgent: function(){ + return navigator.userAgent; + }, + languageKey: function(keys) { + if(!this.options.excludeLanguage) { + // IE 9,10 on Windows 10 does not have the `navigator.language` property any longer + keys.push({ key: "language", value: navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage || "" }); + } + return keys; + }, + colorDepthKey: function(keys) { + if(!this.options.excludeColorDepth) { + keys.push({key: "color_depth", value: screen.colorDepth || -1}); + } + return keys; + }, + pixelRatioKey: function(keys) { + if(!this.options.excludePixelRatio) { + keys.push({key: "pixel_ratio", value: this.getPixelRatio()}); + } + return keys; + }, + getPixelRatio: function() { + return window.devicePixelRatio || ""; + }, + screenResolutionKey: function(keys) { + if(!this.options.excludeScreenResolution) { + return this.getScreenResolution(keys); + } + return keys; + }, + getScreenResolution: function(keys) { + var resolution; + if(this.options.detectScreenOrientation) { + resolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height]; + } else { + resolution = [screen.width, screen.height]; + } + if(typeof resolution !== "undefined") { // headless browsers + keys.push({key: "resolution", value: resolution}); + } + return keys; + }, + availableScreenResolutionKey: function(keys) { + if (!this.options.excludeAvailableScreenResolution) { + return this.getAvailableScreenResolution(keys); + } + return keys; + }, + getAvailableScreenResolution: function(keys) { + var available; + if(screen.availWidth && screen.availHeight) { + if(this.options.detectScreenOrientation) { + available = (screen.availHeight > screen.availWidth) ? [screen.availHeight, screen.availWidth] : [screen.availWidth, screen.availHeight]; + } else { + available = [screen.availHeight, screen.availWidth]; + } + } + if(typeof available !== "undefined") { // headless browsers + keys.push({key: "available_resolution", value: available}); + } + return keys; + }, + timezoneOffsetKey: function(keys) { + if(!this.options.excludeTimezoneOffset) { + keys.push({key: "timezone_offset", value: new Date().getTimezoneOffset()}); + } + return keys; + }, + sessionStorageKey: function(keys) { + if(!this.options.excludeSessionStorage && this.hasSessionStorage()) { + keys.push({key: "session_storage", value: 1}); + } + return keys; + }, + localStorageKey: function(keys) { + if(!this.options.excludeSessionStorage && this.hasLocalStorage()) { + keys.push({key: "local_storage", value: 1}); + } + return keys; + }, + indexedDbKey: function(keys) { + if(!this.options.excludeIndexedDB && this.hasIndexedDB()) { + keys.push({key: "indexed_db", value: 1}); + } + return keys; + }, + addBehaviorKey: function(keys) { + //body might not be defined at this point or removed programmatically + if(document.body && !this.options.excludeAddBehavior && document.body.addBehavior) { + keys.push({key: "add_behavior", value: 1}); + } + return keys; + }, + openDatabaseKey: function(keys) { + if(!this.options.excludeOpenDatabase && window.openDatabase) { + keys.push({key: "open_database", value: 1}); + } + return keys; + }, + cpuClassKey: function(keys) { + if(!this.options.excludeCpuClass) { + keys.push({key: "cpu_class", value: this.getNavigatorCpuClass()}); + } + return keys; + }, + platformKey: function(keys) { + if(!this.options.excludePlatform) { + keys.push({key: "navigator_platform", value: this.getNavigatorPlatform()}); + } + return keys; + }, + doNotTrackKey: function(keys) { + if(!this.options.excludeDoNotTrack) { + keys.push({key: "do_not_track", value: this.getDoNotTrack()}); + } + return keys; + }, + canvasKey: function(keys) { + if(!this.options.excludeCanvas && this.isCanvasSupported()) { + keys.push({key: "canvas", value: this.getCanvasFp()}); + } + return keys; + }, + webglKey: function(keys) { + if(this.options.excludeWebGL) { + if(typeof NODEBUG === "undefined"){ + this.log("Skipping WebGL fingerprinting per excludeWebGL configuration option"); + } + return keys; + } + if(!this.isWebGlSupported()) { + if(typeof NODEBUG === "undefined"){ + this.log("Skipping WebGL fingerprinting because it is not supported in this browser"); + } + return keys; + } + keys.push({key: "webgl", value: this.getWebglFp()}); + return keys; + }, + adBlockKey: function(keys){ + if(!this.options.excludeAdBlock) { + keys.push({key: "adblock", value: this.getAdBlock()}); + } + return keys; + }, + hasLiedLanguagesKey: function(keys){ + if(!this.options.excludeHasLiedLanguages){ + keys.push({key: "has_lied_languages", value: this.getHasLiedLanguages()}); + } + return keys; + }, + hasLiedResolutionKey: function(keys){ + if(!this.options.excludeHasLiedResolution){ + keys.push({key: "has_lied_resolution", value: this.getHasLiedResolution()}); + } + return keys; + }, + hasLiedOsKey: function(keys){ + if(!this.options.excludeHasLiedOs){ + keys.push({key: "has_lied_os", value: this.getHasLiedOs()}); + } + return keys; + }, + hasLiedBrowserKey: function(keys){ + if(!this.options.excludeHasLiedBrowser){ + keys.push({key: "has_lied_browser", value: this.getHasLiedBrowser()}); + } + return keys; + }, + fontsKey: function(keys, done) { + if (this.options.excludeJsFonts) { + return this.flashFontsKey(keys, done); + } + return this.jsFontsKey(keys, done); + }, + // flash fonts (will increase fingerprinting time 20X to ~ 130-150ms) + flashFontsKey: function(keys, done) { + if(this.options.excludeFlashFonts) { + if(typeof NODEBUG === "undefined"){ + this.log("Skipping flash fonts detection per excludeFlashFonts configuration option"); + } + return done(keys); + } + // we do flash if swfobject is loaded + if(!this.hasSwfObjectLoaded()){ + if(typeof NODEBUG === "undefined"){ + this.log("Swfobject is not detected, Flash fonts enumeration is skipped"); + } + return done(keys); + } + if(!this.hasMinFlashInstalled()){ + if(typeof NODEBUG === "undefined"){ + this.log("Flash is not installed, skipping Flash fonts enumeration"); + } + return done(keys); + } + if(typeof this.options.swfPath === "undefined"){ + if(typeof NODEBUG === "undefined"){ + this.log("To use Flash fonts detection, you must pass a valid swfPath option, skipping Flash fonts enumeration"); + } + return done(keys); + } + this.loadSwfAndDetectFonts(function(fonts){ + keys.push({key: "swf_fonts", value: fonts.join(";")}); + done(keys); + }); + }, + // kudos to http://www.lalit.org/lab/javascript-css-font-detect/ + jsFontsKey: function(keys, done) { + var that = this; + // doing js fonts detection in a pseudo-async fashion + return setTimeout(function(){ + + // a font will be compared against all the three default fonts. + // and if it doesn't match all 3 then that font is not available. + var baseFonts = ["monospace", "sans-serif", "serif"]; + + var fontList = [ + "Andale Mono", "Arial", "Arial Black", "Arial Hebrew", "Arial MT", "Arial Narrow", "Arial Rounded MT Bold", "Arial Unicode MS", + "Bitstream Vera Sans Mono", "Book Antiqua", "Bookman Old Style", + "Calibri", "Cambria", "Cambria Math", "Century", "Century Gothic", "Century Schoolbook", "Comic Sans", "Comic Sans MS", "Consolas", "Courier", "Courier New", + "Garamond", "Geneva", "Georgia", + "Helvetica", "Helvetica Neue", + "Impact", + "Lucida Bright", "Lucida Calligraphy", "Lucida Console", "Lucida Fax", "LUCIDA GRANDE", "Lucida Handwriting", "Lucida Sans", "Lucida Sans Typewriter", "Lucida Sans Unicode", + "Microsoft Sans Serif", "Monaco", "Monotype Corsiva", "MS Gothic", "MS Outlook", "MS PGothic", "MS Reference Sans Serif", "MS Sans Serif", "MS Serif", "MYRIAD", "MYRIAD PRO", + "Palatino", "Palatino Linotype", + "Segoe Print", "Segoe Script", "Segoe UI", "Segoe UI Light", "Segoe UI Semibold", "Segoe UI Symbol", + "Tahoma", "Times", "Times New Roman", "Times New Roman PS", "Trebuchet MS", + "Verdana", "Wingdings", "Wingdings 2", "Wingdings 3" + ]; + var extendedFontList = [ + "Abadi MT Condensed Light", "Academy Engraved LET", "ADOBE CASLON PRO", "Adobe Garamond", "ADOBE GARAMOND PRO", "Agency FB", "Aharoni", "Albertus Extra Bold", "Albertus Medium", "Algerian", "Amazone BT", "American Typewriter", + "American Typewriter Condensed", "AmerType Md BT", "Andalus", "Angsana New", "AngsanaUPC", "Antique Olive", "Aparajita", "Apple Chancery", "Apple Color Emoji", "Apple SD Gothic Neo", "Arabic Typesetting", "ARCHER", + "ARNO PRO", "Arrus BT", "Aurora Cn BT", "AvantGarde Bk BT", "AvantGarde Md BT", "AVENIR", "Ayuthaya", "Bandy", "Bangla Sangam MN", "Bank Gothic", "BankGothic Md BT", "Baskerville", + "Baskerville Old Face", "Batang", "BatangChe", "Bauer Bodoni", "Bauhaus 93", "Bazooka", "Bell MT", "Bembo", "Benguiat Bk BT", "Berlin Sans FB", "Berlin Sans FB Demi", "Bernard MT Condensed", "BernhardFashion BT", "BernhardMod BT", "Big Caslon", "BinnerD", + "Blackadder ITC", "BlairMdITC TT", "Bodoni 72", "Bodoni 72 Oldstyle", "Bodoni 72 Smallcaps", "Bodoni MT", "Bodoni MT Black", "Bodoni MT Condensed", "Bodoni MT Poster Compressed", + "Bookshelf Symbol 7", "Boulder", "Bradley Hand", "Bradley Hand ITC", "Bremen Bd BT", "Britannic Bold", "Broadway", "Browallia New", "BrowalliaUPC", "Brush Script MT", "Californian FB", "Calisto MT", "Calligrapher", "Candara", + "CaslonOpnface BT", "Castellar", "Centaur", "Cezanne", "CG Omega", "CG Times", "Chalkboard", "Chalkboard SE", "Chalkduster", "Charlesworth", "Charter Bd BT", "Charter BT", "Chaucer", + "ChelthmITC Bk BT", "Chiller", "Clarendon", "Clarendon Condensed", "CloisterBlack BT", "Cochin", "Colonna MT", "Constantia", "Cooper Black", "Copperplate", "Copperplate Gothic", "Copperplate Gothic Bold", + "Copperplate Gothic Light", "CopperplGoth Bd BT", "Corbel", "Cordia New", "CordiaUPC", "Cornerstone", "Coronet", "Cuckoo", "Curlz MT", "DaunPenh", "Dauphin", "David", "DB LCD Temp", "DELICIOUS", "Denmark", + "DFKai-SB", "Didot", "DilleniaUPC", "DIN", "DokChampa", "Dotum", "DotumChe", "Ebrima", "Edwardian Script ITC", "Elephant", "English 111 Vivace BT", "Engravers MT", "EngraversGothic BT", "Eras Bold ITC", "Eras Demi ITC", "Eras Light ITC", "Eras Medium ITC", + "EucrosiaUPC", "Euphemia", "Euphemia UCAS", "EUROSTILE", "Exotc350 Bd BT", "FangSong", "Felix Titling", "Fixedsys", "FONTIN", "Footlight MT Light", "Forte", + "FrankRuehl", "Fransiscan", "Freefrm721 Blk BT", "FreesiaUPC", "Freestyle Script", "French Script MT", "FrnkGothITC Bk BT", "Fruitger", "FRUTIGER", + "Futura", "Futura Bk BT", "Futura Lt BT", "Futura Md BT", "Futura ZBlk BT", "FuturaBlack BT", "Gabriola", "Galliard BT", "Gautami", "Geeza Pro", "Geometr231 BT", "Geometr231 Hv BT", "Geometr231 Lt BT", "GeoSlab 703 Lt BT", + "GeoSlab 703 XBd BT", "Gigi", "Gill Sans", "Gill Sans MT", "Gill Sans MT Condensed", "Gill Sans MT Ext Condensed Bold", "Gill Sans Ultra Bold", "Gill Sans Ultra Bold Condensed", "Gisha", "Gloucester MT Extra Condensed", "GOTHAM", "GOTHAM BOLD", + "Goudy Old Style", "Goudy Stout", "GoudyHandtooled BT", "GoudyOLSt BT", "Gujarati Sangam MN", "Gulim", "GulimChe", "Gungsuh", "GungsuhChe", "Gurmukhi MN", "Haettenschweiler", "Harlow Solid Italic", "Harrington", "Heather", "Heiti SC", "Heiti TC", "HELV", + "Herald", "High Tower Text", "Hiragino Kaku Gothic ProN", "Hiragino Mincho ProN", "Hoefler Text", "Humanst 521 Cn BT", "Humanst521 BT", "Humanst521 Lt BT", "Imprint MT Shadow", "Incised901 Bd BT", "Incised901 BT", + "Incised901 Lt BT", "INCONSOLATA", "Informal Roman", "Informal011 BT", "INTERSTATE", "IrisUPC", "Iskoola Pota", "JasmineUPC", "Jazz LET", "Jenson", "Jester", "Jokerman", "Juice ITC", "Kabel Bk BT", "Kabel Ult BT", "Kailasa", "KaiTi", "Kalinga", "Kannada Sangam MN", + "Kartika", "Kaufmann Bd BT", "Kaufmann BT", "Khmer UI", "KodchiangUPC", "Kokila", "Korinna BT", "Kristen ITC", "Krungthep", "Kunstler Script", "Lao UI", "Latha", "Leelawadee", "Letter Gothic", "Levenim MT", "LilyUPC", "Lithograph", "Lithograph Light", "Long Island", + "Lydian BT", "Magneto", "Maiandra GD", "Malayalam Sangam MN", "Malgun Gothic", + "Mangal", "Marigold", "Marion", "Marker Felt", "Market", "Marlett", "Matisse ITC", "Matura MT Script Capitals", "Meiryo", "Meiryo UI", "Microsoft Himalaya", "Microsoft JhengHei", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Tai Le", + "Microsoft Uighur", "Microsoft YaHei", "Microsoft Yi Baiti", "MingLiU", "MingLiU_HKSCS", "MingLiU_HKSCS-ExtB", "MingLiU-ExtB", "Minion", "Minion Pro", "Miriam", "Miriam Fixed", "Mistral", "Modern", "Modern No. 20", "Mona Lisa Solid ITC TT", "Mongolian Baiti", + "MONO", "MoolBoran", "Mrs Eaves", "MS LineDraw", "MS Mincho", "MS PMincho", "MS Reference Specialty", "MS UI Gothic", "MT Extra", "MUSEO", "MV Boli", + "Nadeem", "Narkisim", "NEVIS", "News Gothic", "News GothicMT", "NewsGoth BT", "Niagara Engraved", "Niagara Solid", "Noteworthy", "NSimSun", "Nyala", "OCR A Extended", "Old Century", "Old English Text MT", "Onyx", "Onyx BT", "OPTIMA", "Oriya Sangam MN", + "OSAKA", "OzHandicraft BT", "Palace Script MT", "Papyrus", "Parchment", "Party LET", "Pegasus", "Perpetua", "Perpetua Titling MT", "PetitaBold", "Pickwick", "Plantagenet Cherokee", "Playbill", "PMingLiU", "PMingLiU-ExtB", + "Poor Richard", "Poster", "PosterBodoni BT", "PRINCETOWN LET", "Pristina", "PTBarnum BT", "Pythagoras", "Raavi", "Rage Italic", "Ravie", "Ribbon131 Bd BT", "Rockwell", "Rockwell Condensed", "Rockwell Extra Bold", "Rod", "Roman", "Sakkal Majalla", + "Santa Fe LET", "Savoye LET", "Sceptre", "Script", "Script MT Bold", "SCRIPTINA", "Serifa", "Serifa BT", "Serifa Th BT", "ShelleyVolante BT", "Sherwood", + "Shonar Bangla", "Showcard Gothic", "Shruti", "Signboard", "SILKSCREEN", "SimHei", "Simplified Arabic", "Simplified Arabic Fixed", "SimSun", "SimSun-ExtB", "Sinhala Sangam MN", "Sketch Rockwell", "Skia", "Small Fonts", "Snap ITC", "Snell Roundhand", "Socket", + "Souvenir Lt BT", "Staccato222 BT", "Steamer", "Stencil", "Storybook", "Styllo", "Subway", "Swis721 BlkEx BT", "Swiss911 XCm BT", "Sylfaen", "Synchro LET", "System", "Tamil Sangam MN", "Technical", "Teletype", "Telugu Sangam MN", "Tempus Sans ITC", + "Terminal", "Thonburi", "Traditional Arabic", "Trajan", "TRAJAN PRO", "Tristan", "Tubular", "Tunga", "Tw Cen MT", "Tw Cen MT Condensed", "Tw Cen MT Condensed Extra Bold", + "TypoUpright BT", "Unicorn", "Univers", "Univers CE 55 Medium", "Univers Condensed", "Utsaah", "Vagabond", "Vani", "Vijaya", "Viner Hand ITC", "VisualUI", "Vivaldi", "Vladimir Script", "Vrinda", "Westminster", "WHITNEY", "Wide Latin", + "ZapfEllipt BT", "ZapfHumnst BT", "ZapfHumnst Dm BT", "Zapfino", "Zurich BlkEx BT", "Zurich Ex BT", "ZWAdobeF"]; + + if(that.options.extendedJsFonts) { + fontList = fontList.concat(extendedFontList); + } + + fontList = fontList.concat(that.options.userDefinedFonts); + + //we use m or w because these two characters take up the maximum width. + // And we use a LLi so that the same matching fonts can get separated + var testString = "mmmmmmmmmmlli"; + + //we test using 72px font size, we may use any size. I guess larger the better. + var testSize = "72px"; + + var h = document.getElementsByTagName("body")[0]; + + // div to load spans for the base fonts + var baseFontsDiv = document.createElement("div"); + + // div to load spans for the fonts to detect + var fontsDiv = document.createElement("div"); + + var defaultWidth = {}; + var defaultHeight = {}; + + // creates a span where the fonts will be loaded + var createSpan = function() { + var s = document.createElement("span"); + /* + * We need this css as in some weird browser this + * span elements shows up for a microSec which creates a + * bad user experience + */ + s.style.position = "absolute"; + s.style.left = "-9999px"; + s.style.fontSize = testSize; + s.style.lineHeight = "normal"; + s.innerHTML = testString; + return s; + }; + + // creates a span and load the font to detect and a base font for fallback + var createSpanWithFonts = function(fontToDetect, baseFont) { + var s = createSpan(); + s.style.fontFamily = "'" + fontToDetect + "'," + baseFont; + return s; + }; + + // creates spans for the base fonts and adds them to baseFontsDiv + var initializeBaseFontsSpans = function() { + var spans = []; + for (var index = 0, length = baseFonts.length; index < length; index++) { + var s = createSpan(); + s.style.fontFamily = baseFonts[index]; + baseFontsDiv.appendChild(s); + spans.push(s); + } + return spans; + }; + + // creates spans for the fonts to detect and adds them to fontsDiv + var initializeFontsSpans = function() { + var spans = {}; + for(var i = 0, l = fontList.length; i < l; i++) { + var fontSpans = []; + for(var j = 0, numDefaultFonts = baseFonts.length; j < numDefaultFonts; j++) { + var s = createSpanWithFonts(fontList[i], baseFonts[j]); + fontsDiv.appendChild(s); + fontSpans.push(s); + } + spans[fontList[i]] = fontSpans; // Stores {fontName : [spans for that font]} + } + return spans; + }; + + // checks if a font is available + var isFontAvailable = function(fontSpans) { + var detected = false; + for(var i = 0; i < baseFonts.length; i++) { + detected = (fontSpans[i].offsetWidth !== defaultWidth[baseFonts[i]] || fontSpans[i].offsetHeight !== defaultHeight[baseFonts[i]]); + if(detected) { + return detected; + } + } + return detected; + }; + + // create spans for base fonts + var baseFontsSpans = initializeBaseFontsSpans(); + + // add the spans to the DOM + h.appendChild(baseFontsDiv); + + // get the default width for the three base fonts + for (var index = 0, length = baseFonts.length; index < length; index++) { + defaultWidth[baseFonts[index]] = baseFontsSpans[index].offsetWidth; // width for the default font + defaultHeight[baseFonts[index]] = baseFontsSpans[index].offsetHeight; // height for the default font + } + + // create spans for fonts to detect + var fontsSpans = initializeFontsSpans(); + + // add all the spans to the DOM + h.appendChild(fontsDiv); + + // check available fonts + var available = []; + for(var i = 0, l = fontList.length; i < l; i++) { + if(isFontAvailable(fontsSpans[fontList[i]])) { + available.push(fontList[i]); + } + } + + // remove spans from DOM + h.removeChild(fontsDiv); + h.removeChild(baseFontsDiv); + + keys.push({key: "js_fonts", value: available}); + done(keys); + }, 1); + }, + pluginsKey: function(keys) { + if(!this.options.excludePlugins){ + if(this.isIE()){ + if(!this.options.excludeIEPlugins) { + keys.push({key: "ie_plugins", value: this.getIEPlugins()}); + } + } else { + keys.push({key: "regular_plugins", value: this.getRegularPlugins()}); + } + } + return keys; + }, + getRegularPlugins: function () { + var plugins = []; + for(var i = 0, l = navigator.plugins.length; i < l; i++) { + plugins.push(navigator.plugins[i]); + } + // sorting plugins only for those user agents, that we know randomize the plugins + // every time we try to enumerate them + if(this.pluginsShouldBeSorted()) { + plugins = plugins.sort(function(a, b) { + if(a.name > b.name){ return 1; } + if(a.name < b.name){ return -1; } + return 0; + }); + } + return this.map(plugins, function (p) { + var mimeTypes = this.map(p, function(mt){ + return [mt.type, mt.suffixes].join("~"); + }).join(","); + return [p.name, p.description, mimeTypes].join("::"); + }, this); + }, + getIEPlugins: function () { + var result = []; + if((Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(window, "ActiveXObject")) || ("ActiveXObject" in window)) { + var names = [ + "AcroPDF.PDF", // Adobe PDF reader 7+ + "Adodb.Stream", + "AgControl.AgControl", // Silverlight + "DevalVRXCtrl.DevalVRXCtrl.1", + "MacromediaFlashPaper.MacromediaFlashPaper", + "Msxml2.DOMDocument", + "Msxml2.XMLHTTP", + "PDF.PdfCtrl", // Adobe PDF reader 6 and earlier, brrr + "QuickTime.QuickTime", // QuickTime + "QuickTimeCheckObject.QuickTimeCheck.1", + "RealPlayer", + "RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)", + "RealVideo.RealVideo(tm) ActiveX Control (32-bit)", + "Scripting.Dictionary", + "SWCtl.SWCtl", // ShockWave player + "Shell.UIHelper", + "ShockwaveFlash.ShockwaveFlash", //flash plugin + "Skype.Detection", + "TDCCtl.TDCCtl", + "WMPlayer.OCX", // Windows media player + "rmocx.RealPlayer G2 Control", + "rmocx.RealPlayer G2 Control.1" + ]; + // starting to detect plugins in IE + result = this.map(names, function(name) { + try { + new ActiveXObject(name); // eslint-disable-no-new + return name; + } catch(e) { + return null; + } + }); + } + if(navigator.plugins) { + result = result.concat(this.getRegularPlugins()); + } + return result; + }, + pluginsShouldBeSorted: function () { + var should = false; + for(var i = 0, l = this.options.sortPluginsFor.length; i < l; i++) { + var re = this.options.sortPluginsFor[i]; + if(navigator.userAgent.match(re)) { + should = true; + break; + } + } + return should; + }, + touchSupportKey: function (keys) { + if(!this.options.excludeTouchSupport){ + keys.push({key: "touch_support", value: this.getTouchSupport()}); + } + return keys; + }, + hardwareConcurrencyKey: function(keys){ + if(!this.options.excludeHardwareConcurrency){ + keys.push({key: "hardware_concurrency", value: this.getHardwareConcurrency()}); + } + return keys; + }, + hasSessionStorage: function () { + try { + return !!window.sessionStorage; + } catch(e) { + return true; // SecurityError when referencing it means it exists + } + }, + // https://bugzilla.mozilla.org/show_bug.cgi?id=781447 + hasLocalStorage: function () { + try { + return !!window.localStorage; + } catch(e) { + return true; // SecurityError when referencing it means it exists + } + }, + hasIndexedDB: function (){ + try { + return !!window.indexedDB; + } catch(e) { + return true; // SecurityError when referencing it means it exists + } + }, + getHardwareConcurrency: function(){ + if(navigator.hardwareConcurrency){ + return navigator.hardwareConcurrency; + } + return "unknown"; + }, + getNavigatorCpuClass: function () { + if(navigator.cpuClass){ + return navigator.cpuClass; + } else { + return "unknown"; + } + }, + getNavigatorPlatform: function () { + if(navigator.platform) { + return navigator.platform; + } else { + return "unknown"; + } + }, + getDoNotTrack: function () { + if(navigator.doNotTrack) { + return navigator.doNotTrack; + } else if (navigator.msDoNotTrack) { + return navigator.msDoNotTrack; + } else if (window.doNotTrack) { + return window.doNotTrack; + } else { + return "unknown"; + } + }, + // This is a crude and primitive touch screen detection. + // It's not possible to currently reliably detect the availability of a touch screen + // with a JS, without actually subscribing to a touch event. + // http://www.stucox.com/blog/you-cant-detect-a-touchscreen/ + // https://github.com/Modernizr/Modernizr/issues/548 + // method returns an array of 3 values: + // maxTouchPoints, the success or failure of creating a TouchEvent, + // and the availability of the 'ontouchstart' property + getTouchSupport: function () { + var maxTouchPoints = 0; + var touchEvent = false; + if(typeof navigator.maxTouchPoints !== "undefined") { + maxTouchPoints = navigator.maxTouchPoints; + } else if (typeof navigator.msMaxTouchPoints !== "undefined") { + maxTouchPoints = navigator.msMaxTouchPoints; + } + try { + document.createEvent("TouchEvent"); + touchEvent = true; + } catch(_) { /* squelch */ } + var touchStart = "ontouchstart" in window; + return [maxTouchPoints, touchEvent, touchStart]; + }, + // https://www.browserleaks.com/canvas#how-does-it-work + getCanvasFp: function() { + var result = []; + // Very simple now, need to make it more complex (geo shapes etc) + var canvas = document.createElement("canvas"); + canvas.width = 2000; + canvas.height = 200; + canvas.style.display = "inline"; + var ctx = canvas.getContext("2d"); + // detect browser support of canvas winding + // http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/ + // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/canvas/winding.js + ctx.rect(0, 0, 10, 10); + ctx.rect(2, 2, 6, 6); + result.push("canvas winding:" + ((ctx.isPointInPath(5, 5, "evenodd") === false) ? "yes" : "no")); + + ctx.textBaseline = "alphabetic"; + ctx.fillStyle = "#f60"; + ctx.fillRect(125, 1, 62, 20); + ctx.fillStyle = "#069"; + // https://github.com/Valve/fingerprintjs2/issues/66 + if(this.options.dontUseFakeFontInCanvas) { + ctx.font = "11pt Arial"; + } else { + ctx.font = "11pt no-real-font-123"; + } + ctx.fillText("Cwm fjordbank glyphs vext quiz, \ud83d\ude03", 2, 15); + ctx.fillStyle = "rgba(102, 204, 0, 0.2)"; + ctx.font = "18pt Arial"; + ctx.fillText("Cwm fjordbank glyphs vext quiz, \ud83d\ude03", 4, 45); + + // canvas blending + // http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/ + // http://jsfiddle.net/NDYV8/16/ + ctx.globalCompositeOperation = "multiply"; + ctx.fillStyle = "rgb(255,0,255)"; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = "rgb(0,255,255)"; + ctx.beginPath(); + ctx.arc(100, 50, 50, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = "rgb(255,255,0)"; + ctx.beginPath(); + ctx.arc(75, 100, 50, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fill(); + ctx.fillStyle = "rgb(255,0,255)"; + // canvas winding + // http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/ + // http://jsfiddle.net/NDYV8/19/ + ctx.arc(75, 75, 75, 0, Math.PI * 2, true); + ctx.arc(75, 75, 25, 0, Math.PI * 2, true); + ctx.fill("evenodd"); + + result.push("canvas fp:" + canvas.toDataURL()); + return result.join("~"); + }, + + getWebglFp: function() { + var gl; + var fa2s = function(fa) { + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.enable(gl.DEPTH_TEST); + gl.depthFunc(gl.LEQUAL); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + return "[" + fa[0] + ", " + fa[1] + "]"; + }; + var maxAnisotropy = function(gl) { + var anisotropy, ext = gl.getExtension("EXT_texture_filter_anisotropic") || gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic") || gl.getExtension("MOZ_EXT_texture_filter_anisotropic"); + return ext ? (anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT), 0 === anisotropy && (anisotropy = 2), anisotropy) : null; + }; + gl = this.getWebglCanvas(); + if(!gl) { return null; } + // WebGL fingerprinting is a combination of techniques, found in MaxMind antifraud script & Augur fingerprinting. + // First it draws a gradient object with shaders and convers the image to the Base64 string. + // Then it enumerates all WebGL extensions & capabilities and appends them to the Base64 string, resulting in a huge WebGL string, potentially very unique on each device + // Since iOS supports webgl starting from version 8.1 and 8.1 runs on several graphics chips, the results may be different across ios devices, but we need to verify it. + var result = []; + var vShaderTemplate = "attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}"; + var fShaderTemplate = "precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}"; + var vertexPosBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer); + var vertices = new Float32Array([-.2, -.9, 0, .4, -.26, 0, 0, .732134444, 0]); + gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); + vertexPosBuffer.itemSize = 3; + vertexPosBuffer.numItems = 3; + var program = gl.createProgram(), vshader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vshader, vShaderTemplate); + gl.compileShader(vshader); + var fshader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fshader, fShaderTemplate); + gl.compileShader(fshader); + gl.attachShader(program, vshader); + gl.attachShader(program, fshader); + gl.linkProgram(program); + gl.useProgram(program); + program.vertexPosAttrib = gl.getAttribLocation(program, "attrVertex"); + program.offsetUniform = gl.getUniformLocation(program, "uniformOffset"); + gl.enableVertexAttribArray(program.vertexPosArray); + gl.vertexAttribPointer(program.vertexPosAttrib, vertexPosBuffer.itemSize, gl.FLOAT, !1, 0, 0); + gl.uniform2f(program.offsetUniform, 1, 1); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexPosBuffer.numItems); + if (gl.canvas != null) { result.push(gl.canvas.toDataURL()); } + result.push("extensions:" + gl.getSupportedExtensions().join(";")); + result.push("webgl aliased line width range:" + fa2s(gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE))); + result.push("webgl aliased point size range:" + fa2s(gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE))); + result.push("webgl alpha bits:" + gl.getParameter(gl.ALPHA_BITS)); + result.push("webgl antialiasing:" + (gl.getContextAttributes().antialias ? "yes" : "no")); + result.push("webgl blue bits:" + gl.getParameter(gl.BLUE_BITS)); + result.push("webgl depth bits:" + gl.getParameter(gl.DEPTH_BITS)); + result.push("webgl green bits:" + gl.getParameter(gl.GREEN_BITS)); + result.push("webgl max anisotropy:" + maxAnisotropy(gl)); + result.push("webgl max combined texture image units:" + gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS)); + result.push("webgl max cube map texture size:" + gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)); + result.push("webgl max fragment uniform vectors:" + gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS)); + result.push("webgl max render buffer size:" + gl.getParameter(gl.MAX_RENDERBUFFER_SIZE)); + result.push("webgl max texture image units:" + gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)); + result.push("webgl max texture size:" + gl.getParameter(gl.MAX_TEXTURE_SIZE)); + result.push("webgl max varying vectors:" + gl.getParameter(gl.MAX_VARYING_VECTORS)); + result.push("webgl max vertex attribs:" + gl.getParameter(gl.MAX_VERTEX_ATTRIBS)); + result.push("webgl max vertex texture image units:" + gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS)); + result.push("webgl max vertex uniform vectors:" + gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS)); + result.push("webgl max viewport dims:" + fa2s(gl.getParameter(gl.MAX_VIEWPORT_DIMS))); + result.push("webgl red bits:" + gl.getParameter(gl.RED_BITS)); + result.push("webgl renderer:" + gl.getParameter(gl.RENDERER)); + result.push("webgl shading language version:" + gl.getParameter(gl.SHADING_LANGUAGE_VERSION)); + result.push("webgl stencil bits:" + gl.getParameter(gl.STENCIL_BITS)); + result.push("webgl vendor:" + gl.getParameter(gl.VENDOR)); + result.push("webgl version:" + gl.getParameter(gl.VERSION)); + + if (!gl.getShaderPrecisionFormat) { + if (typeof NODEBUG === "undefined") { + this.log("WebGL fingerprinting is incomplete, because your browser does not support getShaderPrecisionFormat"); + } + return result.join("~"); + } + + result.push("webgl vertex shader high float precision:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision); + result.push("webgl vertex shader high float precision rangeMin:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT ).rangeMin); + result.push("webgl vertex shader high float precision rangeMax:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT ).rangeMax); + result.push("webgl vertex shader medium float precision:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision); + result.push("webgl vertex shader medium float precision rangeMin:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).rangeMin); + result.push("webgl vertex shader medium float precision rangeMax:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).rangeMax); + result.push("webgl vertex shader low float precision:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_FLOAT ).precision); + result.push("webgl vertex shader low float precision rangeMin:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_FLOAT ).rangeMin); + result.push("webgl vertex shader low float precision rangeMax:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_FLOAT ).rangeMax); + result.push("webgl fragment shader high float precision:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision); + result.push("webgl fragment shader high float precision rangeMin:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).rangeMin); + result.push("webgl fragment shader high float precision rangeMax:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).rangeMax); + result.push("webgl fragment shader medium float precision:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision); + result.push("webgl fragment shader medium float precision rangeMin:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).rangeMin); + result.push("webgl fragment shader medium float precision rangeMax:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).rangeMax); + result.push("webgl fragment shader low float precision:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT ).precision); + result.push("webgl fragment shader low float precision rangeMin:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT ).rangeMin); + result.push("webgl fragment shader low float precision rangeMax:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT ).rangeMax); + result.push("webgl vertex shader high int precision:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_INT ).precision); + result.push("webgl vertex shader high int precision rangeMin:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_INT ).rangeMin); + result.push("webgl vertex shader high int precision rangeMax:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_INT ).rangeMax); + result.push("webgl vertex shader medium int precision:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_INT ).precision); + result.push("webgl vertex shader medium int precision rangeMin:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_INT ).rangeMin); + result.push("webgl vertex shader medium int precision rangeMax:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_INT ).rangeMax); + result.push("webgl vertex shader low int precision:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_INT ).precision); + result.push("webgl vertex shader low int precision rangeMin:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_INT ).rangeMin); + result.push("webgl vertex shader low int precision rangeMax:" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_INT ).rangeMax); + result.push("webgl fragment shader high int precision:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT ).precision); + result.push("webgl fragment shader high int precision rangeMin:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT ).rangeMin); + result.push("webgl fragment shader high int precision rangeMax:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT ).rangeMax); + result.push("webgl fragment shader medium int precision:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT ).precision); + result.push("webgl fragment shader medium int precision rangeMin:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT ).rangeMin); + result.push("webgl fragment shader medium int precision rangeMax:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT ).rangeMax); + result.push("webgl fragment shader low int precision:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT ).precision); + result.push("webgl fragment shader low int precision rangeMin:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT ).rangeMin); + result.push("webgl fragment shader low int precision rangeMax:" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT ).rangeMax); + return result.join("~"); + }, + getAdBlock: function(){ + var ads = document.createElement("div"); + ads.innerHTML = " "; + ads.className = "adsbox"; + var result = false; + try { + // body may not exist, that's why we need try/catch + document.body.appendChild(ads); + result = document.getElementsByClassName("adsbox")[0].offsetHeight === 0; + document.body.removeChild(ads); + } catch (e) { + result = false; + } + return result; + }, + getHasLiedLanguages: function(){ + //We check if navigator.language is equal to the first language of navigator.languages + if(typeof navigator.languages !== "undefined"){ + try { + var firstLanguages = navigator.languages[0].substr(0, 2); + if(firstLanguages !== navigator.language.substr(0, 2)){ + return true; + } + } catch(err) { + return true; + } + } + return false; + }, + getHasLiedResolution: function(){ + if(screen.width < screen.availWidth){ + return true; + } + if(screen.height < screen.availHeight){ + return true; + } + return false; + }, + getHasLiedOs: function(){ + var userAgent = navigator.userAgent.toLowerCase(); + var oscpu = navigator.oscpu; + var platform = navigator.platform.toLowerCase(); + var os; + //We extract the OS from the user agent (respect the order of the if else if statement) + if(userAgent.indexOf("windows phone") >= 0){ + os = "Windows Phone"; + } else if(userAgent.indexOf("win") >= 0){ + os = "Windows"; + } else if(userAgent.indexOf("android") >= 0){ + os = "Android"; + } else if(userAgent.indexOf("linux") >= 0){ + os = "Linux"; + } else if(userAgent.indexOf("iphone") >= 0 || userAgent.indexOf("ipad") >= 0 ){ + os = "iOS"; + } else if(userAgent.indexOf("mac") >= 0){ + os = "Mac"; + } else{ + os = "Other"; + } + // We detect if the person uses a mobile device + var mobileDevice; + if (("ontouchstart" in window) || + (navigator.maxTouchPoints > 0) || + (navigator.msMaxTouchPoints > 0)) { + mobileDevice = true; + } else{ + mobileDevice = false; + } + + if(mobileDevice && os !== "Windows Phone" && os !== "Android" && os !== "iOS" && os !== "Other"){ + return true; + } + + // We compare oscpu with the OS extracted from the UA + if(typeof oscpu !== "undefined"){ + oscpu = oscpu.toLowerCase(); + if(oscpu.indexOf("win") >= 0 && os !== "Windows" && os !== "Windows Phone"){ + return true; + } else if(oscpu.indexOf("linux") >= 0 && os !== "Linux" && os !== "Android"){ + return true; + } else if(oscpu.indexOf("mac") >= 0 && os !== "Mac" && os !== "iOS"){ + return true; + } else if(oscpu.indexOf("win") === 0 && oscpu.indexOf("linux") === 0 && oscpu.indexOf("mac") >= 0 && os !== "other"){ + return true; + } + } + + //We compare platform with the OS extracted from the UA + if(platform.indexOf("win") >= 0 && os !== "Windows" && os !== "Windows Phone"){ + return true; + } else if((platform.indexOf("linux") >= 0 || platform.indexOf("android") >= 0 || platform.indexOf("pike") >= 0) && os !== "Linux" && os !== "Android"){ + return true; + } else if((platform.indexOf("mac") >= 0 || platform.indexOf("ipad") >= 0 || platform.indexOf("ipod") >= 0 || platform.indexOf("iphone") >= 0) && os !== "Mac" && os !== "iOS"){ + return true; + } else if(platform.indexOf("win") === 0 && platform.indexOf("linux") === 0 && platform.indexOf("mac") >= 0 && os !== "other"){ + return true; + } + + if(typeof navigator.plugins === "undefined" && os !== "Windows" && os !== "Windows Phone"){ + //We are are in the case where the person uses ie, therefore we can infer that it's windows + return true; + } + + return false; + }, + getHasLiedBrowser: function () { + var userAgent = navigator.userAgent.toLowerCase(); + var productSub = navigator.productSub; + + //we extract the browser from the user agent (respect the order of the tests) + var browser; + if(userAgent.indexOf("firefox") >= 0){ + browser = "Firefox"; + } else if(userAgent.indexOf("opera") >= 0 || userAgent.indexOf("opr") >= 0){ + browser = "Opera"; + } else if(userAgent.indexOf("chrome") >= 0){ + browser = "Chrome"; + } else if(userAgent.indexOf("safari") >= 0){ + browser = "Safari"; + } else if(userAgent.indexOf("trident") >= 0){ + browser = "Internet Explorer"; + } else{ + browser = "Other"; + } + + if((browser === "Chrome" || browser === "Safari" || browser === "Opera") && productSub !== "20030107"){ + return true; + } + + var tempRes = eval.toString().length; + if(tempRes === 37 && browser !== "Safari" && browser !== "Firefox" && browser !== "Other"){ + return true; + } else if(tempRes === 39 && browser !== "Internet Explorer" && browser !== "Other"){ + return true; + } else if(tempRes === 33 && browser !== "Chrome" && browser !== "Opera" && browser !== "Other"){ + return true; + } + + //We create an error to see how it is handled + var errFirefox; + try { + throw "a"; + } catch(err){ + try{ + err.toSource(); + errFirefox = true; + } catch(errOfErr){ + errFirefox = false; + } + } + if(errFirefox && browser !== "Firefox" && browser !== "Other"){ + return true; + } + return false; + }, + isCanvasSupported: function () { + var elem = document.createElement("canvas"); + return !!(elem.getContext && elem.getContext("2d")); + }, + isWebGlSupported: function() { + // code taken from Modernizr + if (!this.isCanvasSupported()) { + return false; + } + + var canvas = document.createElement("canvas"), + glContext; + + try { + glContext = canvas.getContext && (canvas.getContext("webgl") || canvas.getContext("experimental-webgl")); + } catch(e) { + glContext = false; + } + + return !!window.WebGLRenderingContext && !!glContext; + }, + isIE: function () { + if(navigator.appName === "Microsoft Internet Explorer") { + return true; + } else if(navigator.appName === "Netscape" && /Trident/.test(navigator.userAgent)) { // IE 11 + return true; + } + return false; + }, + hasSwfObjectLoaded: function(){ + return typeof window.swfobject !== "undefined"; + }, + hasMinFlashInstalled: function () { + return swfobject.hasFlashPlayerVersion("9.0.0"); + }, + addFlashDivNode: function() { + var node = document.createElement("div"); + node.setAttribute("id", this.options.swfContainerId); + document.body.appendChild(node); + }, + loadSwfAndDetectFonts: function(done) { + var hiddenCallback = "___fp_swf_loaded"; + window[hiddenCallback] = function(fonts) { + done(fonts); + }; + var id = this.options.swfContainerId; + this.addFlashDivNode(); + var flashvars = { onReady: hiddenCallback}; + var flashparams = { allowScriptAccess: "always", menu: "false" }; + swfobject.embedSWF(this.options.swfPath, id, "1", "1", "9.0.0", false, flashvars, flashparams, {}); + }, + getWebglCanvas: function() { + var canvas = document.createElement("canvas"); + var gl = null; + try { + gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); + } catch(e) { /* squelch */ } + if (!gl) { gl = null; } + return gl; + }, + each: function (obj, iterator, context) { + if (obj === null) { + return; + } + if (this.nativeForEach && obj.forEach === this.nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if (iterator.call(context, obj[i], i, obj) === {}) { return; } + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if (iterator.call(context, obj[key], key, obj) === {}) { return; } + } + } + } + }, + + map: function(obj, iterator, context) { + var results = []; + // Not using strict equality so that this acts as a + // shortcut to checking for `null` and `undefined`. + if (obj == null) { return results; } + if (this.nativeMap && obj.map === this.nativeMap) { return obj.map(iterator, context); } + this.each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + return results; + }, + + /// MurmurHash3 related functions + + // + // Given two 64bit ints (as an array of two 32bit ints) returns the two + // added together as a 64bit int (as an array of two 32bit ints). + // + x64Add: function(m, n) { + m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]; + n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]; + var o = [0, 0, 0, 0]; + o[3] += m[3] + n[3]; + o[2] += o[3] >>> 16; + o[3] &= 0xffff; + o[2] += m[2] + n[2]; + o[1] += o[2] >>> 16; + o[2] &= 0xffff; + o[1] += m[1] + n[1]; + o[0] += o[1] >>> 16; + o[1] &= 0xffff; + o[0] += m[0] + n[0]; + o[0] &= 0xffff; + return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]; + }, + + // + // Given two 64bit ints (as an array of two 32bit ints) returns the two + // multiplied together as a 64bit int (as an array of two 32bit ints). + // + x64Multiply: function(m, n) { + m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]; + n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]; + var o = [0, 0, 0, 0]; + o[3] += m[3] * n[3]; + o[2] += o[3] >>> 16; + o[3] &= 0xffff; + o[2] += m[2] * n[3]; + o[1] += o[2] >>> 16; + o[2] &= 0xffff; + o[2] += m[3] * n[2]; + o[1] += o[2] >>> 16; + o[2] &= 0xffff; + o[1] += m[1] * n[3]; + o[0] += o[1] >>> 16; + o[1] &= 0xffff; + o[1] += m[2] * n[2]; + o[0] += o[1] >>> 16; + o[1] &= 0xffff; + o[1] += m[3] * n[1]; + o[0] += o[1] >>> 16; + o[1] &= 0xffff; + o[0] += (m[0] * n[3]) + (m[1] * n[2]) + (m[2] * n[1]) + (m[3] * n[0]); + o[0] &= 0xffff; + return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]; + }, + // + // Given a 64bit int (as an array of two 32bit ints) and an int + // representing a number of bit positions, returns the 64bit int (as an + // array of two 32bit ints) rotated left by that number of positions. + // + x64Rotl: function(m, n) { + n %= 64; + if (n === 32) { + return [m[1], m[0]]; + } + else if (n < 32) { + return [(m[0] << n) | (m[1] >>> (32 - n)), (m[1] << n) | (m[0] >>> (32 - n))]; + } + else { + n -= 32; + return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))]; + } + }, + // + // Given a 64bit int (as an array of two 32bit ints) and an int + // representing a number of bit positions, returns the 64bit int (as an + // array of two 32bit ints) shifted left by that number of positions. + // + x64LeftShift: function(m, n) { + n %= 64; + if (n === 0) { + return m; + } + else if (n < 32) { + return [(m[0] << n) | (m[1] >>> (32 - n)), m[1] << n]; + } + else { + return [m[1] << (n - 32), 0]; + } + }, + // + // Given two 64bit ints (as an array of two 32bit ints) returns the two + // xored together as a 64bit int (as an array of two 32bit ints). + // + x64Xor: function(m, n) { + return [m[0] ^ n[0], m[1] ^ n[1]]; + }, + // + // Given a block, returns murmurHash3's final x64 mix of that block. + // (`[0, h[0] >>> 1]` is a 33 bit unsigned right shift. This is the + // only place where we need to right shift 64bit ints.) + // + x64Fmix: function(h) { + h = this.x64Xor(h, [0, h[0] >>> 1]); + h = this.x64Multiply(h, [0xff51afd7, 0xed558ccd]); + h = this.x64Xor(h, [0, h[0] >>> 1]); + h = this.x64Multiply(h, [0xc4ceb9fe, 0x1a85ec53]); + h = this.x64Xor(h, [0, h[0] >>> 1]); + return h; + }, + + // + // Given a string and an optional seed as an int, returns a 128 bit + // hash using the x64 flavor of MurmurHash3, as an unsigned hex. + // + x64hash128: function (key, seed) { + key = key || ""; + seed = seed || 0; + var remainder = key.length % 16; + var bytes = key.length - remainder; + var h1 = [0, seed]; + var h2 = [0, seed]; + var k1 = [0, 0]; + var k2 = [0, 0]; + var c1 = [0x87c37b91, 0x114253d5]; + var c2 = [0x4cf5ad43, 0x2745937f]; + for (var i = 0; i < bytes; i = i + 16) { + k1 = [((key.charCodeAt(i + 4) & 0xff)) | ((key.charCodeAt(i + 5) & 0xff) << 8) | ((key.charCodeAt(i + 6) & 0xff) << 16) | ((key.charCodeAt(i + 7) & 0xff) << 24), ((key.charCodeAt(i) & 0xff)) | ((key.charCodeAt(i + 1) & 0xff) << 8) | ((key.charCodeAt(i + 2) & 0xff) << 16) | ((key.charCodeAt(i + 3) & 0xff) << 24)]; + k2 = [((key.charCodeAt(i + 12) & 0xff)) | ((key.charCodeAt(i + 13) & 0xff) << 8) | ((key.charCodeAt(i + 14) & 0xff) << 16) | ((key.charCodeAt(i + 15) & 0xff) << 24), ((key.charCodeAt(i + 8) & 0xff)) | ((key.charCodeAt(i + 9) & 0xff) << 8) | ((key.charCodeAt(i + 10) & 0xff) << 16) | ((key.charCodeAt(i + 11) & 0xff) << 24)]; + k1 = this.x64Multiply(k1, c1); + k1 = this.x64Rotl(k1, 31); + k1 = this.x64Multiply(k1, c2); + h1 = this.x64Xor(h1, k1); + h1 = this.x64Rotl(h1, 27); + h1 = this.x64Add(h1, h2); + h1 = this.x64Add(this.x64Multiply(h1, [0, 5]), [0, 0x52dce729]); + k2 = this.x64Multiply(k2, c2); + k2 = this.x64Rotl(k2, 33); + k2 = this.x64Multiply(k2, c1); + h2 = this.x64Xor(h2, k2); + h2 = this.x64Rotl(h2, 31); + h2 = this.x64Add(h2, h1); + h2 = this.x64Add(this.x64Multiply(h2, [0, 5]), [0, 0x38495ab5]); + } + k1 = [0, 0]; + k2 = [0, 0]; + switch(remainder) { + case 15: + k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 14)], 48)); + case 14: + k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 13)], 40)); + case 13: + k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 12)], 32)); + case 12: + k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 11)], 24)); + case 11: + k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 10)], 16)); + case 10: + k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 9)], 8)); + case 9: + k2 = this.x64Xor(k2, [0, key.charCodeAt(i + 8)]); + k2 = this.x64Multiply(k2, c2); + k2 = this.x64Rotl(k2, 33); + k2 = this.x64Multiply(k2, c1); + h2 = this.x64Xor(h2, k2); + case 8: + k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 7)], 56)); + case 7: + k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 6)], 48)); + case 6: + k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 5)], 40)); + case 5: + k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 4)], 32)); + case 4: + k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 3)], 24)); + case 3: + k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 2)], 16)); + case 2: + k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 1)], 8)); + case 1: + k1 = this.x64Xor(k1, [0, key.charCodeAt(i)]); + k1 = this.x64Multiply(k1, c1); + k1 = this.x64Rotl(k1, 31); + k1 = this.x64Multiply(k1, c2); + h1 = this.x64Xor(h1, k1); + } + h1 = this.x64Xor(h1, [0, key.length]); + h2 = this.x64Xor(h2, [0, key.length]); + h1 = this.x64Add(h1, h2); + h2 = this.x64Add(h2, h1); + h1 = this.x64Fmix(h1); + h2 = this.x64Fmix(h2); + h1 = this.x64Add(h1, h2); + h2 = this.x64Add(h2, h1); + return ("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8); + } + }; + Fingerprint2.VERSION = "1.4.4"; + return Fingerprint2; +}); diff --git a/clients/electron_app/lib/fingerprint2.min.js b/clients/electron_app/lib/fingerprint2.min.js new file mode 100644 index 0000000..638439d --- /dev/null +++ b/clients/electron_app/lib/fingerprint2.min.js @@ -0,0 +1,4 @@ +!function(e,t,i){"use strict";"function"==typeof define&&define.amd?define(i):"undefined"!=typeof module&&module.exports?module.exports=i():t.exports?t.exports=i():t[e]=i()}("Fingerprint2",this,function(){"use strict";Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){var i;if(null==this)throw new TypeError("'this' is null or undefined");var a=Object(this),r=a.length>>>0;if(0===r)return-1;var n=+t||0;if(Math.abs(n)===1/0&&(n=0),n>=r)return-1;for(i=Math.max(n>=0?n:r-Math.abs(n),0);iscreen.width?[screen.height,screen.width]:[screen.width,screen.height],"undefined"!=typeof t&&e.push({key:"resolution",value:t}),e},availableScreenResolutionKey:function(e){return this.options.excludeAvailableScreenResolution?e:this.getAvailableScreenResolution(e)},getAvailableScreenResolution:function(e){var t;return screen.availWidth&&screen.availHeight&&(t=this.options.detectScreenOrientation?screen.availHeight>screen.availWidth?[screen.availHeight,screen.availWidth]:[screen.availWidth,screen.availHeight]:[screen.availHeight,screen.availWidth]),"undefined"!=typeof t&&e.push({key:"available_resolution",value:t}),e},timezoneOffsetKey:function(e){return this.options.excludeTimezoneOffset||e.push({key:"timezone_offset",value:(new Date).getTimezoneOffset()}),e},sessionStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasSessionStorage()&&e.push({key:"session_storage",value:1}),e},localStorageKey:function(e){return!this.options.excludeSessionStorage&&this.hasLocalStorage()&&e.push({key:"local_storage",value:1}),e},indexedDbKey:function(e){return!this.options.excludeIndexedDB&&this.hasIndexedDB()&&e.push({key:"indexed_db",value:1}),e},addBehaviorKey:function(e){return document.body&&!this.options.excludeAddBehavior&&document.body.addBehavior&&e.push({key:"add_behavior",value:1}),e},openDatabaseKey:function(e){return!this.options.excludeOpenDatabase&&window.openDatabase&&e.push({key:"open_database",value:1}),e},cpuClassKey:function(e){return this.options.excludeCpuClass||e.push({key:"cpu_class",value:this.getNavigatorCpuClass()}),e},platformKey:function(e){return this.options.excludePlatform||e.push({key:"navigator_platform",value:this.getNavigatorPlatform()}),e},doNotTrackKey:function(e){return this.options.excludeDoNotTrack||e.push({key:"do_not_track",value:this.getDoNotTrack()}),e},canvasKey:function(e){return!this.options.excludeCanvas&&this.isCanvasSupported()&&e.push({key:"canvas",value:this.getCanvasFp()}),e},webglKey:function(e){return this.options.excludeWebGL?e:this.isWebGlSupported()?(e.push({key:"webgl",value:this.getWebglFp()}),e):e},adBlockKey:function(e){return this.options.excludeAdBlock||e.push({key:"adblock",value:this.getAdBlock()}),e},hasLiedLanguagesKey:function(e){return this.options.excludeHasLiedLanguages||e.push({key:"has_lied_languages",value:this.getHasLiedLanguages()}),e},hasLiedResolutionKey:function(e){return this.options.excludeHasLiedResolution||e.push({key:"has_lied_resolution",value:this.getHasLiedResolution()}),e},hasLiedOsKey:function(e){return this.options.excludeHasLiedOs||e.push({key:"has_lied_os",value:this.getHasLiedOs()}),e},hasLiedBrowserKey:function(e){return this.options.excludeHasLiedBrowser||e.push({key:"has_lied_browser",value:this.getHasLiedBrowser()}),e},fontsKey:function(e,t){return this.options.excludeJsFonts?this.flashFontsKey(e,t):this.jsFontsKey(e,t)},flashFontsKey:function(e,t){return this.options.excludeFlashFonts?t(e):this.hasSwfObjectLoaded()&&this.hasMinFlashInstalled()?"undefined"==typeof this.options.swfPath?t(e):void this.loadSwfAndDetectFonts(function(i){e.push({key:"swf_fonts",value:i.join(";")}),t(e)}):t(e)},jsFontsKey:function(e,t){var i=this;return setTimeout(function(){var a=["monospace","sans-serif","serif"],r=["Andale Mono","Arial","Arial Black","Arial Hebrew","Arial MT","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS","Bitstream Vera Sans Mono","Book Antiqua","Bookman Old Style","Calibri","Cambria","Cambria Math","Century","Century Gothic","Century Schoolbook","Comic Sans","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Helvetica","Helvetica Neue","Impact","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","LUCIDA GRANDE","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Monotype Corsiva","MS Gothic","MS Outlook","MS PGothic","MS Reference Sans Serif","MS Sans Serif","MS Serif","MYRIAD","MYRIAD PRO","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Segoe UI Light","Segoe UI Semibold","Segoe UI Symbol","Tahoma","Times","Times New Roman","Times New Roman PS","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3"],n=["Abadi MT Condensed Light","Academy Engraved LET","ADOBE CASLON PRO","Adobe Garamond","ADOBE GARAMOND PRO","Agency FB","Aharoni","Albertus Extra Bold","Albertus Medium","Algerian","Amazone BT","American Typewriter","American Typewriter Condensed","AmerType Md BT","Andalus","Angsana New","AngsanaUPC","Antique Olive","Aparajita","Apple Chancery","Apple Color Emoji","Apple SD Gothic Neo","Arabic Typesetting","ARCHER","ARNO PRO","Arrus BT","Aurora Cn BT","AvantGarde Bk BT","AvantGarde Md BT","AVENIR","Ayuthaya","Bandy","Bangla Sangam MN","Bank Gothic","BankGothic Md BT","Baskerville","Baskerville Old Face","Batang","BatangChe","Bauer Bodoni","Bauhaus 93","Bazooka","Bell MT","Bembo","Benguiat Bk BT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","BernhardFashion BT","BernhardMod BT","Big Caslon","BinnerD","Blackadder ITC","BlairMdITC TT","Bodoni 72","Bodoni 72 Oldstyle","Bodoni 72 Smallcaps","Bodoni MT","Bodoni MT Black","Bodoni MT Condensed","Bodoni MT Poster Compressed","Bookshelf Symbol 7","Boulder","Bradley Hand","Bradley Hand ITC","Bremen Bd BT","Britannic Bold","Broadway","Browallia New","BrowalliaUPC","Brush Script MT","Californian FB","Calisto MT","Calligrapher","Candara","CaslonOpnface BT","Castellar","Centaur","Cezanne","CG Omega","CG Times","Chalkboard","Chalkboard SE","Chalkduster","Charlesworth","Charter Bd BT","Charter BT","Chaucer","ChelthmITC Bk BT","Chiller","Clarendon","Clarendon Condensed","CloisterBlack BT","Cochin","Colonna MT","Constantia","Cooper Black","Copperplate","Copperplate Gothic","Copperplate Gothic Bold","Copperplate Gothic Light","CopperplGoth Bd BT","Corbel","Cordia New","CordiaUPC","Cornerstone","Coronet","Cuckoo","Curlz MT","DaunPenh","Dauphin","David","DB LCD Temp","DELICIOUS","Denmark","DFKai-SB","Didot","DilleniaUPC","DIN","DokChampa","Dotum","DotumChe","Ebrima","Edwardian Script ITC","Elephant","English 111 Vivace BT","Engravers MT","EngraversGothic BT","Eras Bold ITC","Eras Demi ITC","Eras Light ITC","Eras Medium ITC","EucrosiaUPC","Euphemia","Euphemia UCAS","EUROSTILE","Exotc350 Bd BT","FangSong","Felix Titling","Fixedsys","FONTIN","Footlight MT Light","Forte","FrankRuehl","Fransiscan","Freefrm721 Blk BT","FreesiaUPC","Freestyle Script","French Script MT","FrnkGothITC Bk BT","Fruitger","FRUTIGER","Futura","Futura Bk BT","Futura Lt BT","Futura Md BT","Futura ZBlk BT","FuturaBlack BT","Gabriola","Galliard BT","Gautami","Geeza Pro","Geometr231 BT","Geometr231 Hv BT","Geometr231 Lt BT","GeoSlab 703 Lt BT","GeoSlab 703 XBd BT","Gigi","Gill Sans","Gill Sans MT","Gill Sans MT Condensed","Gill Sans MT Ext Condensed Bold","Gill Sans Ultra Bold","Gill Sans Ultra Bold Condensed","Gisha","Gloucester MT Extra Condensed","GOTHAM","GOTHAM BOLD","Goudy Old Style","Goudy Stout","GoudyHandtooled BT","GoudyOLSt BT","Gujarati Sangam MN","Gulim","GulimChe","Gungsuh","GungsuhChe","Gurmukhi MN","Haettenschweiler","Harlow Solid Italic","Harrington","Heather","Heiti SC","Heiti TC","HELV","Herald","High Tower Text","Hiragino Kaku Gothic ProN","Hiragino Mincho ProN","Hoefler Text","Humanst 521 Cn BT","Humanst521 BT","Humanst521 Lt BT","Imprint MT Shadow","Incised901 Bd BT","Incised901 BT","Incised901 Lt BT","INCONSOLATA","Informal Roman","Informal011 BT","INTERSTATE","IrisUPC","Iskoola Pota","JasmineUPC","Jazz LET","Jenson","Jester","Jokerman","Juice ITC","Kabel Bk BT","Kabel Ult BT","Kailasa","KaiTi","Kalinga","Kannada Sangam MN","Kartika","Kaufmann Bd BT","Kaufmann BT","Khmer UI","KodchiangUPC","Kokila","Korinna BT","Kristen ITC","Krungthep","Kunstler Script","Lao UI","Latha","Leelawadee","Letter Gothic","Levenim MT","LilyUPC","Lithograph","Lithograph Light","Long Island","Lydian BT","Magneto","Maiandra GD","Malayalam Sangam MN","Malgun Gothic","Mangal","Marigold","Marion","Marker Felt","Market","Marlett","Matisse ITC","Matura MT Script Capitals","Meiryo","Meiryo UI","Microsoft Himalaya","Microsoft JhengHei","Microsoft New Tai Lue","Microsoft PhagsPa","Microsoft Tai Le","Microsoft Uighur","Microsoft YaHei","Microsoft Yi Baiti","MingLiU","MingLiU_HKSCS","MingLiU_HKSCS-ExtB","MingLiU-ExtB","Minion","Minion Pro","Miriam","Miriam Fixed","Mistral","Modern","Modern No. 20","Mona Lisa Solid ITC TT","Mongolian Baiti","MONO","MoolBoran","Mrs Eaves","MS LineDraw","MS Mincho","MS PMincho","MS Reference Specialty","MS UI Gothic","MT Extra","MUSEO","MV Boli","Nadeem","Narkisim","NEVIS","News Gothic","News GothicMT","NewsGoth BT","Niagara Engraved","Niagara Solid","Noteworthy","NSimSun","Nyala","OCR A Extended","Old Century","Old English Text MT","Onyx","Onyx BT","OPTIMA","Oriya Sangam MN","OSAKA","OzHandicraft BT","Palace Script MT","Papyrus","Parchment","Party LET","Pegasus","Perpetua","Perpetua Titling MT","PetitaBold","Pickwick","Plantagenet Cherokee","Playbill","PMingLiU","PMingLiU-ExtB","Poor Richard","Poster","PosterBodoni BT","PRINCETOWN LET","Pristina","PTBarnum BT","Pythagoras","Raavi","Rage Italic","Ravie","Ribbon131 Bd BT","Rockwell","Rockwell Condensed","Rockwell Extra Bold","Rod","Roman","Sakkal Majalla","Santa Fe LET","Savoye LET","Sceptre","Script","Script MT Bold","SCRIPTINA","Serifa","Serifa BT","Serifa Th BT","ShelleyVolante BT","Sherwood","Shonar Bangla","Showcard Gothic","Shruti","Signboard","SILKSCREEN","SimHei","Simplified Arabic","Simplified Arabic Fixed","SimSun","SimSun-ExtB","Sinhala Sangam MN","Sketch Rockwell","Skia","Small Fonts","Snap ITC","Snell Roundhand","Socket","Souvenir Lt BT","Staccato222 BT","Steamer","Stencil","Storybook","Styllo","Subway","Swis721 BlkEx BT","Swiss911 XCm BT","Sylfaen","Synchro LET","System","Tamil Sangam MN","Technical","Teletype","Telugu Sangam MN","Tempus Sans ITC","Terminal","Thonburi","Traditional Arabic","Trajan","TRAJAN PRO","Tristan","Tubular","Tunga","Tw Cen MT","Tw Cen MT Condensed","Tw Cen MT Condensed Extra Bold","TypoUpright BT","Unicorn","Univers","Univers CE 55 Medium","Univers Condensed","Utsaah","Vagabond","Vani","Vijaya","Viner Hand ITC","VisualUI","Vivaldi","Vladimir Script","Vrinda","Westminster","WHITNEY","Wide Latin","ZapfEllipt BT","ZapfHumnst BT","ZapfHumnst Dm BT","Zapfino","Zurich BlkEx BT","Zurich Ex BT","ZWAdobeF"];i.options.extendedJsFonts&&(r=r.concat(n)),r=r.concat(i.options.userDefinedFonts);var o="mmmmmmmmmmlli",s="72px",l=document.getElementsByTagName("body")[0],h=document.createElement("div"),u=document.createElement("div"),d={},c={},g=function(){var e=document.createElement("span");return e.style.position="absolute",e.style.left="-9999px",e.style.fontSize=s,e.style.lineHeight="normal",e.innerHTML=o,e},p=function(e,t){var i=g();return i.style.fontFamily="'"+e+"',"+t,i},f=function(){for(var e=[],t=0,i=a.length;tt.name?1:e.name=0?"Windows Phone":t.indexOf("win")>=0?"Windows":t.indexOf("android")>=0?"Android":t.indexOf("linux")>=0?"Linux":t.indexOf("iphone")>=0||t.indexOf("ipad")>=0?"iOS":t.indexOf("mac")>=0?"Mac":"Other";var r;if(r="ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0,r&&"Windows Phone"!==e&&"Android"!==e&&"iOS"!==e&&"Other"!==e)return!0;if("undefined"!=typeof i){if(i=i.toLowerCase(),i.indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e)return!0;if(i.indexOf("linux")>=0&&"Linux"!==e&&"Android"!==e)return!0;if(i.indexOf("mac")>=0&&"Mac"!==e&&"iOS"!==e)return!0;if(0===i.indexOf("win")&&0===i.indexOf("linux")&&i.indexOf("mac")>=0&&"other"!==e)return!0}return a.indexOf("win")>=0&&"Windows"!==e&&"Windows Phone"!==e||((a.indexOf("linux")>=0||a.indexOf("android")>=0||a.indexOf("pike")>=0)&&"Linux"!==e&&"Android"!==e||((a.indexOf("mac")>=0||a.indexOf("ipad")>=0||a.indexOf("ipod")>=0||a.indexOf("iphone")>=0)&&"Mac"!==e&&"iOS"!==e||(0===a.indexOf("win")&&0===a.indexOf("linux")&&a.indexOf("mac")>=0&&"other"!==e||"undefined"==typeof navigator.plugins&&"Windows"!==e&&"Windows Phone"!==e)))},getHasLiedBrowser:function(){var e,t=navigator.userAgent.toLowerCase(),i=navigator.productSub;if(e=t.indexOf("firefox")>=0?"Firefox":t.indexOf("opera")>=0||t.indexOf("opr")>=0?"Opera":t.indexOf("chrome")>=0?"Chrome":t.indexOf("safari")>=0?"Safari":t.indexOf("trident")>=0?"Internet Explorer":"Other",("Chrome"===e||"Safari"===e||"Opera"===e)&&"20030107"!==i)return!0;var a=eval.toString().length;if(37===a&&"Safari"!==e&&"Firefox"!==e&&"Other"!==e)return!0;if(39===a&&"Internet Explorer"!==e&&"Other"!==e)return!0;if(33===a&&"Chrome"!==e&&"Opera"!==e&&"Other"!==e)return!0;var r;try{throw"a"}catch(n){try{n.toSource(),r=!0}catch(o){r=!1}}return!(!r||"Firefox"===e||"Other"===e)},isCanvasSupported:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},isWebGlSupported:function(){if(!this.isCanvasSupported())return!1;var e,t=document.createElement("canvas");try{e=t.getContext&&(t.getContext("webgl")||t.getContext("experimental-webgl"))}catch(i){e=!1}return!!window.WebGLRenderingContext&&!!e},isIE:function(){return"Microsoft Internet Explorer"===navigator.appName||!("Netscape"!==navigator.appName||!/Trident/.test(navigator.userAgent))},hasSwfObjectLoaded:function(){return"undefined"!=typeof window.swfobject},hasMinFlashInstalled:function(){return swfobject.hasFlashPlayerVersion("9.0.0")},addFlashDivNode:function(){var e=document.createElement("div");e.setAttribute("id",this.options.swfContainerId),document.body.appendChild(e)},loadSwfAndDetectFonts:function(e){var t="___fp_swf_loaded";window[t]=function(t){e(t)};var i=this.options.swfContainerId;this.addFlashDivNode();var a={onReady:t},r={allowScriptAccess:"always",menu:"false"};swfobject.embedSWF(this.options.swfPath,i,"1","1","9.0.0",!1,a,r,{})},getWebglCanvas:function(){var e=document.createElement("canvas"),t=null;try{t=e.getContext("webgl")||e.getContext("experimental-webgl")}catch(i){}return t||(t=null),t},each:function(e,t,i){if(null!==e)if(this.nativeForEach&&e.forEach===this.nativeForEach)e.forEach(t,i);else if(e.length===+e.length){for(var a=0,r=e.length;a>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]+t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]+t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]+t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]+t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Multiply:function(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var i=[0,0,0,0];return i[3]+=e[3]*t[3],i[2]+=i[3]>>>16,i[3]&=65535,i[2]+=e[2]*t[3],i[1]+=i[2]>>>16,i[2]&=65535,i[2]+=e[3]*t[2],i[1]+=i[2]>>>16,i[2]&=65535,i[1]+=e[1]*t[3],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[2]*t[2],i[0]+=i[1]>>>16,i[1]&=65535,i[1]+=e[3]*t[1],i[0]+=i[1]>>>16,i[1]&=65535,i[0]+=e[0]*t[3]+e[1]*t[2]+e[2]*t[1]+e[3]*t[0],i[0]&=65535,[i[0]<<16|i[1],i[2]<<16|i[3]]},x64Rotl:function(e,t){return t%=64,32===t?[e[1],e[0]]:t<32?[e[0]<>>32-t,e[1]<>>32-t]:(t-=32,[e[1]<>>32-t,e[0]<>>32-t])},x64LeftShift:function(e,t){return t%=64,0===t?e:t<32?[e[0]<>>32-t,e[1]<>>1]),e=this.x64Multiply(e,[4283543511,3981806797]),e=this.x64Xor(e,[0,e[0]>>>1]),e=this.x64Multiply(e,[3301882366,444984403]),e=this.x64Xor(e,[0,e[0]>>>1])},x64hash128:function(e,t){e=e||"",t=t||0;for(var i=e.length%16,a=e.length-i,r=[0,t],n=[0,t],o=[0,0],s=[0,0],l=[2277735313,289559509],h=[1291169091,658871167],u=0;u>>0).toString(16)).slice(-8)+("00000000"+(r[1]>>>0).toString(16)).slice(-8)+("00000000"+(n[0]>>>0).toString(16)).slice(-8)+("00000000"+(n[1]>>>0).toString(16)).slice(-8)}},e.VERSION="1.4.4",e}); + +alert('this'); \ No newline at end of file diff --git a/clients/electron_app/lib/roll.js b/clients/electron_app/lib/roll.js new file mode 100644 index 0000000..803f66f --- /dev/null +++ b/clients/electron_app/lib/roll.js @@ -0,0 +1,30 @@ +'use strict'; +const RPM = 15; +const RPS = RPM / 60; //Rotations per second, from 15RPM +const D = 31.27; //mm, Diameter of core (daylight spool here) 32, or 31.5 +const THICKNESS = 0.11938; //mm, 16mm = 0.0047in thick +const PITCH = 7.6; + +class Roll { + constructor () { + //var D_END = 87.16; + this.TOTAL = 33 * 1000; + } + //R = √(36000 × 0.005/π + 32) = √(57.30 + 9) = 8.14 inches. + diameter (length = 0) { + const val = ((length * THICKNESS) / Math.PI) + Math.pow(D / 2, 2); + const r = Math.sqrt(val); + return 2 * r; + } + length (d = 0) { + const len = Math.PI * (Math.pow(d / 2, 2) - Math.pow(D / 2, 2)); + return len / THICKNESS; + } + //mm/s + speed (d = 0) { + const mm = d * Math.PI; + return mm * RPS; + } +} + +module.exports = Roll; \ No newline at end of file diff --git a/clients/electron_app/lib/talktomain.js b/clients/electron_app/lib/talktomain.js new file mode 100644 index 0000000..f97d9b5 --- /dev/null +++ b/clients/electron_app/lib/talktomain.js @@ -0,0 +1,21 @@ +'use strict'; +const {ipcRenderer} = require('electron'); + +class TTM { + constructor () { + this.listeners = []; + } + send (service = null, obj = {}) { + let json = JSON.stringify(obj); + return ipcRenderer.send(service, json); + } + on (service = null, cb = ()=>{}) { + let listener = (event, args, etc) => { + return cb(event, args, etc); + }; + this.listeners.push(service); + return ipcRenderer.on(service, listener); + } +} + +module.exports = new TTM(); \ No newline at end of file diff --git a/clients/electron_app/lib/talktorender.js b/clients/electron_app/lib/talktorender.js new file mode 100644 index 0000000..e275d8f --- /dev/null +++ b/clients/electron_app/lib/talktorender.js @@ -0,0 +1,21 @@ +'use strict'; +const {ipcMain} = require('electron'); + +class TTR { + constructor () { + this.listeners = []; + } + send (service = null, obj = {}) { + let json = JSON.stringify(obj); + return ipcMain.send(service, json); + } + on (service = null, cb = ()=>{}) { + let listener = (event, args, etc) => { + return cb(event, args, etc); + }; + this.listeners.push(service); + return ipcMain.on(service, listener); + } +} + +module.exports = new TTR(); \ No newline at end of file diff --git a/clients/electron_app/main.js b/clients/electron_app/main.js new file mode 100644 index 0000000..74e7e64 --- /dev/null +++ b/clients/electron_app/main.js @@ -0,0 +1,74 @@ +'use strict'; + +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; +const config = require('./lib/config.js'); +const ac = require('./lib/arduinoCom.js'); +const ttr = require('./lib/talktorender.js'); + +const path = require('path'); +const url = require('url'); + +let mainWindow; + +const Roll = require('./lib/roll.js'); + +/* app functions */ + +/*ipcMain.on('asynchronous-message', (event, arg) => { + console.log(arg); // prints "ping" + return event.sender.send('asynchronous-reply', 'pong'); +}); + +ipcMain.on('synchronous-message', (event, arg) => { + console.log(arg) ; // prints "ping" + return event.returnValue = 'pong'; +});*/ + +let createWindow = () => { + mainWindow = new BrowserWindow({ + width: 350, + height: 600 + }); + + if (config.data.position) { + let pos = config.get('position'); + mainWindow.setPosition(pos[0], pos[1]); + } + + mainWindow.loadURL(url.format({ + pathname: path.join(__dirname, 'index.html'), + protocol: 'file:', + slashes: true + })); + + mainWindow.webContents.openDevTools(); + + mainWindow.on('closed', () => { + mainWindow = null; + }); +}; + +let ipcBindings = () => { + ttr.on('config', (event, args, etc) => { + console.dir(event); + console.dir(args); + }); +}; + +app.on('ready', createWindow); +app.on('window-all-closed', () => { + config.set('position', mainWindow.getPosition()); + app.quit(); +}); + +app.on('activate', function () { + if (mainWindow === null) { + createWindow(); + ipcBindings(); + ac.send('c', () => {}); + } +}); + +//ac.close(); \ No newline at end of file diff --git a/clients/electron_app/package.json b/clients/electron_app/package.json new file mode 100644 index 0000000..4a3e4c1 --- /dev/null +++ b/clients/electron_app/package.json @@ -0,0 +1,30 @@ +{ + "name": "contact_printer", + "version": "1.0.0", + "description": "16mm contact printer control software", + "main": "main.js", + "scripts": { + "start": "gulp && electron .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "jshintConfig": { + "esversion": 6, + "strict": "global", + "node": true + }, + "author": "mmcwilliams", + "license": "MIT", + "dependencies": { + "electron": "^1.4.1", + "electron-rebuild": "^1.5.7", + "serialport": "^4.0.7" + }, + "devDependencies": { + "electron-rebuild": "^1.5.11", + "gulp": "^3.9.1", + "gulp-clean-css": "^2.3.2", + "gulp-concat": "^2.6.1", + "gulp-less": "^3.3.0", + "gulp-minify": "0.0.14" + } +} diff --git a/clients/node_client/.gitignore b/clients/node_client/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/clients/node_client/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/clients/node_client/.index.js.swp b/clients/node_client/.index.js.swp new file mode 100644 index 0000000..44a1c12 Binary files /dev/null and b/clients/node_client/.index.js.swp differ diff --git a/clients/node_client/index.js b/clients/node_client/index.js new file mode 100644 index 0000000..bc96412 --- /dev/null +++ b/clients/node_client/index.js @@ -0,0 +1,21 @@ +'use strict'; + +const cmd = require('commander'); +const Arduino = require('arduino'); + +const printer = new Arduino(); + +async function configure () { + //read command lines + +} + +async function run_printer () { + + await printer.connect() + await configure(); + await + +} + +run_printer().then(()=>{}).catch(()=>{}); diff --git a/clients/node_client/lib/arduino/index.js b/clients/node_client/lib/arduino/index.js new file mode 100644 index 0000000..81e7ea0 --- /dev/null +++ b/clients/node_client/lib/arduino/index.js @@ -0,0 +1,333 @@ +'use strict' + +const SerialPort = require('serialport') +const Readline = SerialPort.parsers.Readline +const exec = require('child_process').exec +const parser = new Readline('') +const newlineRe = new RegExp('\n', 'g') +const returnRe = new RegExp('\r', 'g') +let eventEmitter + +const mcopy = {} + +async function delay (ms) { + return new Promise(resolve => { + return setTimeout(resolve, ms) + }) +} + +async function send (device, cmd) { + return new Promise ((resolve, reject) => { + mcopy.arduino.queue[cmd] = (ms) => { + return resolve(ms) + } + return mcopy.arduino.serial[device].write(cmd, (err, results) => { + if (err) { + //console.error(err) + return reject(err) + } + // + }) + }) +} + +async function write (device, str) { + return new Promise ((resolve, reject) => { + mcopy.arduino.serial[device].write(str, function (err, results) { + if (err) { + return reject(err) + } + //console.log('sent: ' + str) + return resolve(results) + }) + }) +} + +async function open (device) { + return new Promise((resolve, reject) => { + return mcopy.arduino.serial[device].open(error => { + if (error) { + return reject(error) + } + return resolve(true) + }) + }) +} + +async function close (device) { + return new Promise((resolve, reject) => { + return mcopy.arduino.serial[device].close((err) => { + if (err) { + return reject(err) + } + return resolve(true) + }) + }) +} + +/****** + Arduino handlers +*******/ +mcopy.arduino = { + path : {}, + known: [ + '/dev/tty.usbmodem1a161', + '/dev/tty.usbserial-A800f8dk', + '/dev/tty.usbserial-A900cebm', + '/dev/tty.usbmodem1a131', + '/dev/tty.usbserial-a900f6de', + '/dev/tty.usbmodem1a141', + '/dev/ttyACM0', + 'COM3' + ], + alias : { + + }, + serial : { + connect : {}, + projector : {}, + camera : {}, + light : {} + }, + baud : 57600, + queue : {}, + timer : 0, + lock : false +} + +mcopy.arduino.enumerate = async function () { + return new Promise( (resolve, reject) => { + return SerialPort.list((err, ports) => { + let matches = [] + if (err) { + return reject(err) + } + ports.forEach(port => { + if (mcopy.arduino.known.indexOf(port.comName) !== -1) { + matches.push(port.comName) + } else if ((port.manufacturer + '').toLowerCase().indexOf('arduino') !== -1) { + matches.push(port.comName) + } + }) + if (matches.length === 0) { + return reject('No USB devices found'); + } else if (matches.length > 0) { + return resolve(matches) + } + }) + }) +} + +//commands which respond to a sent char +mcopy.arduino.send = async function (serial, cmd, res) { + const device = mcopy.arduino.alias[serial] + let results + if (mcopy.arduino.lock) { + return false + } + mcopy.arduino.lock = true + await delay(mcopy.cfg.arduino.serialDelay) + try { + results = await send(device, cmd) + } catch (e) { + return console.error(e) + } + mcopy.arduino.lock = false + mcopy.arduino.timer = new Date().getTime() + return await eventEmitter.emit('arduino_send', cmd) +} + +//send strings, after char triggers firmware to accept +mcopy.arduino.string = async function (serial, str) { + const device = mcopy.arduino.alias[serial] + let writeSuccess + await delay(mcopy.cfg.arduino.serialDelay) + if (typeof mcopy.arduino.serial[device].fake !== 'undefined' + && mcopy.arduino.serial[device].fake) { + return mcopy.arduino.serial[device].string(str) + } else { + try { + writeSuccess = await write(device, str) + } catch (e) { + return console.error(e) + } + return writeSuccess + } +} + +//respond with same char over serial when done +mcopy.arduino.end = async function (data) { + const end = new Date().getTime() + const ms = end - mcopy.arduino.timer + let complete + if (mcopy.arduino.queue[data] !== undefined) { + mcopy.arduino.lock = false; + //console.log('Command ' + data + ' took ' + ms + 'ms'); + complete = mcopy.arduino.queue[data](ms) //execute callback + eventEmitter.emit('arduino_end', data) + delete mcopy.arduino.queue[data] + } else { + //console.log('Received stray "' + data + '"'); //silent to user + } + return complete +}; +mcopy.arduino.alias = function (serial, device) { + console.log(`Making "${serial}" an alias of ${device}`) + mcopy.arduino.alias[serial] = device +} +mcopy.arduino.connect = async function (serial, device, confirm) { + return new Promise(async (resolve, reject) => { + let connectSuccess + mcopy.arduino.path[serial] = device; + mcopy.arduino.alias[serial] = device; + mcopy.arduino.serial[device] = new SerialPort(mcopy.arduino.path[serial], { + autoOpen : false, + baudRate: mcopy.cfg.arduino.baud, + parser: parser + }) + try { + connectSuccess = await open(device) + } catch (e) { + console.error('failed to open: ' + e) + return reject(e) + } + console.log(`Opened connection with ${mcopy.arduino.path[serial]} as ${serial}`); + if (!confirm) { + mcopy.arduino.serial[device].on('data', async (data) => { + let d = data.toString('utf8') + d = d.replace(newlineRe, '').replace(returnRe, '') + return await mcopy.arduino.end(d) + }) + } else { + mcopy.arduino.serial[device].on('data', async (data) => { + let d = data.toString('utf8') + d = d.replace(newlineRe, '').replace(returnRe, '') + return await mcopy.arduino.confirmEnd(d) + }) + } + return resolve(mcopy.arduino.path[serial]) + }) + +} + +mcopy.arduino.confirmExec = {}; +mcopy.arduino.confirmEnd = function (data) { + //console.dir(data) + if (data === mcopy.cfg.arduino.cmd.connect + || data === mcopy.cfg.arduino.cmd.proj_identifier + || data === mcopy.cfg.arduino.cmd.cam_identifier + || data === mcopy.cfg.arduino.cmd.light_identifier + || data === mcopy.cfg.arduino.cmd.proj_light_identifier + || data === mcopy.cfg.arduino.cmd.proj_cam_light_identifier + || data === mcopy.cfg.arduino.cmd.proj_cam_identifier ) { + mcopy.arduino.confirmExec(null, data); + mcopy.arduino.confirmExec = {}; + } +} + +mcopy.arduino.verify = async function () { + return new Promise(async (resolve, reject) => { + const device = mcopy.arduino.alias['connect'] + let writeSuccess + mcopy.arduino.confirmExec = function (err, data) { + if (data === mcopy.cfg.arduino.cmd.connect) { + return resolve(true) + } else { + return reject('Wrong data returned') + } + } + await delay(mcopy.cfg.arduino.serialDelay) + try { + writeSuccess = await send(device, mcopy.cfg.arduino.cmd.connect) + } catch (e) { + return reject(e) + } + return resolve(writeSuccess) + }) +} + +mcopy.arduino.distinguish = async function () { + return new Promise(async (resolve, reject) => { + const device = mcopy.arduino.alias['connect'] + let writeSuccess + let type + mcopy.arduino.confirmExec = function (err, data) { + if (data === mcopy.cfg.arduino.cmd.proj_identifier) { + type = 'projector' + } else if (data === mcopy.cfg.arduino.cmd.cam_identifier) { + type = 'camera' + } else if (data === mcopy.cfg.arduino.cmd.light_identifier) { + type = 'light' + } else if (data === mcopy.cfg.arduino.cmd.proj_light_identifier) { + type = 'projector,light' + } else if (data === mcopy.cfg.arduino.cmd.proj_cam_light_identifier) { + type = 'projector,camera,light' + } else if (data === mcopy.cfg.arduino.cmd.proj_cam_identifier) { + type = 'projector,camera' + } + return resolve(type) + } + await delay(mcopy.cfg.arduino.serialDelay) + try { + writeSuccess = await send(device, mcopy.cfg.arduino.cmd.mcopy_identifier) + } catch (e) { + console.error(e) + return reject(e) + } + }) +} + +mcopy.arduino.close = async function (callback) { + const device = mcopy.arduino.alias['connect'] + let closeSuccess + try { + closeSuccess = await close(device) + } catch (e) { + return console.error(e) + } + return closeSuccess +}; + +mcopy.arduino.fakeConnect = async function (serial) { + //console.log('Connecting to fake arduino...'); + const device = '/dev/fake' + mcopy.arduino.alias[serial] = device + mcopy.arduino.serial[device] = { + write : function (cmd, cb) { + const t = { + c : mcopy.cfg.arduino.cam.time + mcopy.cfg.arduino.cam.delay, + p : mcopy.cfg.arduino.proj.time + mcopy.cfg.arduino.proj.delay + } + let timeout = t[cmd] + let end + if (typeof timeout === 'undefined') timeout = 10 + mcopy.arduino.timer = +new Date() + setTimeout(() => { + mcopy.arduino.end(cmd) + return cb() + }, timeout) + + }, + string : async function (str) { + //do nothing + return true + }, + fake : true + }; + //console.log('Connected to fake arduino! Not real! Doesn\'t exist!'); + return true +} + +if (typeof module !== 'undefined' && module.parent) { + /*module.exports = function (cfg, ee) { + eventEmitter = ee + mcopy.cfg = cfg + return mcopy.arduino + }*/ +} + +class Arduino { + +} + +module.exports = Arduino; \ No newline at end of file diff --git a/clients/node_client/lib/arduino/package.json b/clients/node_client/lib/arduino/package.json new file mode 100644 index 0000000..f2bdefe --- /dev/null +++ b/clients/node_client/lib/arduino/package.json @@ -0,0 +1,11 @@ +{ + "name": "arduino", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "mmcwilliams", + "license": "MIT" +} diff --git a/clients/node_client/package-lock.json b/clients/node_client/package-lock.json new file mode 100644 index 0000000..680cfa1 --- /dev/null +++ b/clients/node_client/package-lock.json @@ -0,0 +1,1563 @@ +{ + "name": "contact_printer_node_client", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@serialport/parser-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-1.0.5.tgz", + "integrity": "sha512-GCz/v/KG2Wv7SdQ2nv8jYGBY6D4h5tibj9bs0+pnryCDAr8xmmvnesFW15FIu4rwOMgsKhCHyp7roD8bRGs63A==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "@serialport/parser-cctalk": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-1.0.5.tgz", + "integrity": "sha512-VdoG1rRXb5deHM1c9Akn9djoJuHn030v7owYHEqpJeS6Rs6wrC4Hrkw8NxvV9ZPlMqAJ+5uJCaAUzB1tbVd3rA==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "@serialport/parser-delimiter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-1.0.5.tgz", + "integrity": "sha512-srDzeNwGM/GjtqK/nFDRIDpcZ6XDgkakFMXBtNDSI+XP6fqO1ynEZok8ljKJxM2ay0CNG83C6/X2xIOHvWhFYQ==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "@serialport/parser-readline": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-1.0.5.tgz", + "integrity": "sha512-QkZoCQPHwdZOMQk7SHz3QSp7xqK4jdNql9M80oXqWt7kNhFvNXguWzf17FfQrPRIb0qiz+96+P6uAOIi02Yxbg==", + "requires": { + "@serialport/parser-delimiter": "^1.0.5", + "safe-buffer": "^5.1.1" + } + }, + "@serialport/parser-ready": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-1.0.5.tgz", + "integrity": "sha512-U/ZkxyY35Z7WrDc0O8TGcGPOdwv6fGVJcZq5vXVko2MRt8wiKVD192mmbfTRZXFAX+rARXtQa3ad3yJzXVhb1g==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "@serialport/parser-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-1.0.5.tgz", + "integrity": "sha512-sX3tRuwwwGV+CZbKEUAKZD/wtG8ZRcGxbiDIm8nyzsPCGv52ck3RlQ9Vp4K8fYjcrGGwm3BWizC4uSzaTLOk1A==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "ansi-bgblack": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bgblack/-/ansi-bgblack-0.1.1.tgz", + "integrity": "sha1-poulAHiHcBtqr74/oNrf36juPKI=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bgblue": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bgblue/-/ansi-bgblue-0.1.1.tgz", + "integrity": "sha1-Z73ATtybm1J4lp2hlt6j11yMNhM=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bgcyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bgcyan/-/ansi-bgcyan-0.1.1.tgz", + "integrity": "sha1-WEiUJWAL3p9VBwaN2Wnr/bUP52g=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bggreen": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bggreen/-/ansi-bggreen-0.1.1.tgz", + "integrity": "sha1-TjGRJIUplD9DIelr8THRwTgWr0k=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bgmagenta": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bgmagenta/-/ansi-bgmagenta-0.1.1.tgz", + "integrity": "sha1-myhDLAduqpmUGGcqPvvhk5HCx6E=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bgred": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bgred/-/ansi-bgred-0.1.1.tgz", + "integrity": "sha1-p2+Sg4OCukMpCmwXeEJPmE1vEEE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bgwhite": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bgwhite/-/ansi-bgwhite-0.1.1.tgz", + "integrity": "sha1-ZQRlE3elim7OzQMxmU5IAljhG6g=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bgyellow": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bgyellow/-/ansi-bgyellow-0.1.1.tgz", + "integrity": "sha1-w/4usIzUdmSAKeaHTRWgs49h1E8=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-black": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-black/-/ansi-black-0.1.1.tgz", + "integrity": "sha1-9hheiJNgslRaHsUMC/Bj/EMDJFM=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-blue": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-blue/-/ansi-blue-0.1.1.tgz", + "integrity": "sha1-FbgEmQ6S/JyoxUds6PaZd3wh7b8=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-bold": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-bold/-/ansi-bold-0.1.1.tgz", + "integrity": "sha1-PmOVCvWswq4uZw5vZ96xFdGl9QU=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-colors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.2.0.tgz", + "integrity": "sha1-csMd4qDZoszQysMMyYI+6y9kNLU=", + "requires": { + "ansi-bgblack": "^0.1.1", + "ansi-bgblue": "^0.1.1", + "ansi-bgcyan": "^0.1.1", + "ansi-bggreen": "^0.1.1", + "ansi-bgmagenta": "^0.1.1", + "ansi-bgred": "^0.1.1", + "ansi-bgwhite": "^0.1.1", + "ansi-bgyellow": "^0.1.1", + "ansi-black": "^0.1.1", + "ansi-blue": "^0.1.1", + "ansi-bold": "^0.1.1", + "ansi-cyan": "^0.1.1", + "ansi-dim": "^0.1.1", + "ansi-gray": "^0.1.1", + "ansi-green": "^0.1.1", + "ansi-grey": "^0.1.1", + "ansi-hidden": "^0.1.1", + "ansi-inverse": "^0.1.1", + "ansi-italic": "^0.1.1", + "ansi-magenta": "^0.1.1", + "ansi-red": "^0.1.1", + "ansi-reset": "^0.1.1", + "ansi-strikethrough": "^0.1.1", + "ansi-underline": "^0.1.1", + "ansi-white": "^0.1.1", + "ansi-yellow": "^0.1.1", + "lazy-cache": "^2.0.1" + } + }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-dim": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-dim/-/ansi-dim-0.1.1.tgz", + "integrity": "sha1-QN5MYDqoCG2Oeoa4/5mNXDbu/Ww=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-green": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-green/-/ansi-green-0.1.1.tgz", + "integrity": "sha1-il2al55FjVfEDjNYCzc5C44Q0Pc=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-grey": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-grey/-/ansi-grey-0.1.1.tgz", + "integrity": "sha1-WdmLasK6GfilF5jphT+6eDOaM8E=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-hidden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-hidden/-/ansi-hidden-0.1.1.tgz", + "integrity": "sha1-7WpMSY0rt8uyidvyqNHcyFZ/rg8=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-inverse": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-inverse/-/ansi-inverse-0.1.1.tgz", + "integrity": "sha1-tq9Fgm/oJr+1KKbHmIV5Q1XM0mk=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-italic": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-italic/-/ansi-italic-0.1.1.tgz", + "integrity": "sha1-EEdDRj9iXBQqA2c5z4XtpoiYbyM=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-magenta": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-magenta/-/ansi-magenta-0.1.1.tgz", + "integrity": "sha1-BjtboW+z8j4c/aKwfAqJ3hHkMK4=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-reset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-reset/-/ansi-reset-0.1.1.tgz", + "integrity": "sha1-5+cSksPH3c1NYu9KbHwFmAkRw7c=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-strikethrough": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-strikethrough/-/ansi-strikethrough-0.1.1.tgz", + "integrity": "sha1-2Eh3FAss/wfRyT685pkE9oiF5Wg=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-underline": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-underline/-/ansi-underline-0.1.1.tgz", + "integrity": "sha1-38kg9Ml7WXfqFi34/7mIMIqqcaQ=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-white": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-white/-/ansi-white-0.1.1.tgz", + "integrity": "sha1-nHe3wZPF7pkuYBHTbsTJIbRXiUQ=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + }, + "ansi-yellow": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-yellow/-/ansi-yellow-0.1.1.tgz", + "integrity": "sha1-y5NW8vRscy8OMZnmEClVp32oPB0=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "arduino": { + "version": "file:lib/arduino" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-swap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arr-swap/-/arr-swap-1.0.1.tgz", + "integrity": "sha1-FHWQ7WX8gVvAf+8Jl8Llgj1kNTQ=", + "requires": { + "is-number": "^3.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "bindings": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "choices-separator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/choices-separator/-/choices-separator-2.0.0.tgz", + "integrity": "sha1-kv0XYxgteQM/XFxR0Lo1LlVnxpY=", + "requires": { + "ansi-dim": "^0.1.1", + "debug": "^2.6.6", + "strip-color": "^0.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + }, + "clone-deep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-1.0.0.tgz", + "integrity": "sha512-hmJRX8x1QOJVV+GUjOBzi6iauhPqc9hIF6xitWRBbiPZOBb6vGo/mDRIK9P74RTKSQK7AE8B0DDWY/vpRrPmQw==", + "requires": { + "for-own": "^1.0.0", + "is-plain-object": "^2.0.4", + "kind-of": "^5.0.0", + "shallow-clone": "^1.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "commander": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", + "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "error-symbol": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz", + "integrity": "sha1-Ck2uN9YA0VopukU9jvkg8YRDM/Y=" + }, + "expand-template": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.1.tgz", + "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "requires": { + "for-in": "^1.0.1" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "info-symbol": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/info-symbol/-/info-symbol-0.1.0.tgz", + "integrity": "sha1-J4QdcoZ920JCzWEtecEGM4gcang=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-number": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-6.0.0.tgz", + "integrity": "sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg==" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "koalas": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/koalas/-/koalas-1.0.2.tgz", + "integrity": "sha1-MYQz8HQjXbePrlZhoCqMpT7ilc0=" + }, + "lazy-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", + "requires": { + "set-getter": "^0.1.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + }, + "log-ok": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/log-ok/-/log-ok-0.1.1.tgz", + "integrity": "sha1-vqPdNqzQuKckDXhza1uXxlREozQ=", + "requires": { + "ansi-green": "^0.1.1", + "success-symbol": "^0.1.0" + } + }, + "log-utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/log-utils/-/log-utils-0.2.1.tgz", + "integrity": "sha1-pMIXoN2aUFFdm5ICBgkas9TgMc8=", + "requires": { + "ansi-colors": "^0.2.0", + "error-symbol": "^0.1.0", + "info-symbol": "^0.1.0", + "log-ok": "^0.1.1", + "success-symbol": "^0.1.0", + "time-stamp": "^1.0.1", + "warning-symbol": "^0.1.0" + } + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", + "requires": { + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=" + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" + }, + "node-abi": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.3.tgz", + "integrity": "sha512-b656V5C0628gOOA2kwcpNA/bxdlqYF9FvxJ+qqVX0ctdXNVZpS8J6xEUYir3WAKc7U0BH/NRlSpNbGsy+azjeg==", + "requires": { + "semver": "^5.4.1" + } + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "pointer-symbol": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pointer-symbol/-/pointer-symbol-1.0.0.tgz", + "integrity": "sha1-YPkRAgTqepKbYmRKITFVQ8uz1Ec=" + }, + "prebuild-install": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-4.0.0.tgz", + "integrity": "sha512-7tayxeYboJX0RbVzdnKyGl2vhQRWr6qfClEXDhOkXjuaOKCw2q8aiuFhONRYVsG/czia7KhpykIlI2S2VaPunA==", + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^1.0.2", + "github-from-package": "0.0.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-abi": "^2.2.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "os-homedir": "^1.0.1", + "pump": "^2.0.1", + "rc": "^1.1.6", + "simple-get": "^2.7.0", + "tar-fs": "^1.13.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "promirepl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promirepl/-/promirepl-1.0.1.tgz", + "integrity": "sha1-KVGq66K/P+InT/Y6FtlMBMpghy4=" + }, + "prompt-actions": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/prompt-actions/-/prompt-actions-3.0.2.tgz", + "integrity": "sha512-dhz2Fl7vK+LPpmnQ/S/eSut4BnH4NZDLyddHKi5uTU/2PDn3grEMGkgsll16V5RpVUh/yxdiam0xsM0RD4xvtg==", + "requires": { + "debug": "^2.6.8" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "prompt-base": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/prompt-base/-/prompt-base-4.1.0.tgz", + "integrity": "sha512-svGzgLUKZoqomz9SGMkf1hBG8Wl3K7JGuRCXc/Pv7xw8239hhaTBXrmjt7EXA9P/QZzdyT8uNWt9F/iJTXq75g==", + "requires": { + "component-emitter": "^1.2.1", + "debug": "^3.0.1", + "koalas": "^1.0.2", + "log-utils": "^0.2.1", + "prompt-actions": "^3.0.2", + "prompt-question": "^5.0.1", + "readline-ui": "^2.2.3", + "readline-utils": "^2.2.3", + "static-extend": "^0.1.2" + } + }, + "prompt-checkbox": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/prompt-checkbox/-/prompt-checkbox-2.2.0.tgz", + "integrity": "sha512-T/QWgkdUmKjRSr0FQlV8O+LfgmBk8PwDbWhzllm7mwWNAjs3qOVuru5Y1gV4/14L73zCncqcuwGwvnDyVcVgvA==", + "requires": { + "ansi-cyan": "^0.1.1", + "debug": "^2.6.8", + "prompt-base": "^4.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "prompt-choices": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/prompt-choices/-/prompt-choices-4.1.0.tgz", + "integrity": "sha512-ZNYLv6rW9z9n0WdwCkEuS+w5nUAGzRgtRt6GQ5aFNFz6MIcU7nHFlHOwZtzy7RQBk80KzUGPSRQphvMiQzB8pg==", + "requires": { + "arr-flatten": "^1.1.0", + "arr-swap": "^1.0.1", + "choices-separator": "^2.0.0", + "clone-deep": "^4.0.0", + "collection-visit": "^1.0.0", + "define-property": "^2.0.2", + "is-number": "^6.0.0", + "kind-of": "^6.0.2", + "koalas": "^1.0.2", + "log-utils": "^0.2.1", + "pointer-symbol": "^1.0.0", + "radio-symbol": "^2.0.0", + "set-value": "^3.0.0", + "strip-color": "^0.1.0", + "terminal-paginator": "^2.0.2", + "toggle-array": "^1.0.1" + }, + "dependencies": { + "clone-deep": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.0.tgz", + "integrity": "sha512-aNJ5/7Bz2IYBb7nIj34TLGk78lBXpXUgV9qsLngtTvJ9+scsZNnlU0OX2S2N4ax/sUQt7sDBkXiGjGJEmNbXOQ==", + "requires": { + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "shallow-clone": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.0.tgz", + "integrity": "sha512-Drg+nOI+ofeuslBf0nulyWLZhK1BZprqNvPJaiB4VvES+9gC6GG+qOVAfuO12zVSgxq9SKevcme7S3uDT6Be8w==", + "requires": { + "kind-of": "^6.0.2" + } + } + } + }, + "prompt-list": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/prompt-list/-/prompt-list-3.2.0.tgz", + "integrity": "sha512-PDao47cmC9+m2zEUghH+WIIascd8SuyyWO+akuUubd0XxOQyUH96HMdIcL3YnNS8kJUHwddH1rHVgL9vZA1QsQ==", + "requires": { + "ansi-cyan": "^0.1.1", + "ansi-dim": "^0.1.1", + "prompt-radio": "^1.2.1" + } + }, + "prompt-question": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/prompt-question/-/prompt-question-5.0.2.tgz", + "integrity": "sha512-wreaLbbu8f5+7zXds199uiT11Ojp59Z4iBi6hONlSLtsKGTvL2UY8VglcxQ3t/X4qWIxsNCg6aT4O8keO65v6Q==", + "requires": { + "clone-deep": "^1.0.0", + "debug": "^3.0.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "kind-of": "^5.0.2", + "koalas": "^1.0.2", + "prompt-choices": "^4.0.5" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "prompt-radio": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prompt-radio/-/prompt-radio-1.2.1.tgz", + "integrity": "sha512-vH1iAkgbWyvZBC1BTajydiHmwJP4F1b684gq0fm2wOjPVW1zaDo01OXWr/Dske0XdoHhtZFNMOXNj/ZUSRBywg==", + "requires": { + "debug": "^2.6.8", + "prompt-checkbox": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "radio-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/radio-symbol/-/radio-symbol-2.0.0.tgz", + "integrity": "sha1-eqm/xQSFY21S3XbWqOYxspB5muE=", + "requires": { + "ansi-gray": "^0.1.1", + "ansi-green": "^0.1.1", + "is-windows": "^1.0.1" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readline-ui": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/readline-ui/-/readline-ui-2.2.3.tgz", + "integrity": "sha512-ix7jz0PxqQqcIuq3yQTHv1TOhlD2IHO74aNO+lSuXsRYm1d+pdyup1yF3zKyLK1wWZrVNGjkzw5tUegO2IDy+A==", + "requires": { + "component-emitter": "^1.2.1", + "debug": "^2.6.8", + "readline-utils": "^2.2.1", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "readline-utils": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/readline-utils/-/readline-utils-2.2.3.tgz", + "integrity": "sha1-b4R9a48ZFcORtYHDZ81HhzhiNRo=", + "requires": { + "arr-flatten": "^1.1.0", + "extend-shallow": "^2.0.1", + "is-buffer": "^1.1.5", + "is-number": "^3.0.0", + "is-windows": "^1.0.1", + "koalas": "^1.0.2", + "mute-stream": "0.0.7", + "strip-color": "^0.1.0", + "window-size": "^1.1.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "serialport": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-6.2.1.tgz", + "integrity": "sha512-Z5irknsC8wJd/r6wR+oG3OJZAhMMcLiF817RrHMlC+3yKmAh0E0WuF0Gh4UfGYYcsXPcgdDcYkmMpQ56gB9pww==", + "requires": { + "@serialport/parser-byte-length": "^1.0.5", + "@serialport/parser-cctalk": "^1.0.5", + "@serialport/parser-delimiter": "^1.0.5", + "@serialport/parser-readline": "^1.0.5", + "@serialport/parser-ready": "^1.0.5", + "@serialport/parser-regex": "^1.0.5", + "bindings": "1.3.0", + "commander": "^2.13.0", + "debug": "^3.1.0", + "nan": "^2.9.2", + "prebuild-install": "^4.0.0", + "promirepl": "^1.0.1", + "prompt-list": "^3.2.0", + "safe-buffer": "^5.1.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-getter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", + "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "requires": { + "to-object-path": "^0.3.0" + } + }, + "set-value": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-3.0.0.tgz", + "integrity": "sha512-tqkg9wJ2TOsxbzIMG5NMAmzjdbDTAD0in7XuUzmFpJE4Ipi2QFBfgC2Z1/gfxcAmWCPsuutiEJyDIMRsrjrMOQ==", + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "shallow-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", + "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", + "requires": { + "is-extendable": "^0.1.1", + "kind-of": "^5.0.0", + "mixin-object": "^2.0.1" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", + "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-color": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", + "integrity": "sha1-EG9l09PmotlAHKwOsM6LinArT3s=" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "success-symbol": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/success-symbol/-/success-symbol-0.1.0.tgz", + "integrity": "sha1-JAIuSG878c3KCUKDt2nEctO3KJc=" + }, + "tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "requires": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + }, + "dependencies": { + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", + "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.1.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.0", + "xtend": "^4.0.0" + } + }, + "terminal-paginator": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/terminal-paginator/-/terminal-paginator-2.0.2.tgz", + "integrity": "sha512-IZMT5ECF9p4s+sNCV8uvZSW9E1+9zy9Ji9xz2oee8Jfo7hUFpauyjxkhfRcIH6Lu3Wdepv5D1kVRc8Hx74/LfQ==", + "requires": { + "debug": "^2.6.6", + "extend-shallow": "^2.0.1", + "log-utils": "^0.2.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "toggle-array": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toggle-array/-/toggle-array-1.0.1.tgz", + "integrity": "sha1-y/WEB5K9UJfzMReugkyTKv/ofVg=", + "requires": { + "isobject": "^3.0.0" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "warning-symbol": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/warning-symbol/-/warning-symbol-0.1.0.tgz", + "integrity": "sha1-uzHdEbeg+dZ6su2V9Fe2WCW7rSE=" + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-1.1.0.tgz", + "integrity": "sha1-O0AtMkTzVWHbLJdhrZ0eUoawei0=", + "requires": { + "define-property": "^1.0.0", + "is-number": "^3.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/clients/node_client/package.json b/clients/node_client/package.json new file mode 100644 index 0000000..ab6d558 --- /dev/null +++ b/clients/node_client/package.json @@ -0,0 +1,18 @@ +{ + "name": "contact_printer_node_client", + "version": "0.0.1", + "description": "Node.js client for the contact_printer project", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "mmcwilliams", + "license": "MIT", + "dependencies": { + "arduino": "file:lib/arduino", + "commander": "^2.16.0", + "lodash": "^4.17.10", + "serialport": "^6.2.1", + "uuid": "^3.3.2" + } +} diff --git a/dxf/InvoluteGear_1.dxf b/dxf/InvoluteGear_1.dxf new file mode 100644 index 0000000..6ef27ce --- /dev/null +++ b/dxf/InvoluteGear_1.dxf @@ -0,0 +1,4600 @@ +999 +DXF generated by OpenJsCad + 0 +SECTION + 2 +HEADER + 0 +ENDSEC + 0 +SECTION + 2 +TABLES + 0 +TABLE + 2 +LTYPE + 70 +1 + 0 +LTYPE + 2 +CONTINUOUS + 3 +Solid Line + 72 +65 + 73 +0 + 40 +0.0 + 0 +ENDTAB + 0 +TABLE + 2 +LAYER + 70 +1 + 0 +LAYER + 2 +OpenJsCad + 62 +7 + 6 +continuous + 0 +ENDTAB + 0 +TABLE + 2 +STYLE + 70 +0 + 0 +ENDTAB + 0 +TABLE + 2 +VIEW + 70 +0 + 0 +ENDTAB + 0 +ENDSEC + 0 +SECTION + 2 +BLOCKS + 0 +ENDSEC + 0 +SECTION + 2 +ENTITIES + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +457 + 70 +1 + 10 +31.667349733732777 + 20 +-9.477933527815228 + 30 +0.0 + 10 +31.976228942117956 + 20 +-8.568004722033198 + 30 +0.0 + 10 +32.16369610384658 + 20 +-7.625543656398133 + 30 +0.0 + 10 +31.486476614196164 + 20 +-7.028878229962151 + 30 +0.0 + 10 +30.571310721415557 + 20 +-6.354610294890315 + 30 +0.0 + 10 +29.78895868864631 + 20 +-5.877403092389345 + 30 +0.0 + 10 +29.165373962809714 + 20 +-5.568100867879595 + 30 +0.0 + 10 +28.722367945749493 + 20 +-5.394651723475533 + 30 +0.0 + 10 +28.216956911498816 + 20 +-5.246076355783762 + 30 +0.0 + 10 +27.768675556526627 + 20 +-5.021254698231774 + 30 +0.0 + 10 +27.573446025612164 + 20 +-4.778493887731326 + 30 +0.0 + 10 +27.870668860977286 + 20 +-2.5208623136106394 + 30 +0.0 + 10 +28.12207722810392 + 20 +-2.336902497904211 + 30 +0.0 + 10 +28.61327189304137 + 20 +-2.2357652047966665 + 30 +0.0 + 10 +29.13991559870711 + 20 +-2.223062421262169 + 30 +0.0 + 10 +29.612718493715757 + 20 +-2.170181807444792 + 30 +0.0 + 10 +30.295108391676425 + 20 +-2.0328144039437053 + 30 +0.0 + 10 +31.174312737845245 + 20 +-1.7743552486116803 + 30 +0.0 + 10 +32.23280849212474 + 20 +-1.359924798765092 + 30 +0.0 + 10 +33.041380663155046 + 20 +-0.958867555355508 + 30 +0.0 + 10 +33.10422816311423 + 20 +2.5069251350982487e-16 + 30 +0.0 + 10 +33.041380663155046 + 20 +0.958867555355509 + 30 +0.0 + 10 +32.23280849211956 + 20 +1.359924798767666 + 30 +0.0 + 10 +31.174312737845337 + 20 +1.774355248612281 + 30 +0.0 + 10 +30.295108391676422 + 20 +2.0328144039437728 + 30 +0.0 + 10 +29.612718493715764 + 20 +2.1701818074448544 + 30 +0.0 + 10 +29.139915598707333 + 20 +2.2230624212622825 + 30 +0.0 + 10 +28.613271893041393 + 20 +2.2357652047971213 + 30 +0.0 + 10 +28.12207722810393 + 20 +2.3369024979045383 + 30 +0.0 + 10 +27.870668860977307 + 20 +2.5208623136106922 + 30 +0.0 + 10 +27.573446025612128 + 20 +4.778493887731371 + 30 +0.0 + 10 +27.76867555652653 + 20 +5.021254698232086 + 30 +0.0 + 10 +28.216956911498677 + 20 +5.246076355784195 + 30 +0.0 + 10 +28.722367945749248 + 20 +5.394651723475585 + 30 +0.0 + 10 +29.165373962809692 + 20 +5.568100867879654 + 30 +0.0 + 10 +29.7889586886463 + 20 +5.877403092389412 + 30 +0.0 + 10 +30.57131072141532 + 20 +6.354610294890874 + 30 +0.0 + 10 +31.486476614200505 + 20 +7.028878229965979 + 30 +0.0 + 10 +32.16369610384658 + 20 +7.6255436563981345 + 30 +0.0 + 10 +31.976228942117956 + 20 +8.5680047220332 + 30 +0.0 + 10 +31.667349733732785 + 20 +9.47793352781523 + 30 +0.0 + 10 +30.782527738539596 + 20 +9.656051199843457 + 30 +0.0 + 10 +29.652836859178606 + 20 +9.782401414182642 + 30 +0.0 + 10 +28.736696522847556 + 20 +9.804498958032761 + 30 +0.0 + 10 +28.042005196606233 + 20 +9.760570178986946 + 30 +0.0 + 10 +27.57162615960069 + 20 +9.689278535775427 + 30 +0.0 + 10 +27.05963968074075 + 20 +9.565243061447777 + 30 +0.0 + 10 +26.55900581051593 + 20 +9.535803650722631 + 30 +0.0 + 10 +26.268551671924865 + 20 +9.648425914202086 + 30 +0.0 + 10 +25.39713841087556 + 20 +11.752203627459012 + 30 +0.0 + 10 +25.52288453567797 + 20 +12.0372216846996 + 30 +0.0 + 10 +25.89770294716342 + 20 +12.370406482269454 + 30 +0.0 + 10 +26.347438383245873 + 20 +12.64472926834197 + 30 +0.0 + 10 +26.7304573943975 + 20 +12.926926670779858 + 30 +0.0 + 10 +27.252740679566767 + 20 +13.38708528084404 + 30 +0.0 + 10 +27.884924400800642 + 20 +14.050519648286652 + 30 +0.0 + 10 +28.594393388881358 + 20 +14.938674823095356 + 30 +0.0 + 10 +29.09410880808195 + 20 +15.690286669774968 + 30 +0.0 + 10 +28.669102561933187 + 20 +16.55211408155711 + 30 +0.0 + 10 +28.135241252726438 + 20 +17.351093993380072 + 30 +0.0 + 10 +27.23446859011049 + 20 +17.294133669029016 + 30 +0.0 + 10 +26.110569152188738 + 20 +17.123793089559154 + 30 +0.0 + 10 +25.219926275623024 + 20 +16.908023110832435 + 30 +0.0 + 10 +24.56027558695268 + 20 +16.68579182293595 + 30 +0.0 + 10 +24.12437596198384 + 20 +16.495186330365343 + 30 +0.0 + 10 +23.661937742366547 + 20 +16.24286541077232 + 30 +0.0 + 10 +23.185982037773606 + 20 +16.084855543404604 + 30 +0.0 + 10 +22.876276097264913 + 20 +16.118465233518325 + 30 +0.0 + 10 +21.490057784193485 + 20 +17.92502011141009 + 30 +0.0 + 10 +21.53775111228392 + 20 +18.232871905804213 + 30 +0.0 + 10 +21.81356332495665 + 20 +18.65171385005134 + 30 +0.0 + 10 +22.17697443612492 + 20 +19.033089409973982 + 30 +0.0 + 10 +22.47390432872659 + 20 +19.404803783822803 + 30 +0.0 + 10 +22.85929343045817 + 20 +19.984459730613594 + 30 +0.0 + 10 +23.298226564287802 + 20 +20.788909307233272 + 30 +0.0 + 10 +23.75364950857929 + 20 +21.83042541435819 + 30 +0.0 + 10 +24.04180607733465 + 20 +22.685762576031347 + 30 +0.0 + 10 +23.40822422008476 + 20 +23.408224220084755 + 30 +0.0 + 10 +22.685762576031355 + 20 +24.041806077334645 + 30 +0.0 + 10 +21.83042541435271 + 20 +23.75364950857744 + 30 +0.0 + 10 +20.78890930723292 + 20 +23.298226564288285 + 30 +0.0 + 10 +19.98445973061355 + 20 +22.859293430458205 + 30 +0.0 + 10 +19.40480378382277 + 20 +22.473904328726633 + 30 +0.0 + 10 +19.033089409974068 + 20 +22.176974436125153 + 30 +0.0 + 10 +18.651713850051042 + 20 +21.813563324956984 + 30 +0.0 + 10 +18.232871905804 + 20 +21.537751112284152 + 30 +0.0 + 10 +17.92502011141008 + 20 +21.49005778419353 + 30 +0.0 + 10 +16.118465233518275 + 20 +22.876276097264913 + 30 +0.0 + 10 +16.084855543404323 + 20 +23.185982037773755 + 30 +0.0 + 10 +16.242865410771923 + 20 +23.661937742366746 + 30 +0.0 + 10 +16.49518633036514 + 20 +24.1243759619837 + 30 +0.0 + 10 +16.6857918229359 + 20 +24.560275586952706 + 30 +0.0 + 10 +16.90802311083239 + 20 +25.219926275623056 + 30 +0.0 + 10 +17.123793089558596 + 20 +26.110569152188955 + 30 +0.0 + 10 +17.294133669029385 + 20 +27.23446859011626 + 30 +0.0 + 10 +17.35109399338008 + 20 +28.135241252726434 + 30 +0.0 + 10 +16.552114081557114 + 20 +28.669102561933187 + 30 +0.0 + 10 +15.690286669774968 + 20 +29.09410880808195 + 30 +0.0 + 10 +14.938674823090535 + 20 +28.594393388878157 + 30 +0.0 + 10 +14.050519648286176 + 20 +27.884924400801015 + 30 +0.0 + 10 +13.38708528084398 + 20 +27.2527406795668 + 30 +0.0 + 10 +12.926926670779809 + 20 +26.730457394397536 + 30 +0.0 + 10 +12.644729268341985 + 20 +26.34743838324612 + 30 +0.0 + 10 +12.37040648226907 + 20 +25.897702947163665 + 30 +0.0 + 10 +12.037221684699324 + 20 +25.52288453567814 + 30 +0.0 + 10 +11.752203627458979 + 20 +25.397138410875602 + 30 +0.0 + 10 +9.648425914202031 + 20 +26.268551671924854 + 30 +0.0 + 10 +9.535803650722313 + 20 +26.559005810516005 + 30 +0.0 + 10 +9.565243061447331 + 20 +27.059639680740844 + 30 +0.0 + 10 +9.68927853577526 + 20 +27.571626159600505 + 30 +0.0 + 10 +9.760570178986884 + 20 +28.042005196606244 + 30 +0.0 + 10 +9.804498958032699 + 20 +28.736696522847577 + 30 +0.0 + 10 +9.782401414182038 + 20 +29.652836859178674 + 30 +0.0 + 10 +9.656051199842313 + 20 +30.78252773854527 + 30 +0.0 + 10 +9.47793352781523 + 20 +31.667349733732777 + 30 +0.0 + 10 +8.5680047220332 + 20 +31.976228942117956 + 30 +0.0 + 10 +7.6255436563981345 + 20 +32.16369610384658 + 30 +0.0 + 10 +7.028878229962153 + 20 +31.486476614196164 + 30 +0.0 + 10 +6.354610294890317 + 20 +30.571310721415557 + 30 +0.0 + 10 +5.877403092389347 + 20 +29.78895868864631 + 30 +0.0 + 10 +5.568100867879597 + 20 +29.165373962809714 + 30 +0.0 + 10 +5.394651723475535 + 20 +28.722367945749493 + 30 +0.0 + 10 +5.246076355783764 + 20 +28.216956911498816 + 30 +0.0 + 10 +5.021254698231775 + 20 +27.768675556526627 + 30 +0.0 + 10 +4.778493887731328 + 20 +27.573446025612164 + 30 +0.0 + 10 +2.520862313610641 + 20 +27.870668860977286 + 30 +0.0 + 10 +2.336902497904213 + 20 +28.12207722810392 + 30 +0.0 + 10 +2.2357652047966683 + 20 +28.61327189304137 + 30 +0.0 + 10 +2.2230624212621706 + 20 +29.13991559870711 + 30 +0.0 + 10 +2.1701818074447936 + 20 +29.612718493715757 + 30 +0.0 + 10 +2.032814403943707 + 20 +30.295108391676425 + 30 +0.0 + 10 +1.7743552486116823 + 20 +31.174312737845245 + 30 +0.0 + 10 +1.359924798765094 + 20 +32.23280849212474 + 30 +0.0 + 10 +0.95886755535551 + 20 +33.041380663155046 + 30 +0.0 + 10 +-3.803406192310326e-15 + 20 +33.10422816311423 + 30 +0.0 + 10 +-0.9588675553555126 + 20 +33.041380663155046 + 30 +0.0 + 10 +-1.3599247987676695 + 20 +32.23280849211956 + 30 +0.0 + 10 +-1.7743552486122847 + 20 +31.174312737845337 + 30 +0.0 + 10 +-2.0328144039437763 + 20 +30.295108391676425 + 30 +0.0 + 10 +-2.170181807444858 + 20 +29.612718493715764 + 30 +0.0 + 10 +-2.223062421262286 + 20 +29.139915598707333 + 30 +0.0 + 10 +-2.235765204797125 + 20 +28.613271893041397 + 30 +0.0 + 10 +-2.336902497904541 + 20 +28.12207722810393 + 30 +0.0 + 10 +-2.520862313610696 + 20 +27.87066886097731 + 30 +0.0 + 10 +-4.778493887731374 + 20 +27.573446025612128 + 30 +0.0 + 10 +-5.02125469823209 + 20 +27.76867555652653 + 30 +0.0 + 10 +-5.246076355784199 + 20 +28.216956911498677 + 30 +0.0 + 10 +-5.394651723475588 + 20 +28.722367945749248 + 30 +0.0 + 10 +-5.568100867879657 + 20 +29.165373962809692 + 30 +0.0 + 10 +-5.877403092389415 + 20 +29.7889586886463 + 30 +0.0 + 10 +-6.354610294890877 + 20 +30.57131072141532 + 30 +0.0 + 10 +-7.028878229965983 + 20 +31.486476614200505 + 30 +0.0 + 10 +-7.625543656398138 + 20 +32.16369610384658 + 30 +0.0 + 10 +-8.568004722033193 + 20 +31.976228942117956 + 30 +0.0 + 10 +-9.477933527815226 + 20 +31.66734973373278 + 30 +0.0 + 10 +-9.656051199843452 + 20 +30.782527738539592 + 30 +0.0 + 10 +-9.782401414182635 + 20 +29.652836859178606 + 30 +0.0 + 10 +-9.804498958032758 + 20 +28.736696522847556 + 30 +0.0 + 10 +-9.76057017898694 + 20 +28.042005196606233 + 30 +0.0 + 10 +-9.689278535775424 + 20 +27.57162615960069 + 30 +0.0 + 10 +-9.565243061447772 + 20 +27.05963968074075 + 30 +0.0 + 10 +-9.535803650722627 + 20 +26.55900581051593 + 30 +0.0 + 10 +-9.648425914202083 + 20 +26.26855167192486 + 30 +0.0 + 10 +-11.752203627459009 + 20 +25.39713841087556 + 30 +0.0 + 10 +-12.037221684699595 + 20 +25.52288453567797 + 30 +0.0 + 10 +-12.370406482269447 + 20 +25.897702947163417 + 30 +0.0 + 10 +-12.644729268341965 + 20 +26.347438383245873 + 30 +0.0 + 10 +-12.926926670779853 + 20 +26.7304573943975 + 30 +0.0 + 10 +-13.387085280844035 + 20 +27.252740679566767 + 30 +0.0 + 10 +-14.050519648286647 + 20 +27.884924400800642 + 30 +0.0 + 10 +-14.938674823095353 + 20 +28.594393388881358 + 30 +0.0 + 10 +-15.690286669774965 + 20 +29.09410880808195 + 30 +0.0 + 10 +-16.55211408155711 + 20 +28.669102561933187 + 30 +0.0 + 10 +-17.351093993380072 + 20 +28.135241252726438 + 30 +0.0 + 10 +-17.294133669029016 + 20 +27.23446859011049 + 30 +0.0 + 10 +-17.123793089559154 + 20 +26.110569152188738 + 30 +0.0 + 10 +-16.908023110832435 + 20 +25.219926275623024 + 30 +0.0 + 10 +-16.68579182293595 + 20 +24.56027558695268 + 30 +0.0 + 10 +-16.495186330365343 + 20 +24.12437596198384 + 30 +0.0 + 10 +-16.24286541077232 + 20 +23.661937742366547 + 30 +0.0 + 10 +-16.084855543404604 + 20 +23.185982037773606 + 30 +0.0 + 10 +-16.118465233518325 + 20 +22.876276097264913 + 30 +0.0 + 10 +-17.92502011141009 + 20 +21.490057784193485 + 30 +0.0 + 10 +-18.232871905804213 + 20 +21.53775111228392 + 30 +0.0 + 10 +-18.65171385005134 + 20 +21.81356332495665 + 30 +0.0 + 10 +-19.033089409973982 + 20 +22.17697443612492 + 30 +0.0 + 10 +-19.404803783822803 + 20 +22.47390432872659 + 30 +0.0 + 10 +-19.984459730613594 + 20 +22.85929343045817 + 30 +0.0 + 10 +-20.788909307233272 + 20 +23.298226564287802 + 30 +0.0 + 10 +-21.83042541435819 + 20 +23.75364950857929 + 30 +0.0 + 10 +-22.685762576031347 + 20 +24.04180607733465 + 30 +0.0 + 10 +-23.40822422008476 + 20 +23.408224220084755 + 30 +0.0 + 10 +-24.04180607733465 + 20 +22.685762576031347 + 30 +0.0 + 10 +-23.753649508577443 + 20 +21.830425414352703 + 30 +0.0 + 10 +-23.298226564288292 + 20 +20.788909307232913 + 30 +0.0 + 10 +-22.859293430458212 + 20 +19.984459730613548 + 30 +0.0 + 10 +-22.47390432872664 + 20 +19.404803783822764 + 30 +0.0 + 10 +-22.176974436125157 + 20 +19.033089409974064 + 30 +0.0 + 10 +-21.813563324956988 + 20 +18.65171385005104 + 30 +0.0 + 10 +-21.53775111228416 + 20 +18.232871905803997 + 30 +0.0 + 10 +-21.490057784193535 + 20 +17.925020111410078 + 30 +0.0 + 10 +-22.876276097264917 + 20 +16.118465233518272 + 30 +0.0 + 10 +-23.18598203777376 + 20 +16.084855543404316 + 30 +0.0 + 10 +-23.66193774236675 + 20 +16.242865410771916 + 30 +0.0 + 10 +-24.124375961983702 + 20 +16.495186330365136 + 30 +0.0 + 10 +-24.56027558695271 + 20 +16.685791822935897 + 30 +0.0 + 10 +-25.219926275623063 + 20 +16.90802311083238 + 30 +0.0 + 10 +-26.11056915218896 + 20 +17.123793089558593 + 30 +0.0 + 10 +-27.234468590116265 + 20 +17.294133669029378 + 30 +0.0 + 10 +-28.135241252726438 + 20 +17.351093993380072 + 30 +0.0 + 10 +-28.66910256193318 + 20 +16.55211408155712 + 30 +0.0 + 10 +-29.09410880808194 + 20 +15.690286669774975 + 30 +0.0 + 10 +-28.59439338887815 + 20 +14.938674823090544 + 30 +0.0 + 10 +-27.88492440080101 + 20 +14.050519648286185 + 30 +0.0 + 10 +-27.25274067956679 + 20 +13.387085280843989 + 30 +0.0 + 10 +-26.730457394397533 + 20 +12.926926670779816 + 30 +0.0 + 10 +-26.34743838324612 + 20 +12.644729268341992 + 30 +0.0 + 10 +-25.89770294716366 + 20 +12.370406482269077 + 30 +0.0 + 10 +-25.522884535678138 + 20 +12.03722168469933 + 30 +0.0 + 10 +-25.397138410875595 + 20 +11.752203627458986 + 30 +0.0 + 10 +-26.26855167192485 + 20 +9.648425914202038 + 30 +0.0 + 10 +-26.559005810516002 + 20 +9.53580365072232 + 30 +0.0 + 10 +-27.05963968074084 + 20 +9.565243061447338 + 30 +0.0 + 10 +-27.5716261596005 + 20 +9.689278535775268 + 30 +0.0 + 10 +-28.04200519660624 + 20 +9.76057017898689 + 30 +0.0 + 10 +-28.736696522847573 + 20 +9.804498958032708 + 30 +0.0 + 10 +-29.65283685917867 + 20 +9.782401414182047 + 30 +0.0 + 10 +-30.782527738545266 + 20 +9.656051199842322 + 30 +0.0 + 10 +-31.667349733732774 + 20 +9.477933527815239 + 30 +0.0 + 10 +-31.976228942117956 + 20 +8.568004722033201 + 30 +0.0 + 10 +-32.16369610384658 + 20 +7.625543656398136 + 30 +0.0 + 10 +-31.486476614196164 + 20 +7.028878229962155 + 30 +0.0 + 10 +-30.571310721415557 + 20 +6.3546102948903185 + 30 +0.0 + 10 +-29.78895868864631 + 20 +5.877403092389349 + 30 +0.0 + 10 +-29.165373962809714 + 20 +5.568100867879599 + 30 +0.0 + 10 +-28.722367945749493 + 20 +5.394651723475537 + 30 +0.0 + 10 +-28.216956911498816 + 20 +5.2460763557837655 + 30 +0.0 + 10 +-27.768675556526627 + 20 +5.021254698231777 + 30 +0.0 + 10 +-27.573446025612164 + 20 +4.778493887731329 + 30 +0.0 + 10 +-27.870668860977286 + 20 +2.520862313610643 + 30 +0.0 + 10 +-28.12207722810392 + 20 +2.3369024979042146 + 30 +0.0 + 10 +-28.61327189304137 + 20 +2.23576520479667 + 30 +0.0 + 10 +-29.13991559870711 + 20 +2.2230624212621724 + 30 +0.0 + 10 +-29.612718493715757 + 20 +2.1701818074447954 + 30 +0.0 + 10 +-30.295108391676425 + 20 +2.032814403943709 + 30 +0.0 + 10 +-31.174312737845245 + 20 +1.774355248611684 + 30 +0.0 + 10 +-32.23280849212474 + 20 +1.359924798765096 + 30 +0.0 + 10 +-33.041380663155046 + 20 +0.958867555355512 + 30 +0.0 + 10 +-33.10422816311423 + 20 +-2.0270493529100753e-15 + 30 +0.0 + 10 +-33.041380663155046 + 20 +-0.9588675553555108 + 30 +0.0 + 10 +-32.23280849211956 + 20 +-1.3599247987676677 + 30 +0.0 + 10 +-31.174312737845337 + 20 +-1.7743552486122829 + 30 +0.0 + 10 +-30.295108391676425 + 20 +-2.0328144039437746 + 30 +0.0 + 10 +-29.612718493715764 + 20 +-2.1701818074448562 + 30 +0.0 + 10 +-29.139915598707333 + 20 +-2.2230624212622843 + 30 +0.0 + 10 +-28.613271893041397 + 20 +-2.235765204797123 + 30 +0.0 + 10 +-28.12207722810393 + 20 +-2.33690249790454 + 30 +0.0 + 10 +-27.87066886097731 + 20 +-2.520862313610694 + 30 +0.0 + 10 +-27.573446025612128 + 20 +-4.778493887731373 + 30 +0.0 + 10 +-27.76867555652653 + 20 +-5.021254698232088 + 30 +0.0 + 10 +-28.216956911498677 + 20 +-5.246076355784197 + 30 +0.0 + 10 +-28.722367945749248 + 20 +-5.394651723475587 + 30 +0.0 + 10 +-29.165373962809692 + 20 +-5.5681008678796555 + 30 +0.0 + 10 +-29.7889586886463 + 20 +-5.877403092389414 + 30 +0.0 + 10 +-30.57131072141532 + 20 +-6.354610294890875 + 30 +0.0 + 10 +-31.486476614200505 + 20 +-7.028878229965981 + 30 +0.0 + 10 +-32.16369610384658 + 20 +-7.625543656398136 + 30 +0.0 + 10 +-31.976228942117956 + 20 +-8.568004722033205 + 30 +0.0 + 10 +-31.66734973373278 + 20 +-9.477933527815237 + 30 +0.0 + 10 +-30.782527738539592 + 20 +-9.656051199843462 + 30 +0.0 + 10 +-29.652836859178606 + 20 +-9.782401414182646 + 30 +0.0 + 10 +-28.736696522847556 + 20 +-9.804498958032768 + 30 +0.0 + 10 +-28.042005196606233 + 20 +-9.760570178986951 + 30 +0.0 + 10 +-27.571626159600687 + 20 +-9.689278535775435 + 30 +0.0 + 10 +-27.059639680740748 + 20 +-9.565243061447783 + 30 +0.0 + 10 +-26.55900581051593 + 20 +-9.535803650722636 + 30 +0.0 + 10 +-26.26855167192486 + 20 +-9.648425914202091 + 30 +0.0 + 10 +-25.397138410875556 + 20 +-11.75220362745902 + 30 +0.0 + 10 +-25.522884535677967 + 20 +-12.037221684699606 + 30 +0.0 + 10 +-25.897702947163417 + 20 +-12.370406482269459 + 30 +0.0 + 10 +-26.34743838324587 + 20 +-12.644729268341976 + 30 +0.0 + 10 +-26.730457394397497 + 20 +-12.926926670779864 + 30 +0.0 + 10 +-27.252740679566767 + 20 +-13.387085280844046 + 30 +0.0 + 10 +-27.88492440080064 + 20 +-14.050519648286658 + 30 +0.0 + 10 +-28.594393388881354 + 20 +-14.938674823095363 + 30 +0.0 + 10 +-29.094108808081945 + 20 +-15.690286669774975 + 30 +0.0 + 10 +-28.66910256193319 + 20 +-16.55211408155711 + 30 +0.0 + 10 +-28.13524125272644 + 20 +-17.35109399338007 + 30 +0.0 + 10 +-27.234468590110495 + 20 +-17.294133669029016 + 30 +0.0 + 10 +-26.11056915218874 + 20 +-17.123793089559154 + 30 +0.0 + 10 +-25.219926275623024 + 20 +-16.908023110832435 + 30 +0.0 + 10 +-24.560275586952685 + 20 +-16.68579182293595 + 30 +0.0 + 10 +-24.124375961983844 + 20 +-16.495186330365343 + 30 +0.0 + 10 +-23.661937742366547 + 20 +-16.24286541077232 + 30 +0.0 + 10 +-23.18598203777361 + 20 +-16.084855543404604 + 30 +0.0 + 10 +-22.876276097264913 + 20 +-16.118465233518325 + 30 +0.0 + 10 +-21.49005778419349 + 20 +-17.92502011141009 + 30 +0.0 + 10 +-21.53775111228392 + 20 +-18.232871905804213 + 30 +0.0 + 10 +-21.813563324956654 + 20 +-18.65171385005134 + 30 +0.0 + 10 +-22.176974436124922 + 20 +-19.033089409973982 + 30 +0.0 + 10 +-22.473904328726594 + 20 +-19.404803783822803 + 30 +0.0 + 10 +-22.859293430458173 + 20 +-19.984459730613594 + 30 +0.0 + 10 +-23.298226564287805 + 20 +-20.788909307233272 + 30 +0.0 + 10 +-23.753649508579294 + 20 +-21.83042541435819 + 30 +0.0 + 10 +-24.041806077334652 + 20 +-22.685762576031347 + 30 +0.0 + 10 +-23.40822422008477 + 20 +-23.408224220084744 + 30 +0.0 + 10 +-22.68576257603136 + 20 +-24.041806077334634 + 30 +0.0 + 10 +-21.830425414352717 + 20 +-23.75364950857743 + 30 +0.0 + 10 +-20.788909307232927 + 20 +-23.298226564288278 + 30 +0.0 + 10 +-19.98445973061356 + 20 +-22.859293430458198 + 30 +0.0 + 10 +-19.40480378382278 + 20 +-22.47390432872663 + 30 +0.0 + 10 +-19.033089409974075 + 20 +-22.176974436125143 + 30 +0.0 + 10 +-18.65171385005105 + 20 +-21.813563324956977 + 30 +0.0 + 10 +-18.232871905804007 + 20 +-21.53775111228415 + 30 +0.0 + 10 +-17.925020111410088 + 20 +-21.490057784193528 + 30 +0.0 + 10 +-16.118465233518286 + 20 +-22.876276097264906 + 30 +0.0 + 10 +-16.08485554340433 + 20 +-23.18598203777375 + 30 +0.0 + 10 +-16.24286541077193 + 20 +-23.66193774236674 + 30 +0.0 + 10 +-16.49518633036515 + 20 +-24.12437596198369 + 30 +0.0 + 10 +-16.68579182293591 + 20 +-24.560275586952695 + 30 +0.0 + 10 +-16.9080231108324 + 20 +-25.21992627562305 + 30 +0.0 + 10 +-17.123793089558607 + 20 +-26.110569152188948 + 30 +0.0 + 10 +-17.294133669029396 + 20 +-27.234468590116254 + 30 +0.0 + 10 +-17.35109399338009 + 20 +-28.135241252726427 + 30 +0.0 + 10 +-16.552114081557107 + 20 +-28.669102561933187 + 30 +0.0 + 10 +-15.690286669774965 + 20 +-29.09410880808195 + 30 +0.0 + 10 +-14.938674823090532 + 20 +-28.594393388878157 + 30 +0.0 + 10 +-14.050519648286175 + 20 +-27.88492440080102 + 30 +0.0 + 10 +-13.387085280843976 + 20 +-27.2527406795668 + 30 +0.0 + 10 +-12.926926670779805 + 20 +-26.730457394397536 + 30 +0.0 + 10 +-12.644729268341981 + 20 +-26.34743838324612 + 30 +0.0 + 10 +-12.370406482269068 + 20 +-25.897702947163665 + 30 +0.0 + 10 +-12.03722168469932 + 20 +-25.52288453567814 + 30 +0.0 + 10 +-11.752203627458977 + 20 +-25.397138410875602 + 30 +0.0 + 10 +-9.648425914202027 + 20 +-26.268551671924854 + 30 +0.0 + 10 +-9.53580365072231 + 20 +-26.559005810516005 + 30 +0.0 + 10 +-9.565243061447328 + 20 +-27.059639680740844 + 30 +0.0 + 10 +-9.689278535775257 + 20 +-27.571626159600505 + 30 +0.0 + 10 +-9.76057017898688 + 20 +-28.042005196606244 + 30 +0.0 + 10 +-9.804498958032696 + 20 +-28.736696522847577 + 30 +0.0 + 10 +-9.782401414182035 + 20 +-29.652836859178674 + 30 +0.0 + 10 +-9.65605119984231 + 20 +-30.78252773854527 + 30 +0.0 + 10 +-9.477933527815226 + 20 +-31.667349733732777 + 30 +0.0 + 10 +-8.568004722033203 + 20 +-31.976228942117956 + 30 +0.0 + 10 +-7.625543656398139 + 20 +-32.16369610384658 + 30 +0.0 + 10 +-7.0288782299621575 + 20 +-31.486476614196164 + 30 +0.0 + 10 +-6.35461029489032 + 20 +-30.571310721415557 + 30 +0.0 + 10 +-5.8774030923893505 + 20 +-29.78895868864631 + 30 +0.0 + 10 +-5.5681008678796005 + 20 +-29.165373962809714 + 30 +0.0 + 10 +-5.394651723475539 + 20 +-28.722367945749493 + 30 +0.0 + 10 +-5.246076355783767 + 20 +-28.216956911498816 + 30 +0.0 + 10 +-5.021254698231779 + 20 +-27.768675556526627 + 30 +0.0 + 10 +-4.778493887731331 + 20 +-27.573446025612164 + 30 +0.0 + 10 +-2.5208623136106447 + 20 +-27.870668860977286 + 30 +0.0 + 10 +-2.3369024979042163 + 20 +-28.12207722810392 + 30 +0.0 + 10 +-2.235765204796672 + 20 +-28.61327189304137 + 30 +0.0 + 10 +-2.223062421262174 + 20 +-29.13991559870711 + 30 +0.0 + 10 +-2.170181807444797 + 20 +-29.612718493715757 + 30 +0.0 + 10 +-2.032814403943711 + 20 +-30.295108391676425 + 30 +0.0 + 10 +-1.774355248611686 + 20 +-31.174312737845245 + 30 +0.0 + 10 +-1.359924798765098 + 20 +-32.23280849212474 + 30 +0.0 + 10 +-0.9588675553555142 + 20 +-33.041380663155046 + 30 +0.0 + 10 +1.2685190389311577e-14 + 20 +-33.10422816311423 + 30 +0.0 + 10 +0.9588675553555224 + 20 +-33.041380663155046 + 30 +0.0 + 10 +1.3599247987676792 + 20 +-32.23280849211956 + 30 +0.0 + 10 +1.7743552486122944 + 20 +-31.174312737845334 + 30 +0.0 + 10 +2.032814403943785 + 20 +-30.295108391676422 + 30 +0.0 + 10 +2.170181807444867 + 20 +-29.612718493715764 + 30 +0.0 + 10 +2.223062421262295 + 20 +-29.139915598707336 + 30 +0.0 + 10 +2.2357652047971337 + 20 +-28.613271893041393 + 30 +0.0 + 10 +2.33690249790455 + 20 +-28.122077228103926 + 30 +0.0 + 10 +2.520862313610704 + 20 +-27.870668860977307 + 30 +0.0 + 10 +4.778493887731383 + 20 +-27.573446025612125 + 30 +0.0 + 10 +5.021254698232098 + 20 +-27.768675556526528 + 30 +0.0 + 10 +5.246076355784207 + 20 +-28.216956911498674 + 30 +0.0 + 10 +5.394651723475597 + 20 +-28.722367945749248 + 30 +0.0 + 10 +5.568100867879666 + 20 +-29.16537396280969 + 30 +0.0 + 10 +5.877403092389424 + 20 +-29.788958688646296 + 30 +0.0 + 10 +6.354610294890884 + 20 +-30.571310721415315 + 30 +0.0 + 10 +7.028878229965992 + 20 +-31.486476614200505 + 30 +0.0 + 10 +7.625543656398147 + 20 +-32.163696103846576 + 30 +0.0 + 10 +8.568004722033205 + 20 +-31.976228942117956 + 30 +0.0 + 10 +9.477933527815237 + 20 +-31.66734973373278 + 30 +0.0 + 10 +9.656051199843462 + 20 +-30.782527738539592 + 30 +0.0 + 10 +9.782401414182646 + 20 +-29.652836859178606 + 30 +0.0 + 10 +9.804498958032768 + 20 +-28.736696522847556 + 30 +0.0 + 10 +9.760570178986951 + 20 +-28.042005196606233 + 30 +0.0 + 10 +9.689278535775435 + 20 +-27.571626159600687 + 30 +0.0 + 10 +9.565243061447783 + 20 +-27.059639680740748 + 30 +0.0 + 10 +9.535803650722636 + 20 +-26.55900581051593 + 30 +0.0 + 10 +9.648425914202091 + 20 +-26.26855167192486 + 30 +0.0 + 10 +11.75220362745902 + 20 +-25.397138410875556 + 30 +0.0 + 10 +12.037221684699606 + 20 +-25.522884535677967 + 30 +0.0 + 10 +12.370406482269459 + 20 +-25.897702947163417 + 30 +0.0 + 10 +12.644729268341976 + 20 +-26.34743838324587 + 30 +0.0 + 10 +12.926926670779864 + 20 +-26.730457394397497 + 30 +0.0 + 10 +13.387085280844046 + 20 +-27.252740679566767 + 30 +0.0 + 10 +14.050519648286658 + 20 +-27.88492440080064 + 30 +0.0 + 10 +14.938674823095363 + 20 +-28.594393388881354 + 30 +0.0 + 10 +15.690286669774975 + 20 +-29.094108808081945 + 30 +0.0 + 10 +16.552114081557132 + 20 +-28.669102561933173 + 30 +0.0 + 10 +17.351093993380093 + 20 +-28.135241252726424 + 30 +0.0 + 10 +17.294133669029037 + 20 +-27.234468590110477 + 30 +0.0 + 10 +17.12379308955917 + 20 +-26.110569152188724 + 30 +0.0 + 10 +16.908023110832456 + 20 +-25.21992627562301 + 30 +0.0 + 10 +16.685791822935972 + 20 +-24.56027558695267 + 30 +0.0 + 10 +16.495186330365364 + 20 +-24.12437596198383 + 30 +0.0 + 10 +16.24286541077234 + 20 +-23.661937742366533 + 30 +0.0 + 10 +16.084855543404622 + 20 +-23.185982037773595 + 30 +0.0 + 10 +16.118465233518343 + 20 +-22.876276097264896 + 30 +0.0 + 10 +17.925020111410113 + 20 +-21.49005778419347 + 30 +0.0 + 10 +18.232871905804235 + 20 +-21.537751112283907 + 30 +0.0 + 10 +18.651713850051358 + 20 +-21.813563324956636 + 30 +0.0 + 10 +19.033089409974 + 20 +-22.1769744361249 + 30 +0.0 + 10 +19.40480378382282 + 20 +-22.473904328726572 + 30 +0.0 + 10 +19.984459730613615 + 20 +-22.859293430458152 + 30 +0.0 + 10 +20.78890930723329 + 20 +-23.298226564287788 + 30 +0.0 + 10 +21.830425414358206 + 20 +-23.753649508579272 + 30 +0.0 + 10 +22.685762576031365 + 20 +-24.04180607733463 + 30 +0.0 + 10 +23.408224220084744 + 20 +-23.40822422008477 + 30 +0.0 + 10 +24.041806077334634 + 20 +-22.68576257603136 + 30 +0.0 + 10 +23.75364950857743 + 20 +-21.830425414352717 + 30 +0.0 + 10 +23.298226564288278 + 20 +-20.788909307232927 + 30 +0.0 + 10 +22.859293430458198 + 20 +-19.98445973061356 + 30 +0.0 + 10 +22.47390432872663 + 20 +-19.40480378382278 + 30 +0.0 + 10 +22.176974436125143 + 20 +-19.033089409974075 + 30 +0.0 + 10 +21.813563324956977 + 20 +-18.65171385005105 + 30 +0.0 + 10 +21.53775111228415 + 20 +-18.232871905804007 + 30 +0.0 + 10 +21.490057784193528 + 20 +-17.925020111410088 + 30 +0.0 + 10 +22.876276097264906 + 20 +-16.118465233518286 + 30 +0.0 + 10 +23.18598203777375 + 20 +-16.08485554340433 + 30 +0.0 + 10 +23.66193774236674 + 20 +-16.24286541077193 + 30 +0.0 + 10 +24.12437596198369 + 20 +-16.49518633036515 + 30 +0.0 + 10 +24.560275586952695 + 20 +-16.68579182293591 + 30 +0.0 + 10 +25.21992627562305 + 20 +-16.9080231108324 + 30 +0.0 + 10 +26.110569152188948 + 20 +-17.123793089558607 + 30 +0.0 + 10 +27.234468590116254 + 20 +-17.294133669029396 + 30 +0.0 + 10 +28.135241252726427 + 20 +-17.35109399338009 + 30 +0.0 + 10 +28.669102561933187 + 20 +-16.55211408155711 + 30 +0.0 + 10 +29.09410880808195 + 20 +-15.690286669774967 + 30 +0.0 + 10 +28.594393388878157 + 20 +-14.938674823090535 + 30 +0.0 + 10 +27.88492440080102 + 20 +-14.050519648286175 + 30 +0.0 + 10 +27.2527406795668 + 20 +-13.387085280843978 + 30 +0.0 + 10 +26.730457394397536 + 20 +-12.926926670779805 + 30 +0.0 + 10 +26.34743838324612 + 20 +-12.644729268341985 + 30 +0.0 + 10 +25.897702947163665 + 20 +-12.37040648226907 + 30 +0.0 + 10 +25.52288453567814 + 20 +-12.03722168469932 + 30 +0.0 + 10 +25.397138410875602 + 20 +-11.752203627458977 + 30 +0.0 + 10 +26.268551671924854 + 20 +-9.648425914202027 + 30 +0.0 + 10 +26.559005810516005 + 20 +-9.535803650722311 + 30 +0.0 + 10 +27.059639680740844 + 20 +-9.565243061447331 + 30 +0.0 + 10 +27.571626159600505 + 20 +-9.689278535775259 + 30 +0.0 + 10 +28.042005196606244 + 20 +-9.760570178986882 + 30 +0.0 + 10 +28.736696522847577 + 20 +-9.804498958032697 + 30 +0.0 + 10 +29.652836859178674 + 20 +-9.782401414182036 + 30 +0.0 + 10 +30.78252773854527 + 20 +-9.656051199842311 + 30 +0.0 + 10 +31.667349733732777 + 20 +-9.477933527815228 + 30 +0.0 + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +31 + 70 +1 + 10 +0.41582338163551874 + 20 +-1.9562952014676114 + 30 +0.0 + 10 +1.2246467991473532e-16 + 20 +-2 + 30 +0.0 + 10 +-0.41582338163551785 + 20 +-1.9562952014676114 + 30 +0.0 + 10 +-0.8134732861516002 + 20 +-1.827090915285202 + 30 +0.0 + 10 +-1.1755705045849467 + 20 +-1.6180339887498945 + 30 +0.0 + 10 +-1.486289650954788 + 20 +-1.338261212717717 + 30 +0.0 + 10 +-1.7320508075688772 + 20 +-1.0000000000000002 + 30 +0.0 + 10 +-1.9021130325903073 + 20 +-0.6180339887498946 + 30 +0.0 + 10 +-1.9890437907365468 + 20 +-0.20905692653530608 + 30 +0.0 + 10 +-1.9890437907365466 + 20 +0.20905692653530836 + 30 +0.0 + 10 +-1.902113032590307 + 20 +0.618033988749895 + 30 +0.0 + 10 +-1.7320508075688767 + 20 +1.0000000000000009 + 30 +0.0 + 10 +-1.486289650954788 + 20 +1.338261212717717 + 30 +0.0 + 10 +-1.175570504584946 + 20 +1.618033988749895 + 30 +0.0 + 10 +-0.8134732861516005 + 20 +1.8270909152852017 + 30 +0.0 + 10 +-0.41582338163551824 + 20 +1.9562952014676114 + 30 +0.0 + 10 +1.0106430996148606e-15 + 20 +2 + 30 +0.0 + 10 +0.4158233816355185 + 20 +1.9562952014676114 + 30 +0.0 + 10 +0.8134732861516 + 20 +1.827090915285202 + 30 +0.0 + 10 +1.1755705045849465 + 20 +1.618033988749895 + 30 +0.0 + 10 +1.486289650954789 + 20 +1.3382612127177158 + 30 +0.0 + 10 +1.7320508075688774 + 20 +0.9999999999999997 + 30 +0.0 + 10 +1.9021130325903073 + 20 +0.6180339887498948 + 30 +0.0 + 10 +1.9890437907365468 + 20 +0.20905692653530678 + 30 +0.0 + 10 +1.9890437907365466 + 20 +-0.2090569265353068 + 30 +0.0 + 10 +1.902113032590307 + 20 +-0.6180339887498948 + 30 +0.0 + 10 +1.7320508075688772 + 20 +-1.0000000000000002 + 30 +0.0 + 10 +1.4862896509547885 + 20 +-1.3382612127177165 + 30 +0.0 + 10 +1.1755705045849463 + 20 +-1.618033988749895 + 30 +0.0 + 10 +0.8134732861516004 + 20 +-1.8270909152852017 + 30 +0.0 + 10 +0.41582338163551874 + 20 +-1.9562952014676114 + 30 +0.0 + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +229 + 70 +1 + 10 +28.908264411386597 + 20 +5.409238575089372 + 30 +0.0 + 10 +28.61865418009465 + 20 +4.613541004171724 + 30 +0.0 + 10 +28.471615212130537 + 20 +3.779641578381499 + 30 +0.0 + 10 +28.908022441344983 + 20 +3.2797006347076385 + 30 +0.0 + 10 +30.007682325386632 + 20 +2.392966048474426 + 30 +0.0 + 10 +30.858032304349603 + 20 +1.923901530707663 + 30 +0.0 + 10 +31.35917583721576 + 20 +1.7525003477700496 + 30 +0.0 + 10 +31.446265802514446 + 20 +1.7388908869047492 + 30 +0.0 + 10 +31.705553576775984 + 20 +1.7439522167197854 + 30 +0.0 + 10 +32.6861322144129 + 20 +1.5451382157093896 + 30 +0.0 + 10 +33.154228163114226 + 20 +1.1385562939891836 + 30 +0.0 + 10 +33.15422816311422 + 20 +-1.1385562939891605 + 30 +0.0 + 10 +32.686132214413 + 20 +-1.545138215709939 + 30 +0.0 + 10 +31.705553576775984 + 20 +-1.7439522167197963 + 30 +0.0 + 10 +31.44626580251446 + 20 +-1.738890886904766 + 30 +0.0 + 10 +31.35917583721574 + 20 +-1.7525003477700343 + 30 +0.0 + 10 +30.85803230434957 + 20 +-1.9239015307076544 + 30 +0.0 + 10 +30.00768232538669 + 20 +-2.3929660484743827 + 30 +0.0 + 10 +28.90802244134499 + 20 +-3.2797006347076323 + 30 +0.0 + 10 +28.47161521213054 + 20 +-3.7796415783815043 + 30 +0.0 + 10 +28.618654180094648 + 20 +-4.61354100417172 + 30 +0.0 + 10 +28.908264411386593 + 20 +-5.409238575089367 + 30 +0.0 + 10 +29.53617463011841 + 20 +-5.623996518095676 + 30 +0.0 + 10 +30.931875318337738 + 20 +-5.842101254167094 + 30 +0.0 + 10 +31.902832261110614 + 20 +-5.823148053085523 + 30 +0.0 + 10 +32.422535882983794 + 20 +-5.7210140653151225 + 30 +0.0 + 10 +32.50476273577981 + 20 +-5.689255221506937 + 30 +0.0 + 10 +32.726781870273506 + 20 +-5.555228094179418 + 30 +0.0 + 10 +33.67539488138061 + 20 +-5.2371167508639855 + 30 +0.0 + 10 +34.28406882522464 + 20 +-5.355179049442518 + 30 +0.0 + 10 +35.422625119213805 + 20 +-7.327216397909096 + 30 +0.0 + 10 +35.22053309709037 + 20 +-7.913374645189394 + 30 +0.0 + 10 +34.4707340869933 + 20 +-8.575841939510466 + 30 +0.0 + 10 +34.24365362268458 + 20 +-8.701102586444478 + 30 +0.0 + 10 +34.17503623075382 + 20 +-8.75643370793497 + 30 +0.0 + 10 +33.82673379181824 + 20 +-9.155443253030738 + 30 +0.0 + 10 +33.324841366812194 + 20 +-9.986840030912063 + 30 +0.0 + 10 +32.815875264826055 + 20 +-11.304604651025187 + 30 +0.0 + 10 +32.6879059897681 + 20 +-11.955769823245953 + 30 +0.0 + 10 +33.232195184266374 + 20 +-12.604428426199485 + 30 +0.0 + 10 +33.880853787219905 + 20 +-13.148717620697763 + 30 +0.0 + 10 +34.532018959440656 + 20 +-13.020748345639806 + 30 +0.0 + 10 +35.84978357955372 + 20 +-12.511782243653693 + 30 +0.0 + 10 +36.681180357435125 + 20 +-12.00988981864758 + 30 +0.0 + 10 +37.080189902530876 + 20 +-11.661587379712014 + 30 +0.0 + 10 +37.135521024021386 + 20 +-11.592969987781292 + 30 +0.0 + 10 +37.260781670955396 + 20 +-11.365889523472562 + 30 +0.0 + 10 +37.92324896527688 + 20 +-10.61609051337585 + 30 +0.0 + 10 +38.50940721255674 + 20 +-10.41399849125203 + 30 +0.0 + 10 +40.48144456102331 + 20 +-11.552554785241211 + 30 +0.0 + 10 +40.59950685960239 + 20 +-12.161228729085428 + 30 +0.0 + 10 +40.281395516286445 + 20 +-13.109841740192353 + 30 +0.0 + 10 +40.14736838895894 + 20 +-13.33186087468604 + 30 +0.0 + 10 +40.11560954515071 + 20 +-13.41408772748207 + 30 +0.0 + 10 +40.01347555738031 + 20 +-13.933791349355264 + 30 +0.0 + 10 +39.99452235629875 + 20 +-14.90474829212805 + 30 +0.0 + 10 +40.21262709237018 + 20 +-16.300448980347433 + 30 +0.0 + 10 +40.42738503537649 + 20 +-16.92835919907926 + 30 +0.0 + 10 +41.22308260629413 + 20 +-17.217969430371205 + 30 +0.0 + 10 +42.056982032084356 + 20 +-17.36500839833532 + 30 +0.0 + 10 +42.55692297575822 + 20 +-16.928601169120874 + 30 +0.0 + 10 +43.44365756199143 + 20 +-15.828941285079226 + 30 +0.0 + 10 +43.91272207975819 + 20 +-14.978591306116254 + 30 +0.0 + 10 +44.084123262695805 + 20 +-14.4774477732501 + 30 +0.0 + 10 +44.09773272356111 + 20 +-14.390357807951409 + 30 +0.0 + 10 +44.09267139374607 + 20 +-14.131070033689875 + 30 +0.0 + 10 +44.291485394756464 + 20 +-13.150491396052955 + 30 +0.0 + 10 +44.698067316476674 + 20 +-12.682395447351631 + 30 +0.0 + 10 +46.97517990445502 + 20 +-12.682395447351642 + 30 +0.0 + 10 +47.3817618261758 + 20 +-13.150491396052855 + 30 +0.0 + 10 +47.580575827185655 + 20 +-14.131070033689875 + 30 +0.0 + 10 +47.57551449737062 + 20 +-14.390357807951396 + 30 +0.0 + 10 +47.58912395823589 + 20 +-14.477447773250116 + 30 +0.0 + 10 +47.76052514117351 + 20 +-14.978591306116286 + 30 +0.0 + 10 +48.22958965894024 + 20 +-15.828941285079168 + 30 +0.0 + 10 +49.11632424517349 + 20 +-16.928601169120867 + 30 +0.0 + 10 +49.61626518884736 + 20 +-17.365008398335316 + 30 +0.0 + 10 +50.45016461463757 + 20 +-17.21796943037121 + 30 +0.0 + 10 +51.24586218555522 + 20 +-16.928359199079264 + 30 +0.0 + 10 +51.46062012856153 + 20 +-16.300448980347443 + 30 +0.0 + 10 +51.67872486463295 + 20 +-14.90474829212812 + 30 +0.0 + 10 +51.65977166355138 + 20 +-13.933791349355243 + 30 +0.0 + 10 +51.55763767578098 + 20 +-13.414087727482066 + 30 +0.0 + 10 +51.52587883197279 + 20 +-13.331860874686045 + 30 +0.0 + 10 +51.391851704645276 + 20 +-13.109841740192348 + 30 +0.0 + 10 +51.07374036132984 + 20 +-12.161228729085241 + 30 +0.0 + 10 +51.191802659908376 + 20 +-11.552554785241217 + 30 +0.0 + 10 +53.16384000837495 + 20 +-10.413998491252052 + 30 +0.0 + 10 +53.74999825565525 + 20 +-10.616090513375491 + 30 +0.0 + 10 +54.41246554997632 + 20 +-11.365889523472559 + 30 +0.0 + 10 +54.537726196910334 + 20 +-11.592969987781277 + 30 +0.0 + 10 +54.593057318400824 + 20 +-11.661587379712037 + 30 +0.0 + 10 +54.99206686349659 + 20 +-12.009889818647613 + 30 +0.0 + 10 +55.82346364137791 + 20 +-12.511782243653666 + 30 +0.0 + 10 +57.141228261491044 + 20 +-13.020748345639804 + 30 +0.0 + 10 +57.79239343371181 + 20 +-13.148717620697763 + 30 +0.0 + 10 +58.44105203666534 + 20 +-12.604428426199483 + 30 +0.0 + 10 +58.98534123116362 + 20 +-11.955769823245951 + 30 +0.0 + 10 +58.857371956105666 + 20 +-11.304604651025201 + 30 +0.0 + 10 +58.34840585411955 + 20 +-9.986840030912129 + 30 +0.0 + 10 +57.846513429113436 + 20 +-9.155443253030729 + 30 +0.0 + 10 +57.498210990177874 + 20 +-8.756433707934976 + 30 +0.0 + 10 +57.42959359824715 + 20 +-8.701102586444472 + 30 +0.0 + 10 +57.202513133938425 + 20 +-8.575841939510457 + 30 +0.0 + 10 +56.45271412384171 + 20 +-7.9133746451889655 + 30 +0.0 + 10 +56.25062210171789 + 20 +-7.327216397909113 + 30 +0.0 + 10 +57.38917839570707 + 20 +-5.355179049442544 + 30 +0.0 + 10 +57.99785233955129 + 20 +-5.237116750863459 + 30 +0.0 + 10 +58.94646535065821 + 20 +-5.555228094179409 + 30 +0.0 + 10 +59.1684844851519 + 20 +-5.689255221506917 + 30 +0.0 + 10 +59.250711337947926 + 20 +-5.721014065315145 + 30 +0.0 + 10 +59.770414959821125 + 20 +-5.823148053085546 + 30 +0.0 + 10 +60.741371902593905 + 20 +-5.842101254167103 + 30 +0.0 + 10 +62.13707259081329 + 20 +-5.623996518095675 + 30 +0.0 + 10 +62.76498280954512 + 20 +-5.409238575089362 + 30 +0.0 + 10 +63.05459304083706 + 20 +-4.613541004171726 + 30 +0.0 + 10 +63.20163200880118 + 20 +-3.7796415783815016 + 30 +0.0 + 10 +62.76522477958673 + 20 +-3.2797006347076403 + 30 +0.0 + 10 +61.66556489554508 + 20 +-2.392966048474428 + 30 +0.0 + 10 +60.81521491658211 + 20 +-1.9239015307076648 + 30 +0.0 + 10 +60.314071383715955 + 20 +-1.7525003477700514 + 30 +0.0 + 10 +60.22698141841727 + 20 +-1.738890886904751 + 30 +0.0 + 10 +59.96769364415573 + 20 +-1.7439522167197872 + 30 +0.0 + 10 +58.98711500651881 + 20 +-1.5451382157093914 + 30 +0.0 + 10 +58.51901905781749 + 20 +-1.1385562939891853 + 30 +0.0 + 10 +58.5190190578175 + 20 +1.1385562939891591 + 30 +0.0 + 10 +58.987115006518714 + 20 +1.5451382157099376 + 30 +0.0 + 10 +59.96769364415573 + 20 +1.7439522167197945 + 30 +0.0 + 10 +60.22698141841725 + 20 +1.7388908869047641 + 30 +0.0 + 10 +60.31407138371597 + 20 +1.7525003477700327 + 30 +0.0 + 10 +60.81521491658214 + 20 +1.9239015307076526 + 30 +0.0 + 10 +61.665564895545025 + 20 +2.3929660484743804 + 30 +0.0 + 10 +62.765224779586724 + 20 +3.2797006347076305 + 30 +0.0 + 10 +63.20163200880117 + 20 +3.7796415783815016 + 30 +0.0 + 10 +63.05459304083706 + 20 +4.613541004171724 + 30 +0.0 + 10 +62.76498280954512 + 20 +5.40923857508937 + 30 +0.0 + 10 +62.1370725908133 + 20 +5.623996518095678 + 30 +0.0 + 10 +60.741371902593976 + 20 +5.842101254167096 + 30 +0.0 + 10 +59.770414959821096 + 20 +5.823148053085526 + 30 +0.0 + 10 +59.25071133794792 + 20 +5.721014065315127 + 30 +0.0 + 10 +59.1684844851519 + 20 +5.689255221506941 + 30 +0.0 + 10 +58.9464653506582 + 20 +5.55522809417942 + 30 +0.0 + 10 +57.997852339551095 + 20 +5.237116750863987 + 30 +0.0 + 10 +57.38917839570707 + 20 +5.355179049442519 + 30 +0.0 + 10 +56.25062210171791 + 20 +7.327216397909099 + 30 +0.0 + 10 +56.452714123841346 + 20 +7.9133746451893945 + 30 +0.0 + 10 +57.20251313393841 + 20 +8.575841939510468 + 30 +0.0 + 10 +57.42959359824713 + 20 +8.701102586444481 + 30 +0.0 + 10 +57.498210990177895 + 20 +8.756433707934974 + 30 +0.0 + 10 +57.846513429113465 + 20 +9.15544325303074 + 30 +0.0 + 10 +58.34840585411952 + 20 +9.986840030912065 + 30 +0.0 + 10 +58.85737195610566 + 20 +11.30460465102519 + 30 +0.0 + 10 +58.985341231163616 + 20 +11.955769823245955 + 30 +0.0 + 10 +58.44105203666535 + 20 +12.604428426199478 + 30 +0.0 + 10 +57.792393433711815 + 20 +13.148717620697756 + 30 +0.0 + 10 +57.141228261491065 + 20 +13.020748345639802 + 30 +0.0 + 10 +55.823463641378 + 20 +12.511782243653688 + 30 +0.0 + 10 +54.99206686349659 + 20 +12.009889818647576 + 30 +0.0 + 10 +54.59305731840084 + 20 +11.66158737971201 + 30 +0.0 + 10 +54.537726196910334 + 20 +11.59296998778129 + 30 +0.0 + 10 +54.41246554997632 + 20 +11.365889523472557 + 30 +0.0 + 10 +53.74999825565483 + 20 +10.616090513375847 + 30 +0.0 + 10 +53.163840008374976 + 20 +10.413998491252029 + 30 +0.0 + 10 +51.191802659908404 + 20 +11.55255478524121 + 30 +0.0 + 10 +51.07374036132933 + 20 +12.161228729085426 + 30 +0.0 + 10 +51.391851704645276 + 20 +13.10984174019235 + 30 +0.0 + 10 +51.52587883197278 + 20 +13.331860874686036 + 30 +0.0 + 10 +51.55763767578101 + 20 +13.414087727482068 + 30 +0.0 + 10 +51.65977166355141 + 20 +13.933791349355262 + 30 +0.0 + 10 +51.67872486463297 + 20 +14.904748292128044 + 30 +0.0 + 10 +51.460620128561544 + 20 +16.30044898034743 + 30 +0.0 + 10 +51.245862185555225 + 20 +16.92835919907926 + 30 +0.0 + 10 +50.450164614637586 + 20 +17.217969430371205 + 30 +0.0 + 10 +49.61626518884736 + 20 +17.36500839833532 + 30 +0.0 + 10 +49.1163242451735 + 20 +16.928601169120874 + 30 +0.0 + 10 +48.229589658940284 + 20 +15.828941285079225 + 30 +0.0 + 10 +47.760525141173524 + 20 +14.978591306116254 + 30 +0.0 + 10 +47.58912395823591 + 20 +14.477447773250098 + 30 +0.0 + 10 +47.57551449737061 + 20 +14.390357807951407 + 30 +0.0 + 10 +47.58057582718565 + 20 +14.131070033689873 + 30 +0.0 + 10 +47.38176182617525 + 20 +13.150491396052953 + 30 +0.0 + 10 +46.97517990445504 + 20 +12.682395447351631 + 30 +0.0 + 10 +44.698067316476696 + 20 +12.682395447351642 + 30 +0.0 + 10 +44.291485394755924 + 20 +13.150491396052855 + 30 +0.0 + 10 +44.092671393746066 + 20 +14.131070033689875 + 30 +0.0 + 10 +44.097732723561094 + 20 +14.390357807951396 + 30 +0.0 + 10 +44.084123262695826 + 20 +14.477447773250116 + 30 +0.0 + 10 +43.912722079758204 + 20 +14.978591306116286 + 30 +0.0 + 10 +43.44365756199148 + 20 +15.828941285079168 + 30 +0.0 + 10 +42.556922975758226 + 20 +16.928601169120867 + 30 +0.0 + 10 +42.056982032084356 + 20 +17.365008398335316 + 30 +0.0 + 10 +41.223082606294135 + 20 +17.21796943037121 + 30 +0.0 + 10 +40.42738503537649 + 20 +16.92835919907926 + 30 +0.0 + 10 +40.21262709237018 + 20 +16.30044898034744 + 30 +0.0 + 10 +39.99452235629876 + 20 +14.904748292128119 + 30 +0.0 + 10 +40.01347555738033 + 20 +13.933791349355243 + 30 +0.0 + 10 +40.11560954515073 + 20 +13.414087727482066 + 30 +0.0 + 10 +40.14736838895892 + 20 +13.331860874686043 + 30 +0.0 + 10 +40.28139551628644 + 20 +13.109841740192346 + 30 +0.0 + 10 +40.59950685960187 + 20 +12.16122872908524 + 30 +0.0 + 10 +40.48144456102334 + 20 +11.552554785241213 + 30 +0.0 + 10 +38.50940721255676 + 20 +10.41399849125205 + 30 +0.0 + 10 +37.923248965276464 + 20 +10.61609051337549 + 30 +0.0 + 10 +37.26078167095539 + 20 +11.365889523472555 + 30 +0.0 + 10 +37.13552102402137 + 20 +11.592969987781274 + 30 +0.0 + 10 +37.08018990253088 + 20 +11.661587379712037 + 30 +0.0 + 10 +36.68118035743512 + 20 +12.00988981864761 + 30 +0.0 + 10 +35.849783579553794 + 20 +12.511782243653665 + 30 +0.0 + 10 +34.53201895944066 + 20 +13.0207483456398 + 30 +0.0 + 10 +33.880853787219905 + 20 +13.14871762069776 + 30 +0.0 + 10 +33.23219518426638 + 20 +12.604428426199492 + 30 +0.0 + 10 +32.6879059897681 + 20 +11.955769823245959 + 30 +0.0 + 10 +32.815875264826055 + 20 +11.304604651025207 + 30 +0.0 + 10 +33.324841366812166 + 20 +9.986840030912138 + 30 +0.0 + 10 +33.826733791818285 + 20 +9.155443253030736 + 30 +0.0 + 10 +34.17503623075385 + 20 +8.756433707934983 + 30 +0.0 + 10 +34.24365362268457 + 20 +8.701102586444478 + 30 +0.0 + 10 +34.4707340869933 + 20 +8.575841939510465 + 30 +0.0 + 10 +35.22053309709001 + 20 +7.9133746451889735 + 30 +0.0 + 10 +35.422625119213826 + 20 +7.327216397909119 + 30 +0.0 + 10 +34.28406882522465 + 20 +5.355179049442551 + 30 +0.0 + 10 +33.67539488138043 + 20 +5.237116750863468 + 30 +0.0 + 10 +32.726781870273506 + 20 +5.555228094179418 + 30 +0.0 + 10 +32.50476273577982 + 20 +5.689255221506924 + 30 +0.0 + 10 +32.42253588298379 + 20 +5.721014065315151 + 30 +0.0 + 10 +31.902832261110596 + 20 +5.823148053085555 + 30 +0.0 + 10 +30.931875318337813 + 20 +5.842101254167114 + 30 +0.0 + 10 +29.536174630118428 + 20 +5.623996518095684 + 30 +0.0 + 10 +28.908264411386597 + 20 +5.409238575089372 + 30 +0.0 + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +31 + 70 +1 + 10 +44.92864261098676 + 20 +1.782013048376736 + 30 +0.0 + 10 +45.31898552026082 + 20 +1.9318516525781366 + 30 +0.0 + 10 +45.731951697979966 + 20 +1.9972590695091477 + 30 +0.0 + 10 +46.14949254054632 + 20 +1.9753766811902758 + 30 +0.0 + 10 +46.55335950955646 + 20 +1.8671608529944033 + 30 +0.0 + 10 +46.92590168049591 + 20 +1.6773411358908485 + 30 +0.0 + 10 +47.25083717283895 + 20 +1.4142135623730954 + 30 +0.0 + 10 +47.513964746356706 + 20 +1.089278070030054 + 30 +0.0 + 10 +47.70378446346026 + 20 +0.7167358990905998 + 30 +0.0 + 10 +47.81200029165613 + 20 +0.31286893008046046 + 30 +0.0 + 10 +47.833882679975005 + 20 +-0.10467191248588775 + 30 +0.0 + 10 +47.768475263043996 + 20 +-0.5176380902050426 + 30 +0.0 + 10 +47.61863665884259 + 20 +-0.907980999479094 + 30 +0.0 + 10 +47.3909155333798 + 20 +-1.258640782099675 + 30 +0.0 + 10 +47.09526439256553 + 20 +-1.5542919229139418 + 30 +0.0 + 10 +46.74460460994495 + 20 +-1.782013048376736 + 30 +0.0 + 10 +46.3542617006709 + 20 +-1.9318516525781368 + 30 +0.0 + 10 +45.94129552295175 + 20 +-1.9972590695091479 + 30 +0.0 + 10 +45.523754680385395 + 20 +-1.9753766811902755 + 30 +0.0 + 10 +45.119887711375256 + 20 +-1.8671608529944037 + 30 +0.0 + 10 +44.7473455404358 + 20 +-1.6773411358908477 + 30 +0.0 + 10 +44.422410048092765 + 20 +-1.414213562373095 + 30 +0.0 + 10 +44.15928247457501 + 20 +-1.0892780700300542 + 30 +0.0 + 10 +43.969462757471454 + 20 +-0.7167358990906005 + 30 +0.0 + 10 +43.86124692927558 + 20 +-0.3128689300804619 + 30 +0.0 + 10 +43.83936454095671 + 20 +0.10467191248588753 + 30 +0.0 + 10 +43.90477195788772 + 20 +0.5176380902050417 + 30 +0.0 + 10 +44.054610562089124 + 20 +0.9079809994790935 + 30 +0.0 + 10 +44.28233168755192 + 20 +1.258640782099675 + 30 +0.0 + 10 +44.57798282836618 + 20 +1.5542919229139418 + 30 +0.0 + 10 +44.92864261098676 + 20 +1.782013048376736 + 30 +0.0 + 0 +ENDSEC + 0 +EOF diff --git a/dxf/InvoluteGear_2.dxf b/dxf/InvoluteGear_2.dxf new file mode 100644 index 0000000..ca2502e --- /dev/null +++ b/dxf/InvoluteGear_2.dxf @@ -0,0 +1,4144 @@ +999 +DXF generated by OpenJsCad + 0 +SECTION + 2 +HEADER + 0 +ENDSEC + 0 +SECTION + 2 +TABLES + 0 +TABLE + 2 +LTYPE + 70 +1 + 0 +LTYPE + 2 +CONTINUOUS + 3 +Solid Line + 72 +65 + 73 +0 + 40 +0.0 + 0 +ENDTAB + 0 +TABLE + 2 +LAYER + 70 +1 + 0 +LAYER + 2 +OpenJsCad + 62 +7 + 6 +continuous + 0 +ENDTAB + 0 +TABLE + 2 +STYLE + 70 +0 + 0 +ENDTAB + 0 +TABLE + 2 +VIEW + 70 +0 + 0 +ENDTAB + 0 +ENDSEC + 0 +SECTION + 2 +BLOCKS + 0 +ENDSEC + 0 +SECTION + 2 +ENTITIES + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +381 + 70 +1 + 10 +26.280794545155107 + 20 +-9.523883451586096 + 30 +0.0 + 10 +26.640300848151124 + 20 +-8.6559584591345 + 30 +0.0 + 10 +26.85960765010154 + 20 +-7.74247988739117 + 30 +0.0 + 10 +26.27070284635001 + 20 +-7.135165080233106 + 30 +0.0 + 10 +25.356220508541686 + 20 +-6.371034733203745 + 30 +0.0 + 10 +24.586432704391544 + 20 +-5.8541151922644525 + 30 +0.0 + 10 +24.000595778963696 + 20 +-5.544169757986571 + 30 +0.0 + 10 +23.63098394965083 + 20 +-5.395723708360466 + 30 +0.0 + 10 +23.17568411102707 + 20 +-5.2661851615271535 + 30 +0.0 + 10 +22.637821596318798 + 20 +-4.996843000825778 + 30 +0.0 + 10 +22.408655494354424 + 20 +-4.701930900309027 + 30 +0.0 + 10 +22.764874383891094 + 20 +-2.452853346940511 + 30 +0.0 + 10 +23.073957149384828 + 20 +-2.2431914920514777 + 30 +0.0 + 10 +23.668726103827414 + 20 +-2.153240532685363 + 30 +0.0 + 10 +24.14177159461666 + 20 +-2.170737441279176 + 30 +0.0 + 10 +24.539165685466823 + 20 +-2.1437731950436536 + 30 +0.0 + 10 +25.192108117402064 + 20 +-2.0300311359673224 + 30 +0.0 + 10 +26.08395674757863 + 20 +-1.7762889517015832 + 30 +0.0 + 10 +27.189810397138167 + 20 +-1.3321483892987869 + 30 +0.0 + 10 +27.93756274457033 + 20 +-0.9365392769371835 + 30 +0.0 + 10 +28.011269984173577 + 20 +-6.116123309172532e-17 + 30 +0.0 + 10 +27.93756274457033 + 20 +0.936539276937184 + 30 +0.0 + 10 +27.18981039713753 + 20 +1.332148389299128 + 30 +0.0 + 10 +26.083956747578398 + 20 +1.776288951701775 + 30 +0.0 + 10 +25.19210811740213 + 20 +2.030031135967422 + 30 +0.0 + 10 +24.53916568546687 + 20 +2.143773195043757 + 30 +0.0 + 10 +24.141771594616802 + 20 +2.170737441279251 + 30 +0.0 + 10 +23.668726103827417 + 20 +2.153240532685565 + 30 +0.0 + 10 +23.07395714938482 + 20 +2.243191492051523 + 30 +0.0 + 10 +22.764874383891154 + 20 +2.4528533469406164 + 30 +0.0 + 10 +22.40865549435433 + 20 +4.701930900309109 + 30 +0.0 + 10 +22.637821596318787 + 20 +4.996843000825823 + 30 +0.0 + 10 +23.175684111027003 + 20 +5.2661851615273445 + 30 +0.0 + 10 +23.63098394965067 + 20 +5.395723708360494 + 30 +0.0 + 10 +24.00059577896362 + 20 +5.544169757986656 + 30 +0.0 + 10 +24.58643270439145 + 20 +5.854115192264526 + 30 +0.0 + 10 +25.356220508541846 + 20 +6.371034733204 + 30 +0.0 + 10 +26.27070284635051 + 20 +7.135165080233627 + 30 +0.0 + 10 +26.85960765010154 + 20 +7.742479887391169 + 30 +0.0 + 10 +26.640300848151124 + 20 +8.655958459134501 + 30 +0.0 + 10 +26.280794545155114 + 20 +9.52388345158609 + 30 +0.0 + 10 +25.44738986370472 + 20 +9.669061892863164 + 30 +0.0 + 10 +24.25841356254907 + 20 +9.749737097881868 + 30 +0.0 + 10 +23.331804464143122 + 20 +9.71546387255219 + 30 +0.0 + 10 +22.6756710802557 + 20 +9.621868691197067 + 30 +0.0 + 10 +22.289394430288276 + 20 +9.524711685749468 + 30 +0.0 + 10 +21.844908275873465 + 20 +9.361892041050062 + 30 +0.0 + 10 +21.251453010956368 + 20 +9.263646772452677 + 30 +0.0 + 10 +20.892708756526186 + 20 +9.36753521855753 + 30 +0.0 + 10 +19.858921274746674 + 20 +11.396457390757543 + 30 +0.0 + 10 +19.985738338427453 + 20 +11.747751685729936 + 30 +0.0 + 10 +20.41404468295316 + 20 +12.17011996046022 + 30 +0.0 + 10 +20.807030948946252 + 20 +12.434013827208174 + 30 +0.0 + 10 +21.112680335631794 + 20 +12.689410746603121 + 30 +0.0 + 10 +21.574065954525462 + 20 +13.16521993745859 + 30 +0.0 + 10 +22.146440738952442 + 20 +13.894717148814422 + 30 +0.0 + 10 +22.78003586221242 + 20 +14.904038878094434 + 30 +0.0 + 10 +23.15244701695013 + 20 +15.663611175312264 + 30 +0.0 + 10 +22.66159345122129 + 20 +16.464611394680045 + 30 +0.0 + 10 +22.051479066597466 + 20 +17.178963557195875 + 30 +0.0 + 10 +21.214001508021703 + 20 +17.059500250038198 + 30 +0.0 + 10 +20.058287839711646 + 20 +16.768813046508523 + 30 +0.0 + 10 +19.187621227693203 + 20 +16.449879313674398 + 30 +0.0 + 10 +18.59252379901862 + 20 +16.158108640354822 + 30 +0.0 + 10 +18.255176039780327 + 20 +15.946340787850007 + 30 +0.0 + 10 +17.882758623451352 + 20 +15.654136328299233 + 30 +0.0 + 10 +17.34870858423581 + 20 +15.377311763143853 + 30 +0.0 + 10 +16.97541922801093 + 20 +15.365257475526354 + 30 +0.0 + 10 +15.365257475526228 + 20 +16.97541922801094 + 30 +0.0 + 10 +15.377311763143814 + 20 +17.348708584235837 + 30 +0.0 + 10 +15.654136328299064 + 20 +17.882758623451465 + 30 +0.0 + 10 +15.946340787849858 + 20 +18.255176039780256 + 30 +0.0 + 10 +16.158108640354712 + 20 +18.592523799018643 + 30 +0.0 + 10 +16.449879313674277 + 20 +19.187621227693203 + 30 +0.0 + 10 +16.768813046508505 + 20 +20.058287839711944 + 30 +0.0 + 10 +17.0595002500383 + 20 +21.214001508022417 + 30 +0.0 + 10 +17.17896355719588 + 20 +22.051479066597462 + 30 +0.0 + 10 +16.46461139468005 + 20 +22.66159345122129 + 30 +0.0 + 10 +15.663611175312262 + 20 +23.152447016950127 + 30 +0.0 + 10 +14.904038878093784 + 20 +22.7800358622121 + 30 +0.0 + 10 +13.894717148814129 + 20 +22.146440738952364 + 30 +0.0 + 10 +13.165219937458549 + 20 +21.574065954525576 + 30 +0.0 + 10 +12.689410746603064 + 20 +21.112680335631886 + 30 +0.0 + 10 +12.434013827208195 + 20 +20.80703094894641 + 30 +0.0 + 10 +12.170119960460056 + 20 +20.414044682953282 + 30 +0.0 + 10 +11.747751685729895 + 20 +19.98573833842747 + 30 +0.0 + 10 +11.396457390757496 + 20 +19.858921274746784 + 30 +0.0 + 10 +9.367535218557409 + 20 +20.892708756526158 + 30 +0.0 + 10 +9.263646772452635 + 20 +21.251453010956382 + 30 +0.0 + 10 +9.361892041049868 + 20 +21.84490827587352 + 30 +0.0 + 10 +9.52471168574935 + 20 +22.289394430288162 + 30 +0.0 + 10 +9.621868691196953 + 20 +22.675671080255682 + 30 +0.0 + 10 +9.715463872552077 + 20 +23.331804464143083 + 30 +0.0 + 10 +9.749737097881754 + 20 +24.258413562549343 + 30 +0.0 + 10 +9.669061892863036 + 20 +25.447389863705432 + 30 +0.0 + 10 +9.523883451586089 + 20 +26.280794545155107 + 30 +0.0 + 10 +8.655958459134501 + 20 +26.640300848151124 + 30 +0.0 + 10 +7.7424798873911715 + 20 +26.85960765010154 + 30 +0.0 + 10 +7.135165080233108 + 20 +26.27070284635001 + 30 +0.0 + 10 +6.3710347332037465 + 20 +25.356220508541686 + 30 +0.0 + 10 +5.854115192264454 + 20 +24.586432704391544 + 30 +0.0 + 10 +5.544169757986573 + 20 +24.000595778963696 + 30 +0.0 + 10 +5.395723708360467 + 20 +23.63098394965083 + 30 +0.0 + 10 +5.266185161527155 + 20 +23.17568411102707 + 30 +0.0 + 10 +4.99684300082578 + 20 +22.637821596318798 + 30 +0.0 + 10 +4.701930900309029 + 20 +22.408655494354424 + 30 +0.0 + 10 +2.4528533469405125 + 20 +22.764874383891094 + 30 +0.0 + 10 +2.243191492051479 + 20 +23.073957149384828 + 30 +0.0 + 10 +2.1532405326853645 + 20 +23.668726103827414 + 30 +0.0 + 10 +2.170737441279177 + 20 +24.14177159461666 + 30 +0.0 + 10 +2.143773195043655 + 20 +24.539165685466823 + 30 +0.0 + 10 +2.0300311359673238 + 20 +25.192108117402064 + 30 +0.0 + 10 +1.7762889517015847 + 20 +26.08395674757863 + 30 +0.0 + 10 +1.3321483892987884 + 20 +27.189810397138167 + 30 +0.0 + 10 +0.9365392769371852 + 20 +27.93756274457033 + 30 +0.0 + 10 +1.8375180724919756e-15 + 20 +28.01126998417358 + 30 +0.0 + 10 +-0.9365392769371813 + 20 +27.937562744570332 + 30 +0.0 + 10 +-1.3321483892991253 + 20 +27.18981039713753 + 30 +0.0 + 10 +-1.7762889517017733 + 20 +26.0839567475784 + 30 +0.0 + 10 +-2.0300311359674192 + 20 +25.19210811740213 + 30 +0.0 + 10 +-2.1437731950437553 + 20 +24.53916568546687 + 30 +0.0 + 10 +-2.170737441279249 + 20 +24.141771594616806 + 30 +0.0 + 10 +-2.153240532685563 + 20 +23.668726103827417 + 30 +0.0 + 10 +-2.2431914920515212 + 20 +23.073957149384825 + 30 +0.0 + 10 +-2.4528533469406146 + 20 +22.764874383891158 + 30 +0.0 + 10 +-4.701930900309106 + 20 +22.40865549435433 + 30 +0.0 + 10 +-4.996843000825821 + 20 +22.63782159631879 + 30 +0.0 + 10 +-5.266185161527344 + 20 +23.175684111027007 + 30 +0.0 + 10 +-5.395723708360491 + 20 +23.63098394965067 + 30 +0.0 + 10 +-5.544169757986655 + 20 +24.00059577896362 + 30 +0.0 + 10 +-5.8541151922645245 + 20 +24.586432704391452 + 30 +0.0 + 10 +-6.371034733203998 + 20 +25.35622050854185 + 30 +0.0 + 10 +-7.135165080233627 + 20 +26.270702846350513 + 30 +0.0 + 10 +-7.742479887391169 + 20 +26.859607650101545 + 30 +0.0 + 10 +-8.655958459134498 + 20 +26.640300848151124 + 30 +0.0 + 10 +-9.523883451586087 + 20 +26.28079454515511 + 30 +0.0 + 10 +-9.66906189286316 + 20 +25.44738986370472 + 30 +0.0 + 10 +-9.749737097881866 + 20 +24.25841356254907 + 30 +0.0 + 10 +-9.71546387255219 + 20 +23.331804464143122 + 30 +0.0 + 10 +-9.621868691197063 + 20 +22.675671080255697 + 30 +0.0 + 10 +-9.524711685749464 + 20 +22.289394430288276 + 30 +0.0 + 10 +-9.36189204105006 + 20 +21.844908275873465 + 30 +0.0 + 10 +-9.263646772452676 + 20 +21.251453010956368 + 30 +0.0 + 10 +-9.367535218557526 + 20 +20.892708756526186 + 30 +0.0 + 10 +-11.396457390757542 + 20 +19.858921274746674 + 30 +0.0 + 10 +-11.747751685729932 + 20 +19.985738338427453 + 30 +0.0 + 10 +-12.170119960460216 + 20 +20.41404468295316 + 30 +0.0 + 10 +-12.43401382720817 + 20 +20.807030948946252 + 30 +0.0 + 10 +-12.68941074660312 + 20 +21.112680335631794 + 30 +0.0 + 10 +-13.165219937458588 + 20 +21.574065954525462 + 30 +0.0 + 10 +-13.894717148814419 + 20 +22.146440738952442 + 30 +0.0 + 10 +-14.90403887809443 + 20 +22.78003586221242 + 30 +0.0 + 10 +-15.66361117531226 + 20 +23.15244701695013 + 30 +0.0 + 10 +-16.464611394680045 + 20 +22.661593451221293 + 30 +0.0 + 10 +-17.17896355719587 + 20 +22.051479066597466 + 30 +0.0 + 10 +-17.059500250038198 + 20 +21.214001508021703 + 30 +0.0 + 10 +-16.76881304650852 + 20 +20.05828783971165 + 30 +0.0 + 10 +-16.449879313674394 + 20 +19.187621227693207 + 30 +0.0 + 10 +-16.15810864035482 + 20 +18.592523799018622 + 30 +0.0 + 10 +-15.946340787850001 + 20 +18.25517603978033 + 30 +0.0 + 10 +-15.654136328299229 + 20 +17.882758623451355 + 30 +0.0 + 10 +-15.377311763143847 + 20 +17.34870858423581 + 30 +0.0 + 10 +-15.365257475526349 + 20 +16.97541922801093 + 30 +0.0 + 10 +-16.975419228010935 + 20 +15.36525747552623 + 30 +0.0 + 10 +-17.348708584235833 + 20 +15.377311763143817 + 30 +0.0 + 10 +-17.882758623451465 + 20 +15.654136328299066 + 30 +0.0 + 10 +-18.255176039780252 + 20 +15.94634078784986 + 30 +0.0 + 10 +-18.59252379901864 + 20 +16.158108640354715 + 30 +0.0 + 10 +-19.187621227693203 + 20 +16.44987931367428 + 30 +0.0 + 10 +-20.05828783971194 + 20 +16.768813046508505 + 30 +0.0 + 10 +-21.214001508022413 + 20 +17.059500250038305 + 30 +0.0 + 10 +-22.05147906659746 + 20 +17.178963557195882 + 30 +0.0 + 10 +-22.661593451221286 + 20 +16.46461139468005 + 30 +0.0 + 10 +-23.152447016950127 + 20 +15.663611175312264 + 30 +0.0 + 10 +-22.7800358622121 + 20 +14.904038878093786 + 30 +0.0 + 10 +-22.146440738952364 + 20 +13.89471714881413 + 30 +0.0 + 10 +-21.574065954525572 + 20 +13.16521993745855 + 30 +0.0 + 10 +-21.112680335631886 + 20 +12.689410746603066 + 30 +0.0 + 10 +-20.80703094894641 + 20 +12.434013827208197 + 30 +0.0 + 10 +-20.414044682953282 + 20 +12.170119960460058 + 30 +0.0 + 10 +-19.98573833842747 + 20 +11.747751685729897 + 30 +0.0 + 10 +-19.85892127474678 + 20 +11.396457390757496 + 30 +0.0 + 10 +-20.892708756526158 + 20 +9.36753521855741 + 30 +0.0 + 10 +-21.251453010956382 + 20 +9.263646772452637 + 30 +0.0 + 10 +-21.84490827587352 + 20 +9.36189204104987 + 30 +0.0 + 10 +-22.289394430288162 + 20 +9.524711685749352 + 30 +0.0 + 10 +-22.675671080255682 + 20 +9.621868691196953 + 30 +0.0 + 10 +-23.331804464143083 + 20 +9.715463872552077 + 30 +0.0 + 10 +-24.258413562549343 + 20 +9.749737097881757 + 30 +0.0 + 10 +-25.447389863705432 + 20 +9.669061892863038 + 30 +0.0 + 10 +-26.280794545155107 + 20 +9.523883451586093 + 30 +0.0 + 10 +-26.640300848151124 + 20 +8.655958459134503 + 30 +0.0 + 10 +-26.85960765010154 + 20 +7.742479887391173 + 30 +0.0 + 10 +-26.27070284635001 + 20 +7.13516508023311 + 30 +0.0 + 10 +-25.356220508541686 + 20 +6.371034733203747 + 30 +0.0 + 10 +-24.586432704391544 + 20 +5.854115192264455 + 30 +0.0 + 10 +-24.000595778963696 + 20 +5.544169757986574 + 30 +0.0 + 10 +-23.63098394965083 + 20 +5.395723708360468 + 30 +0.0 + 10 +-23.17568411102707 + 20 +5.266185161527156 + 30 +0.0 + 10 +-22.637821596318798 + 20 +4.9968430008257805 + 30 +0.0 + 10 +-22.408655494354424 + 20 +4.70193090030903 + 30 +0.0 + 10 +-22.764874383891094 + 20 +2.452853346940514 + 30 +0.0 + 10 +-23.073957149384828 + 20 +2.2431914920514804 + 30 +0.0 + 10 +-23.668726103827414 + 20 +2.1532405326853663 + 30 +0.0 + 10 +-24.14177159461666 + 20 +2.170737441279179 + 30 +0.0 + 10 +-24.539165685466823 + 20 +2.1437731950436567 + 30 +0.0 + 10 +-25.192108117402064 + 20 +2.0300311359673255 + 30 +0.0 + 10 +-26.08395674757863 + 20 +1.7762889517015863 + 30 +0.0 + 10 +-27.189810397138167 + 20 +1.3321483892987902 + 30 +0.0 + 10 +-27.93756274457033 + 20 +0.936539276937187 + 30 +0.0 + 10 +-28.01126998417358 + 20 +-8.820622963909527e-15 + 30 +0.0 + 10 +-27.937562744570332 + 20 +-0.9365392769371929 + 30 +0.0 + 10 +-27.18981039713753 + 20 +-1.3321483892991368 + 30 +0.0 + 10 +-26.083956747578398 + 20 +-1.776288951701784 + 30 +0.0 + 10 +-25.192108117402135 + 20 +-2.03003113596743 + 30 +0.0 + 10 +-24.53916568546687 + 20 +-2.143773195043765 + 30 +0.0 + 10 +-24.141771594616806 + 20 +-2.170737441279258 + 30 +0.0 + 10 +-23.66872610382742 + 20 +-2.153240532685573 + 30 +0.0 + 10 +-23.07395714938482 + 20 +-2.24319149205153 + 30 +0.0 + 10 +-22.764874383891158 + 20 +-2.4528533469406244 + 30 +0.0 + 10 +-22.40865549435433 + 20 +-4.701930900309116 + 30 +0.0 + 10 +-22.637821596318787 + 20 +-4.99684300082583 + 30 +0.0 + 10 +-23.175684111027007 + 20 +-5.266185161527353 + 30 +0.0 + 10 +-23.630983949650673 + 20 +-5.395723708360501 + 30 +0.0 + 10 +-24.00059577896362 + 20 +-5.544169757986665 + 30 +0.0 + 10 +-24.58643270439145 + 20 +-5.854115192264534 + 30 +0.0 + 10 +-25.356220508541846 + 20 +-6.371034733204007 + 30 +0.0 + 10 +-26.27070284635051 + 20 +-7.135165080233637 + 30 +0.0 + 10 +-26.85960765010154 + 20 +-7.7424798873911795 + 30 +0.0 + 10 +-26.640300848151124 + 20 +-8.655958459134498 + 30 +0.0 + 10 +-26.28079454515511 + 20 +-9.523883451586087 + 30 +0.0 + 10 +-25.44738986370472 + 20 +-9.66906189286316 + 30 +0.0 + 10 +-24.25841356254907 + 20 +-9.749737097881866 + 30 +0.0 + 10 +-23.331804464143122 + 20 +-9.71546387255219 + 30 +0.0 + 10 +-22.675671080255697 + 20 +-9.621868691197063 + 30 +0.0 + 10 +-22.289394430288276 + 20 +-9.524711685749464 + 30 +0.0 + 10 +-21.844908275873465 + 20 +-9.36189204105006 + 30 +0.0 + 10 +-21.251453010956368 + 20 +-9.263646772452676 + 30 +0.0 + 10 +-20.892708756526186 + 20 +-9.367535218557526 + 30 +0.0 + 10 +-19.858921274746674 + 20 +-11.396457390757542 + 30 +0.0 + 10 +-19.985738338427453 + 20 +-11.747751685729932 + 30 +0.0 + 10 +-20.41404468295316 + 20 +-12.170119960460216 + 30 +0.0 + 10 +-20.807030948946252 + 20 +-12.43401382720817 + 30 +0.0 + 10 +-21.112680335631794 + 20 +-12.68941074660312 + 30 +0.0 + 10 +-21.574065954525462 + 20 +-13.165219937458588 + 30 +0.0 + 10 +-22.146440738952442 + 20 +-13.894717148814419 + 30 +0.0 + 10 +-22.78003586221242 + 20 +-14.90403887809443 + 30 +0.0 + 10 +-23.15244701695013 + 20 +-15.66361117531226 + 30 +0.0 + 10 +-22.661593451221293 + 20 +-16.464611394680045 + 30 +0.0 + 10 +-22.051479066597466 + 20 +-17.17896355719587 + 30 +0.0 + 10 +-21.214001508021703 + 20 +-17.059500250038198 + 30 +0.0 + 10 +-20.05828783971165 + 20 +-16.76881304650852 + 30 +0.0 + 10 +-19.187621227693207 + 20 +-16.449879313674394 + 30 +0.0 + 10 +-18.592523799018622 + 20 +-16.15810864035482 + 30 +0.0 + 10 +-18.25517603978033 + 20 +-15.946340787850001 + 30 +0.0 + 10 +-17.882758623451355 + 20 +-15.654136328299229 + 30 +0.0 + 10 +-17.34870858423581 + 20 +-15.377311763143847 + 30 +0.0 + 10 +-16.97541922801093 + 20 +-15.365257475526349 + 30 +0.0 + 10 +-15.36525747552623 + 20 +-16.975419228010935 + 30 +0.0 + 10 +-15.377311763143817 + 20 +-17.348708584235833 + 30 +0.0 + 10 +-15.654136328299066 + 20 +-17.882758623451465 + 30 +0.0 + 10 +-15.94634078784986 + 20 +-18.255176039780252 + 30 +0.0 + 10 +-16.158108640354715 + 20 +-18.59252379901864 + 30 +0.0 + 10 +-16.44987931367428 + 20 +-19.187621227693203 + 30 +0.0 + 10 +-16.768813046508505 + 20 +-20.05828783971194 + 30 +0.0 + 10 +-17.059500250038305 + 20 +-21.214001508022413 + 30 +0.0 + 10 +-17.178963557195882 + 20 +-22.05147906659746 + 30 +0.0 + 10 +-16.46461139468005 + 20 +-22.661593451221286 + 30 +0.0 + 10 +-15.663611175312264 + 20 +-23.152447016950127 + 30 +0.0 + 10 +-14.904038878093786 + 20 +-22.7800358622121 + 30 +0.0 + 10 +-13.894717148814133 + 20 +-22.146440738952364 + 30 +0.0 + 10 +-13.16521993745855 + 20 +-21.574065954525572 + 30 +0.0 + 10 +-12.689410746603068 + 20 +-21.112680335631886 + 30 +0.0 + 10 +-12.434013827208199 + 20 +-20.80703094894641 + 30 +0.0 + 10 +-12.170119960460058 + 20 +-20.414044682953282 + 30 +0.0 + 10 +-11.747751685729897 + 20 +-19.98573833842747 + 30 +0.0 + 10 +-11.396457390757496 + 20 +-19.85892127474678 + 30 +0.0 + 10 +-9.367535218557412 + 20 +-20.892708756526158 + 30 +0.0 + 10 +-9.263646772452638 + 20 +-21.251453010956382 + 30 +0.0 + 10 +-9.361892041049872 + 20 +-21.84490827587352 + 30 +0.0 + 10 +-9.524711685749352 + 20 +-22.289394430288162 + 30 +0.0 + 10 +-9.621868691196955 + 20 +-22.675671080255682 + 30 +0.0 + 10 +-9.715463872552078 + 20 +-23.331804464143083 + 30 +0.0 + 10 +-9.749737097881757 + 20 +-24.258413562549343 + 30 +0.0 + 10 +-9.66906189286304 + 20 +-25.447389863705432 + 30 +0.0 + 10 +-9.523883451586093 + 20 +-26.280794545155107 + 30 +0.0 + 10 +-8.655958459134505 + 20 +-26.640300848151124 + 30 +0.0 + 10 +-7.742479887391175 + 20 +-26.85960765010154 + 30 +0.0 + 10 +-7.135165080233111 + 20 +-26.27070284635001 + 30 +0.0 + 10 +-6.371034733203749 + 20 +-25.356220508541686 + 30 +0.0 + 10 +-5.854115192264457 + 20 +-24.586432704391544 + 30 +0.0 + 10 +-5.544169757986576 + 20 +-24.000595778963696 + 30 +0.0 + 10 +-5.39572370836047 + 20 +-23.63098394965083 + 30 +0.0 + 10 +-5.266185161527158 + 20 +-23.17568411102707 + 30 +0.0 + 10 +-4.996843000825782 + 20 +-22.637821596318798 + 30 +0.0 + 10 +-4.701930900309032 + 20 +-22.408655494354424 + 30 +0.0 + 10 +-2.452853346940515 + 20 +-22.764874383891094 + 30 +0.0 + 10 +-2.243191492051482 + 20 +-23.073957149384828 + 30 +0.0 + 10 +-2.1532405326853676 + 20 +-23.668726103827414 + 30 +0.0 + 10 +-2.1707374412791802 + 20 +-24.14177159461666 + 30 +0.0 + 10 +-2.143773195043658 + 20 +-24.539165685466823 + 30 +0.0 + 10 +-2.030031135967327 + 20 +-25.192108117402064 + 30 +0.0 + 10 +-1.776288951701588 + 20 +-26.08395674757863 + 30 +0.0 + 10 +-1.3321483892987918 + 20 +-27.189810397138167 + 30 +0.0 + 10 +-0.9365392769371886 + 20 +-27.93756274457033 + 30 +0.0 + 10 +-5.3902317512924765e-15 + 20 +-28.01126998417358 + 30 +0.0 + 10 +0.9365392769371778 + 20 +-27.937562744570332 + 30 +0.0 + 10 +1.3321483892991217 + 20 +-27.189810397137528 + 30 +0.0 + 10 +1.7762889517017697 + 20 +-26.0839567475784 + 30 +0.0 + 10 +2.0300311359674166 + 20 +-25.19210811740213 + 30 +0.0 + 10 +2.1437731950437526 + 20 +-24.53916568546687 + 30 +0.0 + 10 +2.1707374412792464 + 20 +-24.141771594616806 + 30 +0.0 + 10 +2.1532405326855604 + 20 +-23.668726103827417 + 30 +0.0 + 10 +2.2431914920515186 + 20 +-23.073957149384825 + 30 +0.0 + 10 +2.452853346940612 + 20 +-22.764874383891158 + 30 +0.0 + 10 +4.7019309003091045 + 20 +-22.40865549435433 + 30 +0.0 + 10 +4.996843000825819 + 20 +-22.63782159631879 + 30 +0.0 + 10 +5.266185161527341 + 20 +-23.175684111027007 + 30 +0.0 + 10 +5.395723708360489 + 20 +-23.63098394965067 + 30 +0.0 + 10 +5.544169757986651 + 20 +-24.00059577896362 + 30 +0.0 + 10 +5.854115192264522 + 20 +-24.586432704391452 + 30 +0.0 + 10 +6.371034733203994 + 20 +-25.35622050854185 + 30 +0.0 + 10 +7.135165080233623 + 20 +-26.270702846350513 + 30 +0.0 + 10 +7.742479887391165 + 20 +-26.859607650101545 + 30 +0.0 + 10 +8.655958459134494 + 20 +-26.640300848151128 + 30 +0.0 + 10 +9.523883451586082 + 20 +-26.280794545155114 + 30 +0.0 + 10 +9.669061892863159 + 20 +-25.44738986370472 + 30 +0.0 + 10 +9.74973709788186 + 20 +-24.258413562549073 + 30 +0.0 + 10 +9.715463872552185 + 20 +-23.331804464143122 + 30 +0.0 + 10 +9.62186869119706 + 20 +-22.675671080255697 + 30 +0.0 + 10 +9.52471168574946 + 20 +-22.289394430288276 + 30 +0.0 + 10 +9.361892041050059 + 20 +-21.844908275873465 + 30 +0.0 + 10 +9.263646772452672 + 20 +-21.251453010956368 + 30 +0.0 + 10 +9.367535218557524 + 20 +-20.892708756526186 + 30 +0.0 + 10 +11.396457390757538 + 20 +-19.858921274746674 + 30 +0.0 + 10 +11.747751685729929 + 20 +-19.985738338427456 + 30 +0.0 + 10 +12.170119960460214 + 20 +-20.41404468295316 + 30 +0.0 + 10 +12.434013827208169 + 20 +-20.807030948946252 + 30 +0.0 + 10 +12.689410746603116 + 20 +-21.112680335631794 + 30 +0.0 + 10 +13.165219937458584 + 20 +-21.574065954525466 + 30 +0.0 + 10 +13.894717148814413 + 20 +-22.146440738952442 + 30 +0.0 + 10 +14.90403887809443 + 20 +-22.78003586221242 + 30 +0.0 + 10 +15.663611175312257 + 20 +-23.15244701695013 + 30 +0.0 + 10 +16.46461139468004 + 20 +-22.661593451221293 + 30 +0.0 + 10 +17.17896355719587 + 20 +-22.05147906659747 + 30 +0.0 + 10 +17.059500250038198 + 20 +-21.214001508021706 + 30 +0.0 + 10 +16.76881304650852 + 20 +-20.05828783971165 + 30 +0.0 + 10 +16.449879313674394 + 20 +-19.187621227693207 + 30 +0.0 + 10 +16.15810864035482 + 20 +-18.592523799018622 + 30 +0.0 + 10 +15.946340787850001 + 20 +-18.25517603978033 + 30 +0.0 + 10 +15.654136328299227 + 20 +-17.88275862345136 + 30 +0.0 + 10 +15.377311763143847 + 20 +-17.348708584235812 + 30 +0.0 + 10 +15.365257475526349 + 20 +-16.975419228010935 + 30 +0.0 + 10 +16.975419228010935 + 20 +-15.365257475526233 + 30 +0.0 + 10 +17.348708584235833 + 20 +-15.377311763143819 + 30 +0.0 + 10 +17.882758623451465 + 20 +-15.654136328299069 + 30 +0.0 + 10 +18.255176039780252 + 20 +-15.946340787849863 + 30 +0.0 + 10 +18.59252379901864 + 20 +-16.158108640354715 + 30 +0.0 + 10 +19.187621227693203 + 20 +-16.44987931367428 + 30 +0.0 + 10 +20.05828783971194 + 20 +-16.76881304650851 + 30 +0.0 + 10 +21.214001508022413 + 20 +-17.059500250038305 + 30 +0.0 + 10 +22.05147906659746 + 20 +-17.178963557195882 + 30 +0.0 + 10 +22.661593451221286 + 20 +-16.464611394680052 + 30 +0.0 + 10 +23.152447016950127 + 20 +-15.663611175312266 + 30 +0.0 + 10 +22.7800358622121 + 20 +-14.904038878093788 + 30 +0.0 + 10 +22.146440738952364 + 20 +-13.894717148814134 + 30 +0.0 + 10 +21.574065954525572 + 20 +-13.165219937458554 + 30 +0.0 + 10 +21.112680335631886 + 20 +-12.689410746603068 + 30 +0.0 + 10 +20.80703094894641 + 20 +-12.434013827208199 + 30 +0.0 + 10 +20.41404468295328 + 20 +-12.17011996046006 + 30 +0.0 + 10 +19.98573833842747 + 20 +-11.747751685729899 + 30 +0.0 + 10 +19.85892127474678 + 20 +-11.396457390757499 + 30 +0.0 + 10 +20.892708756526158 + 20 +-9.367535218557412 + 30 +0.0 + 10 +21.251453010956382 + 20 +-9.263646772452638 + 30 +0.0 + 10 +21.84490827587352 + 20 +-9.361892041049874 + 30 +0.0 + 10 +22.28939443028816 + 20 +-9.524711685749354 + 30 +0.0 + 10 +22.675671080255682 + 20 +-9.621868691196957 + 30 +0.0 + 10 +23.331804464143083 + 20 +-9.71546387255208 + 30 +0.0 + 10 +24.258413562549343 + 20 +-9.749737097881761 + 30 +0.0 + 10 +25.447389863705432 + 20 +-9.669061892863041 + 30 +0.0 + 10 +26.280794545155107 + 20 +-9.523883451586096 + 30 +0.0 + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +31 + 70 +1 + 10 +0.10395584540887969 + 20 +-0.48907380036690284 + 30 +0.0 + 10 +3.061616997868383e-17 + 20 +-0.5 + 30 +0.0 + 10 +-0.10395584540887946 + 20 +-0.48907380036690284 + 30 +0.0 + 10 +-0.20336832153790005 + 20 +-0.4567727288213005 + 30 +0.0 + 10 +-0.2938926261462367 + 20 +-0.40450849718747367 + 30 +0.0 + 10 +-0.371572412738697 + 20 +-0.33456530317942923 + 30 +0.0 + 10 +-0.4330127018922193 + 20 +-0.25000000000000006 + 30 +0.0 + 10 +-0.4755282581475768 + 20 +-0.15450849718747364 + 30 +0.0 + 10 +-0.4972609476841367 + 20 +-0.05226423163382652 + 30 +0.0 + 10 +-0.49726094768413664 + 20 +0.05226423163382709 + 30 +0.0 + 10 +-0.47552825814757677 + 20 +0.15450849718747375 + 30 +0.0 + 10 +-0.43301270189221924 + 20 +0.2500000000000002 + 30 +0.0 + 10 +-0.371572412738697 + 20 +0.33456530317942923 + 30 +0.0 + 10 +-0.2938926261462365 + 20 +0.4045084971874737 + 30 +0.0 + 10 +-0.20336832153790013 + 20 +0.45677272882130043 + 30 +0.0 + 10 +-0.10395584540887956 + 20 +0.48907380036690284 + 30 +0.0 + 10 +2.5266077490371514e-16 + 20 +0.5 + 30 +0.0 + 10 +0.10395584540887963 + 20 +0.48907380036690284 + 30 +0.0 + 10 +0.2033683215379 + 20 +0.4567727288213005 + 30 +0.0 + 10 +0.2938926261462366 + 20 +0.40450849718747367 + 30 +0.0 + 10 +0.37157241273869723 + 20 +0.33456530317942895 + 30 +0.0 + 10 +0.43301270189221935 + 20 +0.24999999999999992 + 30 +0.0 + 10 +0.4755282581475768 + 20 +0.1545084971874737 + 30 +0.0 + 10 +0.4972609476841367 + 20 +0.052264231633826694 + 30 +0.0 + 10 +0.49726094768413664 + 20 +-0.0522642316338267 + 30 +0.0 + 10 +0.47552825814757677 + 20 +-0.1545084971874737 + 30 +0.0 + 10 +0.4330127018922193 + 20 +-0.25000000000000006 + 30 +0.0 + 10 +0.3715724127386971 + 20 +-0.3345653031794291 + 30 +0.0 + 10 +0.29389262614623657 + 20 +-0.4045084971874737 + 30 +0.0 + 10 +0.2033683215379001 + 20 +-0.45677272882130043 + 30 +0.0 + 10 +0.10395584540887969 + 20 +-0.48907380036690284 + 30 +0.0 + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +229 + 70 +1 + 10 +23.81530623244595 + 20 +5.409238575089372 + 30 +0.0 + 10 +23.525696001154003 + 20 +4.613541004171724 + 30 +0.0 + 10 +23.37865703318989 + 20 +3.7796415783815007 + 30 +0.0 + 10 +23.815064262404334 + 20 +3.2797006347076385 + 30 +0.0 + 10 +24.914724146445984 + 20 +2.392966048474426 + 30 +0.0 + 10 +25.765074125408955 + 20 +1.923901530707663 + 30 +0.0 + 10 +26.26621765827511 + 20 +1.7525003477700496 + 30 +0.0 + 10 +26.353307623573798 + 20 +1.7388908869047492 + 30 +0.0 + 10 +26.612595397835335 + 20 +1.7439522167197854 + 30 +0.0 + 10 +27.593174035472252 + 20 +1.5451382157093896 + 30 +0.0 + 10 +28.061269984173578 + 20 +1.1385562939891836 + 30 +0.0 + 10 +28.06126998417357 + 20 +-1.1385562939891605 + 30 +0.0 + 10 +27.59317403547235 + 20 +-1.545138215709939 + 30 +0.0 + 10 +26.612595397835335 + 20 +-1.7439522167197963 + 30 +0.0 + 10 +26.353307623573812 + 20 +-1.738890886904766 + 30 +0.0 + 10 +26.266217658275092 + 20 +-1.7525003477700343 + 30 +0.0 + 10 +25.765074125408923 + 20 +-1.9239015307076544 + 30 +0.0 + 10 +24.91472414644604 + 20 +-2.3929660484743827 + 30 +0.0 + 10 +23.81506426240434 + 20 +-3.2797006347076323 + 30 +0.0 + 10 +23.378657033189892 + 20 +-3.7796415783815043 + 30 +0.0 + 10 +23.525696001154 + 20 +-4.61354100417172 + 30 +0.0 + 10 +23.815306232445945 + 20 +-5.409238575089366 + 30 +0.0 + 10 +24.44321645117776 + 20 +-5.623996518095676 + 30 +0.0 + 10 +25.83891713939709 + 20 +-5.842101254167094 + 30 +0.0 + 10 +26.809874082169966 + 20 +-5.823148053085523 + 30 +0.0 + 10 +27.329577704043146 + 20 +-5.7210140653151225 + 30 +0.0 + 10 +27.411804556839165 + 20 +-5.689255221506937 + 30 +0.0 + 10 +27.633823691332857 + 20 +-5.555228094179418 + 30 +0.0 + 10 +28.582436702439963 + 20 +-5.2371167508639855 + 30 +0.0 + 10 +29.19111064628399 + 20 +-5.355179049442518 + 30 +0.0 + 10 +30.329666940273157 + 20 +-7.327216397909096 + 30 +0.0 + 10 +30.12757491814972 + 20 +-7.913374645189394 + 30 +0.0 + 10 +29.37777590805265 + 20 +-8.575841939510466 + 30 +0.0 + 10 +29.150695443743935 + 20 +-8.701102586444478 + 30 +0.0 + 10 +29.08207805181317 + 20 +-8.75643370793497 + 30 +0.0 + 10 +28.733775612877597 + 20 +-9.155443253030738 + 30 +0.0 + 10 +28.231883187871542 + 20 +-9.986840030912063 + 30 +0.0 + 10 +27.722917085885406 + 20 +-11.304604651025187 + 30 +0.0 + 10 +27.594947810827446 + 20 +-11.955769823245953 + 30 +0.0 + 10 +28.13923700532572 + 20 +-12.604428426199485 + 30 +0.0 + 10 +28.787895608279257 + 20 +-13.148717620697763 + 30 +0.0 + 10 +29.439060780500007 + 20 +-13.020748345639806 + 30 +0.0 + 10 +30.756825400613074 + 20 +-12.511782243653693 + 30 +0.0 + 10 +31.588222178494476 + 20 +-12.00988981864758 + 30 +0.0 + 10 +31.98723172359023 + 20 +-11.661587379712014 + 30 +0.0 + 10 +32.04256284508074 + 20 +-11.592969987781292 + 30 +0.0 + 10 +32.16782349201475 + 20 +-11.365889523472562 + 30 +0.0 + 10 +32.830290786336235 + 20 +-10.61609051337585 + 30 +0.0 + 10 +33.41644903361609 + 20 +-10.41399849125203 + 30 +0.0 + 10 +35.38848638208266 + 20 +-11.552554785241211 + 30 +0.0 + 10 +35.506548680661744 + 20 +-12.161228729085428 + 30 +0.0 + 10 +35.188437337345796 + 20 +-13.109841740192353 + 30 +0.0 + 10 +35.05441021001829 + 20 +-13.33186087468604 + 30 +0.0 + 10 +35.02265136621006 + 20 +-13.41408772748207 + 30 +0.0 + 10 +34.92051737843966 + 20 +-13.933791349355264 + 30 +0.0 + 10 +34.901564177358104 + 20 +-14.90474829212805 + 30 +0.0 + 10 +35.11966891342953 + 20 +-16.300448980347433 + 30 +0.0 + 10 +35.33442685643584 + 20 +-16.92835919907926 + 30 +0.0 + 10 +36.13012442735348 + 20 +-17.217969430371205 + 30 +0.0 + 10 +36.96402385314371 + 20 +-17.36500839833532 + 30 +0.0 + 10 +37.46396479681757 + 20 +-16.928601169120874 + 30 +0.0 + 10 +38.35069938305078 + 20 +-15.828941285079226 + 30 +0.0 + 10 +38.81976390081754 + 20 +-14.978591306116254 + 30 +0.0 + 10 +38.991165083755156 + 20 +-14.4774477732501 + 30 +0.0 + 10 +39.00477454462046 + 20 +-14.390357807951409 + 30 +0.0 + 10 +38.999713214805425 + 20 +-14.131070033689875 + 30 +0.0 + 10 +39.198527215815815 + 20 +-13.150491396052955 + 30 +0.0 + 10 +39.605109137536026 + 20 +-12.682395447351631 + 30 +0.0 + 10 +41.88222172551437 + 20 +-12.682395447351642 + 30 +0.0 + 10 +42.28880364723515 + 20 +-13.150491396052855 + 30 +0.0 + 10 +42.487617648245006 + 20 +-14.131070033689875 + 30 +0.0 + 10 +42.48255631842997 + 20 +-14.390357807951396 + 30 +0.0 + 10 +42.49616577929524 + 20 +-14.477447773250116 + 30 +0.0 + 10 +42.66756696223286 + 20 +-14.978591306116286 + 30 +0.0 + 10 +43.13663147999959 + 20 +-15.828941285079168 + 30 +0.0 + 10 +44.02336606623284 + 20 +-16.928601169120867 + 30 +0.0 + 10 +44.52330700990671 + 20 +-17.365008398335316 + 30 +0.0 + 10 +45.357206435696924 + 20 +-17.21796943037121 + 30 +0.0 + 10 +46.15290400661457 + 20 +-16.928359199079264 + 30 +0.0 + 10 +46.36766194962088 + 20 +-16.300448980347443 + 30 +0.0 + 10 +46.5857666856923 + 20 +-14.90474829212812 + 30 +0.0 + 10 +46.566813484610734 + 20 +-13.933791349355243 + 30 +0.0 + 10 +46.46467949684033 + 20 +-13.414087727482066 + 30 +0.0 + 10 +46.43292065303214 + 20 +-13.331860874686045 + 30 +0.0 + 10 +46.29889352570463 + 20 +-13.109841740192348 + 30 +0.0 + 10 +45.98078218238919 + 20 +-12.161228729085241 + 30 +0.0 + 10 +46.09884448096773 + 20 +-11.552554785241217 + 30 +0.0 + 10 +48.0708818294343 + 20 +-10.413998491252052 + 30 +0.0 + 10 +48.6570400767146 + 20 +-10.616090513375491 + 30 +0.0 + 10 +49.31950737103567 + 20 +-11.365889523472559 + 30 +0.0 + 10 +49.444768017969686 + 20 +-11.592969987781277 + 30 +0.0 + 10 +49.500099139460175 + 20 +-11.661587379712037 + 30 +0.0 + 10 +49.89910868455594 + 20 +-12.009889818647613 + 30 +0.0 + 10 +50.730505462437264 + 20 +-12.511782243653666 + 30 +0.0 + 10 +52.048270082550395 + 20 +-13.020748345639804 + 30 +0.0 + 10 +52.69943525477116 + 20 +-13.148717620697763 + 30 +0.0 + 10 +53.34809385772469 + 20 +-12.604428426199483 + 30 +0.0 + 10 +53.892383052222975 + 20 +-11.955769823245953 + 30 +0.0 + 10 +53.76441377716502 + 20 +-11.304604651025201 + 30 +0.0 + 10 +53.2554476751789 + 20 +-9.986840030912129 + 30 +0.0 + 10 +52.75355525017279 + 20 +-9.155443253030729 + 30 +0.0 + 10 +52.405252811237226 + 20 +-8.756433707934976 + 30 +0.0 + 10 +52.3366354193065 + 20 +-8.701102586444472 + 30 +0.0 + 10 +52.109554954997776 + 20 +-8.575841939510457 + 30 +0.0 + 10 +51.35975594490106 + 20 +-7.9133746451889655 + 30 +0.0 + 10 +51.15766392277724 + 20 +-7.327216397909113 + 30 +0.0 + 10 +52.29622021676642 + 20 +-5.355179049442544 + 30 +0.0 + 10 +52.90489416061064 + 20 +-5.237116750863459 + 30 +0.0 + 10 +53.85350717171756 + 20 +-5.555228094179409 + 30 +0.0 + 10 +54.07552630621125 + 20 +-5.689255221506917 + 30 +0.0 + 10 +54.15775315900728 + 20 +-5.721014065315145 + 30 +0.0 + 10 +54.677456780880476 + 20 +-5.823148053085546 + 30 +0.0 + 10 +55.648413723653256 + 20 +-5.842101254167103 + 30 +0.0 + 10 +57.04411441187264 + 20 +-5.623996518095675 + 30 +0.0 + 10 +57.67202463060447 + 20 +-5.409238575089362 + 30 +0.0 + 10 +57.961634861896414 + 20 +-4.613541004171726 + 30 +0.0 + 10 +58.10867382986053 + 20 +-3.7796415783815034 + 30 +0.0 + 10 +57.67226660064608 + 20 +-3.2797006347076403 + 30 +0.0 + 10 +56.57260671660443 + 20 +-2.392966048474428 + 30 +0.0 + 10 +55.72225673764146 + 20 +-1.9239015307076648 + 30 +0.0 + 10 +55.22111320477531 + 20 +-1.7525003477700514 + 30 +0.0 + 10 +55.13402323947662 + 20 +-1.738890886904751 + 30 +0.0 + 10 +54.87473546521508 + 20 +-1.7439522167197872 + 30 +0.0 + 10 +53.894156827578165 + 20 +-1.5451382157093914 + 30 +0.0 + 10 +53.42606087887684 + 20 +-1.1385562939891853 + 30 +0.0 + 10 +53.426060878876854 + 20 +1.1385562939891591 + 30 +0.0 + 10 +53.894156827578065 + 20 +1.5451382157099376 + 30 +0.0 + 10 +54.87473546521508 + 20 +1.7439522167197945 + 30 +0.0 + 10 +55.134023239476605 + 20 +1.7388908869047641 + 30 +0.0 + 10 +55.22111320477532 + 20 +1.7525003477700327 + 30 +0.0 + 10 +55.722256737641494 + 20 +1.9239015307076526 + 30 +0.0 + 10 +56.572606716604376 + 20 +2.3929660484743804 + 30 +0.0 + 10 +57.672266600646076 + 20 +3.2797006347076305 + 30 +0.0 + 10 +58.10867382986052 + 20 +3.7796415783815016 + 30 +0.0 + 10 +57.961634861896414 + 20 +4.613541004171724 + 30 +0.0 + 10 +57.67202463060447 + 20 +5.409238575089369 + 30 +0.0 + 10 +57.04411441187265 + 20 +5.623996518095678 + 30 +0.0 + 10 +55.64841372365333 + 20 +5.842101254167096 + 30 +0.0 + 10 +54.67745678088045 + 20 +5.823148053085526 + 30 +0.0 + 10 +54.15775315900727 + 20 +5.721014065315127 + 30 +0.0 + 10 +54.07552630621125 + 20 +5.689255221506941 + 30 +0.0 + 10 +53.85350717171755 + 20 +5.55522809417942 + 30 +0.0 + 10 +52.904894160610446 + 20 +5.237116750863987 + 30 +0.0 + 10 +52.29622021676642 + 20 +5.355179049442519 + 30 +0.0 + 10 +51.15766392277726 + 20 +7.327216397909099 + 30 +0.0 + 10 +51.3597559449007 + 20 +7.9133746451893945 + 30 +0.0 + 10 +52.10955495499776 + 20 +8.575841939510468 + 30 +0.0 + 10 +52.33663541930648 + 20 +8.701102586444481 + 30 +0.0 + 10 +52.40525281123725 + 20 +8.756433707934974 + 30 +0.0 + 10 +52.753555250172816 + 20 +9.15544325303074 + 30 +0.0 + 10 +53.25544767517887 + 20 +9.986840030912065 + 30 +0.0 + 10 +53.76441377716501 + 20 +11.30460465102519 + 30 +0.0 + 10 +53.89238305222297 + 20 +11.955769823245955 + 30 +0.0 + 10 +53.348093857724706 + 20 +12.604428426199483 + 30 +0.0 + 10 +52.69943525477117 + 20 +13.14871762069776 + 30 +0.0 + 10 +52.04827008255042 + 20 +13.020748345639802 + 30 +0.0 + 10 +50.73050546243735 + 20 +12.511782243653691 + 30 +0.0 + 10 +49.89910868455595 + 20 +12.009889818647578 + 30 +0.0 + 10 +49.50009913946019 + 20 +11.661587379712014 + 30 +0.0 + 10 +49.444768017969686 + 20 +11.59296998778129 + 30 +0.0 + 10 +49.31950737103567 + 20 +11.36588952347256 + 30 +0.0 + 10 +48.65704007671418 + 20 +10.616090513375848 + 30 +0.0 + 10 +48.07088182943433 + 20 +10.413998491252029 + 30 +0.0 + 10 +46.098844480967756 + 20 +11.55255478524121 + 30 +0.0 + 10 +45.98078218238867 + 20 +12.161228729085426 + 30 +0.0 + 10 +46.29889352570463 + 20 +13.10984174019235 + 30 +0.0 + 10 +46.432920653032134 + 20 +13.331860874686038 + 30 +0.0 + 10 +46.46467949684036 + 20 +13.41408772748207 + 30 +0.0 + 10 +46.56681348461076 + 20 +13.933791349355262 + 30 +0.0 + 10 +46.58576668569232 + 20 +14.904748292128048 + 30 +0.0 + 10 +46.367661949620896 + 20 +16.30044898034743 + 30 +0.0 + 10 +46.15290400661458 + 20 +16.928359199079264 + 30 +0.0 + 10 +45.35720643569694 + 20 +17.217969430371205 + 30 +0.0 + 10 +44.523307009906716 + 20 +17.36500839833532 + 30 +0.0 + 10 +44.02336606623285 + 20 +16.928601169120874 + 30 +0.0 + 10 +43.136631479999636 + 20 +15.828941285079225 + 30 +0.0 + 10 +42.667566962232875 + 20 +14.978591306116254 + 30 +0.0 + 10 +42.49616577929526 + 20 +14.477447773250098 + 30 +0.0 + 10 +42.482556318429964 + 20 +14.390357807951407 + 30 +0.0 + 10 +42.487617648245 + 20 +14.131070033689873 + 30 +0.0 + 10 +42.2888036472346 + 20 +13.150491396052953 + 30 +0.0 + 10 +41.88222172551439 + 20 +12.682395447351631 + 30 +0.0 + 10 +39.60510913753605 + 20 +12.682395447351642 + 30 +0.0 + 10 +39.198527215815275 + 20 +13.150491396052855 + 30 +0.0 + 10 +38.99971321480542 + 20 +14.131070033689875 + 30 +0.0 + 10 +39.004774544620446 + 20 +14.390357807951396 + 30 +0.0 + 10 +38.99116508375518 + 20 +14.477447773250116 + 30 +0.0 + 10 +38.819763900817556 + 20 +14.978591306116286 + 30 +0.0 + 10 +38.35069938305083 + 20 +15.828941285079168 + 30 +0.0 + 10 +37.46396479681758 + 20 +16.928601169120867 + 30 +0.0 + 10 +36.96402385314371 + 20 +17.365008398335316 + 30 +0.0 + 10 +36.130124427353486 + 20 +17.21796943037121 + 30 +0.0 + 10 +35.33442685643584 + 20 +16.92835919907926 + 30 +0.0 + 10 +35.11966891342953 + 20 +16.30044898034744 + 30 +0.0 + 10 +34.90156417735811 + 20 +14.904748292128119 + 30 +0.0 + 10 +34.92051737843968 + 20 +13.933791349355243 + 30 +0.0 + 10 +35.022651366210084 + 20 +13.414087727482066 + 30 +0.0 + 10 +35.05441021001827 + 20 +13.331860874686043 + 30 +0.0 + 10 +35.18843733734579 + 20 +13.109841740192346 + 30 +0.0 + 10 +35.50654868066122 + 20 +12.16122872908524 + 30 +0.0 + 10 +35.38848638208269 + 20 +11.552554785241213 + 30 +0.0 + 10 +33.41644903361611 + 20 +10.41399849125205 + 30 +0.0 + 10 +32.830290786335816 + 20 +10.61609051337549 + 30 +0.0 + 10 +32.16782349201474 + 20 +11.365889523472555 + 30 +0.0 + 10 +32.042562845080724 + 20 +11.592969987781274 + 30 +0.0 + 10 +31.987231723590234 + 20 +11.661587379712037 + 30 +0.0 + 10 +31.58822217849447 + 20 +12.00988981864761 + 30 +0.0 + 10 +30.756825400613145 + 20 +12.511782243653665 + 30 +0.0 + 10 +29.439060780500018 + 20 +13.0207483456398 + 30 +0.0 + 10 +28.787895608279253 + 20 +13.14871762069776 + 30 +0.0 + 10 +28.139237005325732 + 20 +12.604428426199492 + 30 +0.0 + 10 +27.594947810827453 + 20 +11.955769823245959 + 30 +0.0 + 10 +27.722917085885406 + 20 +11.304604651025207 + 30 +0.0 + 10 +28.23188318787152 + 20 +9.986840030912138 + 30 +0.0 + 10 +28.733775612877633 + 20 +9.155443253030736 + 30 +0.0 + 10 +29.0820780518132 + 20 +8.756433707934983 + 30 +0.0 + 10 +29.15069544374392 + 20 +8.701102586444478 + 30 +0.0 + 10 +29.37777590805265 + 20 +8.575841939510465 + 30 +0.0 + 10 +30.127574918149364 + 20 +7.9133746451889735 + 30 +0.0 + 10 +30.329666940273178 + 20 +7.327216397909119 + 30 +0.0 + 10 +29.191110646284 + 20 +5.355179049442551 + 30 +0.0 + 10 +28.582436702439782 + 20 +5.237116750863468 + 30 +0.0 + 10 +27.633823691332857 + 20 +5.555228094179418 + 30 +0.0 + 10 +27.411804556839172 + 20 +5.689255221506924 + 30 +0.0 + 10 +27.32957770404314 + 20 +5.721014065315151 + 30 +0.0 + 10 +26.809874082169948 + 20 +5.823148053085555 + 30 +0.0 + 10 +25.838917139397164 + 20 +5.842101254167114 + 30 +0.0 + 10 +24.44321645117778 + 20 +5.623996518095684 + 30 +0.0 + 10 +23.81530623244595 + 20 +5.409238575089372 + 30 +0.0 + 0 +LWPOLYLINE + 8 +OpenJsCad + 90 +31 + 70 +1 + 10 +40.516670181655435 + 20 +0.445503262094184 + 30 +0.0 + 10 +40.614255908973945 + 20 +0.48296291314453416 + 30 +0.0 + 10 +40.71749745340374 + 20 +0.4993147673772869 + 30 +0.0 + 10 +40.821882664045326 + 20 +0.49384417029756894 + 30 +0.0 + 10 +40.92284940629786 + 20 +0.4667902132486009 + 30 +0.0 + 10 +41.01598494903272 + 20 +0.41933528397271214 + 30 +0.0 + 10 +41.097218822118485 + 20 +0.35355339059327384 + 30 +0.0 + 10 +41.16300071549792 + 20 +0.2723195175075135 + 30 +0.0 + 10 +41.21045564477381 + 20 +0.17918397477264994 + 30 +0.0 + 10 +41.23750960182278 + 20 +0.07821723252011512 + 30 +0.0 + 10 +41.242980198902494 + 20 +-0.026167978121471938 + 30 +0.0 + 10 +41.22662834466974 + 20 +-0.12940952255126062 + 30 +0.0 + 10 +41.18916869361939 + 20 +-0.2269952498697735 + 30 +0.0 + 10 +41.13223841225369 + 20 +-0.31466019552491875 + 30 +0.0 + 10 +41.058325627050124 + 20 +-0.38857298072848545 + 30 +0.0 + 10 +40.97066068139498 + 20 +-0.445503262094184 + 30 +0.0 + 10 +40.87307495407647 + 20 +-0.4829629131445342 + 30 +0.0 + 10 +40.76983340964668 + 20 +-0.49931476737728697 + 30 +0.0 + 10 +40.66544819900509 + 20 +-0.4938441702975689 + 30 +0.0 + 10 +40.56448145675256 + 20 +-0.46679021324860087 + 30 +0.0 + 10 +40.4713459140177 + 20 +-0.4193352839727119 + 30 +0.0 + 10 +40.39011204093193 + 20 +-0.35355339059327373 + 30 +0.0 + 10 +40.324330147552494 + 20 +-0.27231951750751354 + 30 +0.0 + 10 +40.27687521827661 + 20 +-0.17918397477265013 + 30 +0.0 + 10 +40.24982126122764 + 20 +-0.07821723252011548 + 30 +0.0 + 10 +40.24435066414792 + 20 +0.026167978121471883 + 30 +0.0 + 10 +40.260702518380675 + 20 +0.12940952255126043 + 30 +0.0 + 10 +40.29816216943102 + 20 +0.22699524986977337 + 30 +0.0 + 10 +40.355092450796725 + 20 +0.31466019552491875 + 30 +0.0 + 10 +40.42900523600029 + 20 +0.38857298072848545 + 30 +0.0 + 10 +40.516670181655435 + 20 +0.445503262094184 + 30 +0.0 + 0 +ENDSEC + 0 +EOF diff --git a/ino/contact_printer/contact_printer.ino b/ino/contact_printer/contact_printer.ino new file mode 100644 index 0000000..60403bb --- /dev/null +++ b/ino/contact_printer/contact_printer.ino @@ -0,0 +1,216 @@ +#include +#include + +StaticJsonBuffer<200> jsonBuffer; + +/*LIGHT VARIABLES*/ +#define NUMPIXELS 1 // Number of Pixies in the strip +#define PIXELPIN 3 // Pin number for SoftwareSerial output; +Adafruit_NeoPixel light = Adafruit_NeoPixel(1, PIXELPIN, NEO_GRB + NEO_KHZ800); + +String color = "000,000,000"; + +volatile int commaR = 0; +volatile int commaG = 0; + +String strR = "000"; +String strG = "000"; +String strB = "000"; + +volatile int r = 0; +volatile int g = 0; +volatile int b = 0; + +/*MOTOR VARIABLES*/ +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 + +const float RPM = 15.0; +const float RPS = RPM / 60.0; +const float RATIO = 0.5; //Gear ratio +const float THICKNESS = 0.11938; //16mm thickness + +volatile int LENGTH = 33000; //mm +String lengthStr = "33000"; +volatile float CORE_D = 31.27; //Daylight spool +//2in core +//3in core +//takeup spool? +unsigned long starttime = 0; +unsigned long runtime = 0; +volatile boolean running = false; + +//motor pins +const int MOTOR_PIN = 9; //TIP120 -> 2.2k resistor + +/*CORE INFO*/ +volatile int i = 0; +unsigned long now; //to be compared to stored values every loop + +/*COMMANDS*/ +volatile char cmd_char = 'z'; //null command default +const char cmd_connect = 'c'; +const char cmd_light = 'l'; +const char cmd_length = 'f'; +const char cmd_start = 's'; +const char cmd_stop = 'x'; + +const int serialDelay = 5;//allows for sending longer strings to arduino in realtime + +void setup () { + Serial.begin(57600); + Serial.flush(); + Serial.setTimeout(serialDelay); + pinMode(MOTOR_PIN, OUTPUT); + + light.begin(); + setAll(0, 0, 0); + + delay(2000); + reportString("msg", "Connected to contact printer"); +} + +void loop () { + now = millis(); + readCmd(); + if (running) { + motor_run(); + } +} + +void readCmd () { + if (Serial.available()) { + /* read the most recent byte */ + cmd_char = (char)Serial.read(); + } + if (cmd_char != 'z') { + cmd(cmd_char); + cmd_char = 'z'; + } +} + +void cmd (const char val) { + if (val == cmd_connect) { + reportString("verify", "contact_printer"); + } else if (val == cmd_light) { + colorString(); + reportString("light", color); + } else if (val == cmd_length) { + setLength(); + reportInt("length", LENGTH); + } else if (val == cmd_start) { + running = true; + } else if (val == cmd_stop) { + runtime = now - starttime; + reportInt("stopped", runtime); + running = false; + i = 0; + } +} + +void reportString (String key, String val) { + JsonObject& jsonObj = jsonBuffer.createObject(); + jsonObj[key] = val; + jsonObj.printTo(Serial); + Serial.println(""); +} + +void reportFloat (String key, const float val) { + JsonObject& jsonObj = jsonBuffer.createObject(); + jsonObj[key] = val; + jsonObj.printTo(Serial); + Serial.println(""); +} + +void reportInt (String key, const int val) { + JsonObject& jsonObj = jsonBuffer.createObject(); + jsonObj[key] = val; + jsonObj.printTo(Serial); + Serial.println(""); +} + +void motor_run () { + starttime = now; + runtime = 0; + Serial.println("Starting motor"); + //analogWrite(MOTOR_PIN, 255 - (i * 2)); + analogWrite(MOTOR_PIN, pwm()); + Serial.print("PWM = "); + Serial.println(255 - (i * 2)); + Serial.print(i); + Serial.print("ft = "); + Serial.print(diameter(12.0 * 25.4 * i)); + Serial.println("mm"); + + Serial.print(32.0 + (i * 0.4)); + Serial.print("mm = "); + Serial.print(length(32.0 + (i * 0.4)) / (12 * 25.4) ); + Serial.println("ft"); + delay(1000); + i++; + if (i > 108) { + runtime = now - starttime; + reportInt("completed", runtime); + running = false; + i = 0; + } +} + +int pwm () { + int val = 255; //full speed + + return val; +} + +float diameter (const float len) { //mm + 'use strict'; + return 2 * sqrt( ((len * THICKNESS) / PI) + pow(CORE_D / 2, 2) ); +} + +float length (const float diam) { + return (PI * (pow(diam / 2, 2) - pow(CORE_D / 2, 2)) ) / THICKNESS; + //var len = Math.PI * (Math.pow(d / 2, 2) - Math.pow(D / 2, 2)); + //return len / THICKNESS; +} + +void setAll (const int red, const int green, const int blue) { + for (volatile int x = 0; x < NUMPIXELS; x++) { + light.setPixelColor(x, red, green, blue); + } + light.show(); + } + + void setLength () { + while (Serial.available() == 0) { + //Wait for length string + } + lengthStr = Serial.readString(); + LENGTH = lengthStr.toInt(); + } + +float speed (float diam) { + return (diam * PI) * RPS; +} + +void colorString () { + while (Serial.available() == 0) { + //Wait for color string + } + color = Serial.readString(); + + commaR = color.indexOf(','); //comma trailing R + commaG = color.indexOf(',', commaR + 1); + + strR = color.substring(0, commaR); + strG = color.substring(commaR + 1, commaG); + strB = color.substring(commaG + 1); + + r = strR.toInt(); + g = strG.toInt(); + b = strB.toInt(); + + setAll(r, g, b); +} diff --git a/models.txt b/models.txt new file mode 100644 index 0000000..43bd5e3 --- /dev/null +++ b/models.txt @@ -0,0 +1,2 @@ +light_housing +lamp_plate \ No newline at end of file diff --git a/notes/contact_printer.js b/notes/contact_printer.js new file mode 100644 index 0000000..db8f853 --- /dev/null +++ b/notes/contact_printer.js @@ -0,0 +1,64 @@ +var RPM = 15; +var RPS = RPM / 60; //Rotations per second, from 15RPM +var D = 31.27; //mm, Diameter of core (daylight spool here) 32, or 31.5 +//var D_END = 87.16; +var THICKNESS = 0.11938; //mm, 16mm = 0.0047in thick +var PITCH = 7.6; +var TOTAL = 33 * 1000; + +var roll = {}; + +//R = √(36000 × 0.005/π + 32) = √(57.30 + 9) = 8.14 inches. +roll.diameter = function (length) { + 'use strict'; + var r = Math.sqrt(((length * THICKNESS) / Math.PI) + Math.pow(D / 2, 2)); + return 2 * r; +}; + +roll.length = function (d) { + 'use strict'; + var len = Math.PI * (Math.pow(d / 2, 2) - Math.pow(D / 2, 2)); + return len / THICKNESS; +}; + +//mm/s +roll.speed = function (d) { + 'use strict'; + var mm = d * Math.PI; + return mm * RPS; +}; + +var job = {}; + +job.pmw = {}; //15 7.5 +/* +job.pmw.values = [255, 55]; +job.pmw.rps = [0.1100917431, 0.06629834254]; +*/ + +job.state = { + motor_pwm : 255, + current_rps : RPS, + start_time : 0, + end_time : 0, + estimated_time : 0 +}; + +job.begin = function () { + 'use strict'; + job.state.start_time = +new Date(); + //job pins set + job.state.estimated_time = 0; +}; + +job.simulate = function () { + 'use strict'; + + +}; + + + + +job.begin(); +console.dir(job.state); diff --git a/notes/proofs.r b/notes/proofs.r new file mode 100644 index 0000000..d4b5449 --- /dev/null +++ b/notes/proofs.r @@ -0,0 +1,2 @@ + +print("Motor PWM values to maintain a constant speed"); diff --git a/notes/winding_forum.txt b/notes/winding_forum.txt new file mode 100644 index 0000000..c61e036 --- /dev/null +++ b/notes/winding_forum.txt @@ -0,0 +1,96 @@ +vnkarwa +June 3rd, 2003, 03:46 AM +Can anybody have the circuit for the calculation of diameter vs. linear speed. +I have a application in the winding machine that as the coil diameter increases the linear speed increases as the rpm is fix. +I want a circuit which can reduce the referance voltage according to increase in the diameter so that the linear speed will be maintained. +Thanks a lot. +Also Mr jvdcande I want your Email address to communicate with you personally. +My address is vnkarwa@indiatimes.com +JesperMP +June 3rd, 2003, 04:05 AM +Is this a trick question ? + +Speed = Diameter x Pi x RPM + +If Speed is constant then + +RPM = Constant Speed / (Pi x Diameter) + +So RPM is inversely linear with the Diameter. It cant get much simpler than that. +Calistodwt +June 3rd, 2003, 05:24 AM +Linear velocity v = omega * r [m/s] + +Where omega = 2*PI*n ( n is speed in revs per second) +and v = velocity in metres per second. +and r is the radius in metres and D is diameter in metres. + +So v = 2*PI*n*r = PI*D*n [m/s] + +So v is proportional to D. + +Therefore v1/v2 = D1/D2 + +which gives: v2 = v1 * D2/D1 + +So with your references of diameter D1 and speed of v1 you can work out v2 for any given diameter D2 +rdrast +June 3rd, 2003, 09:18 AM +If possible, the simplest solution for what (I think) you want to do, is mount a tachometer/encoder with either a belt drive, or a rubber roll, and use it as a surface speed feedback device to your drive. + +If you can put such an arrangement on an arm so a belt can maintain contact with the winder roll, you are covered in all cases. + +If you can only put a single roller on the material coming into the winder, you need to also put in some extra circuitry/logic to take care of the case when no material is loaded. +Peter Nachtwey +June 4th, 2003, 02:06 AM +vnkarwa, clearly stated that he wanted change his system to keep the linear speed constant and not the RPM constant as he has it now. + +Although the equations are valid, they assume that the RPM is held constant. + +Hint, vnkarwa, don't assume that you are the first to ask this question. I know we discussed an unwinder a few months back. Search this site and search the web. The answers are out there. +JesperMP +June 4th, 2003, 02:42 AM +Peter, + +neither mine nor Calisto's replies assumes that the RPM should be kept constant. +Both formulas assumes that the speed (of the unwinded material) should be kept constant. + +I found the relation between speed = f(diameter) so simple that maybe I had misunderstood something. +Calistodwt +June 5th, 2003, 05:00 AM +I assumed that what was required was to control the linear speed as the diameter of the cable coil varied; with the winding rpm assumed to be constant. From this I also assumed that the application could measure the changing diameter and use this in the velocity formula to determine a measured value for a controller. Maybe I assumed too much but then the initial information was rather vague with no further response on the suggestions made being offered by the originator. +scottezell +July 12th, 2003, 10:17 AM +The issue as I understand it is that you wish to be able to maintain a constant linear speed as the diameter decreases. The first thought is that you need to know the circumfrence of the object an any point during the cycle. ie if the cir=1 meter then at 60 rpm your linear spd is 60 m/s. but as the dia changes the spd would change at this rpm. Therefore to maintain constant linear spd you have to vary the rpm. To find the cir of the object at any point in the process it is easier if you use polar math rather than conventional math. The equation that explains this reduction in dia is R=(T/2p)*q where R=Radius T=change in diameter per revoulution p=Pi and q= Theta(angular position). if you have a graphing calculator ie ti-85 or similar change your mode to polar and enter this formula. you will basically get a spiral. This formula can be used in the calculation for circumfrence and applied as the angular velocity. +Peter Nachtwey +July 12th, 2003, 12:03 PM +The is because the change ing angular velocity is changing as the diameter changes. The simple arithmetic formulas above require that one assumes the rotational speed is constant or conituously measures the sheet speed and roll radius. With the equations below, if you know the initial conditions then one can calculate the state knowing how many encoder pulses have gone by. The calculus equations end up being pretty simple, but they look nothing like what I see above. It isn't that they are wrong. They just make assumptions that a lot of the parameters are known or measured. + +Below is the link I post a long time ago for winder equations. + +If you want to show the world that you know something about winding, you better study the info at this URL. It isn't hard, but it does take more effort than lifting another beer. + +Winder Control Equations +http://www.apicsllc.com/apics/Ie_ias03/IAS4p5s.html + +Winder Control Equations (http://www.apicsllc.com/apics/Ie_ias03/IAS4p5s.html) + +( I couldn't get the link to work, but I could cut and paste the URL into my browser ) + +Since we are quoting rock stars now..... + +"Living is easy with eyes closed, misunderstanding all you see." +Strawberry Fields Forever, John Lennon +DickDV +July 12th, 2003, 10:31 PM +You could avoid the calculus at the cost of a slight increase in error by using the static formulas and recalculating the rpm required while adjusting the diameter either up or down by double the caliper of the sheet being wound or unwound. + +Use the results of this calculation to adjust the drive speed on the center shaft. Remember also that you need to tell the control system the size of the empty core so it knows what diameter to use at the beginning of a run (assuming a winder). +DickDV +July 12th, 2003, 10:35 PM +The first paragraph in my previous post should read "recalculate the rpm required after each complete revolution while adjusting the diameter...." +Peter Nachtwey +July 13th, 2003, 01:20 PM +That is why I recommend using best algorithms available. + +Did you read the full report? In the end the calculus boils down to equations that use a square root and no calculus is necessary. \ No newline at end of file diff --git a/scad/16mm_sprocketed_roller.scad b/scad/16mm_sprocketed_roller.scad new file mode 100644 index 0000000..88b8b32 --- /dev/null +++ b/scad/16mm_sprocketed_roller.scad @@ -0,0 +1,61 @@ +time = 0; + +SPROCKET_BASE_D = 19.05; //8 frames +SPROCKET_BASE_H = 2.7; + +INNER_D = 13.98; +INNER_H = 10.6; + +TOP_BASE_D = 18.47; +TOP_BASE_H = 2.96; + +LIP_D = 18.84; +LIP_H = 0.33; + +HOLLOW_D = 4.7; +HOLLOW_BASE_D = 12.01; +HOLLOW_BASE_H = 6.09; + +TOP_D = 21.66; +TOP_H = 1.4; + +SPROCKET_H = 10; +SPROCKET_W = 0.79; +SPROCKET_L = 1.3; + +FRAME_C = (SPROCKET_BASE_D * PI) / 8; +//echo(FRAME_C); + +$fn = 100; +module sprocket () { + //cube([SPROCKET_L, SPROCKET_W, SPROCKET_H], center = true); + translate ([0, 0, -SPROCKET_H/2]) { + difference () { + translate([0, 0, 0]) scale([1, 1, 2.25]) rotate([90, 0, 90]) cylinder(r = SPROCKET_W/2, h = SPROCKET_L, center = true); + translate([0, 0, -1]) cube([2, 2, 2], center = true); + //translate([1.5, 0, 0]) rotate([0, -5, 0]) cube([2, 2, 2], center = true); + //translate([-1.5, 0, 0]) rotate([0, 5, 0]) cube([2, 2, 2], center = true); + } + } +} +module sprocketed_roller () { + difference () { + union () { + cylinder(r = SPROCKET_BASE_D / 2, h = SPROCKET_BASE_H, center = true); + + translate([0, 0, (INNER_H / 2) + (SPROCKET_BASE_H / 2)]) cylinder(r = INNER_D / 2, h = INNER_H, center = true); + + translate([0, 0, (TOP_BASE_H / 2) +INNER_H + (SPROCKET_BASE_H / 2)]) cylinder(r = TOP_BASE_D / 2, h = TOP_BASE_H, center = true); + translate([0, 0, (TOP_BASE_H / 2) + INNER_H + (SPROCKET_BASE_H / 2) - (TOP_BASE_H / 2) + (LIP_H / 2)]) cylinder(r = LIP_D / 2, h = LIP_H, center = true); + translate([0, 0, (TOP_BASE_H / 2) + INNER_H + (SPROCKET_BASE_H / 2) + (TOP_BASE_H / 2) - (LIP_H / 2)]) cylinder(r = LIP_D / 2, h = LIP_H, center = true); + translate([0, 0, (TOP_H / 2) + (TOP_BASE_H / 2) + INNER_H + (SPROCKET_BASE_H / 2) + (TOP_BASE_H / 2) - (LIP_H / 2)]) cylinder(r = TOP_D / 2, h = TOP_H, center = true); + } + cylinder(r = HOLLOW_D / 2, h = 100, center = true); + translate([0, 0, (HOLLOW_BASE_H / 2) - (SPROCKET_BASE_H / 2)]) cylinder(r = HOLLOW_BASE_D/2, h = HOLLOW_BASE_H + 0.1, center = true); + } + for (i = [0: 8]) { + rotate([0, 0, i * 360 / 8]) translate([(SPROCKET_BASE_D / 2) + (SPROCKET_H / 2) - .15, 0, (SPROCKET_BASE_H / 2) - (SPROCKET_L / 2)]) rotate([0, 90, 0]) sprocket(); + } +} + +sprocketed_roller(); diff --git a/scad/16mm_sprocketed_roller_var.scad b/scad/16mm_sprocketed_roller_var.scad new file mode 100644 index 0000000..befc8b3 --- /dev/null +++ b/scad/16mm_sprocketed_roller_var.scad @@ -0,0 +1,116 @@ +time = 0; + +$fn = 100; + +SPROCKET_BASE_D = 19.05; //8 frames +SPROCKET_BASE_H = 2.7; +FRAME_C = (SPROCKET_BASE_D * PI) / 8; + +SPROCKET_H = 10; +SPROCKET_W = 1; +SPROCKET_L = 1.5; + +INNER_H = 10.6; + +TOP_D = 21.66; +TOP_C = (TOP_D * PI) / 8; +TOP_H = 1.4; + +TOP_BASE_D = 18.47; +TOP_BASE_C = (TOP_BASE_D * PI) / 8; +TOP_BASE_H = 2.96; + +LIP_D = 18.84; +LIP_H = 0.33; +LIP_C = (LIP_D * PI) / 8; + +echo(FRAME_C); + +module bearing_laser (x, y, z, width= 8, hole = true) { + innerD = 8.05; + outerD = 22.1 - .4; + fuzz = 0.3; + translate ([x, y, z]) { + difference () { + cylinder(r = (outerD / 2) + fuzz, h = width, center = true); + if (hole) { + cylinder(r = innerD / 2 - fuzz, h = width, center = true); + } + } + } +} + +module sprocket () { + translate ([0, 0, -SPROCKET_H/2]) { + difference () { + translate([0, 0, 0]) scale([1, 1.2, 2]) rotate([90, 0, 90]) cylinder(r = SPROCKET_W/2, h = SPROCKET_L, center = true); + translate([0, 0, -1]) cube([2, 2, 2], center = true); + } + } +} + +module sprocketed_roller (sprockets = 8) { + D = (FRAME_C * sprockets) / PI; + LIP_D = (LIP_C * sprockets) / PI; + TOP_D = (TOP_C * sprockets) / PI; + TOP_BASE_D = (TOP_BASE_C * sprockets) / PI; + INNER_D = D - 5.07; + + echo(D); + echo(LIP_D); + + //top + cylinder(r = D / 2, h = SPROCKET_BASE_H, center = true); + + //center + translate([0, 0, (INNER_H / 2) + (SPROCKET_BASE_H / 2)]) { + cylinder(r = INNER_D / 2, h = INNER_H, center = true); + } + + //lip + translate([0, 0, (TOP_BASE_H / 2) + INNER_H + (SPROCKET_BASE_H / 2) - (TOP_BASE_H / 2) + (LIP_H / 2)]) { + cylinder(r = LIP_D / 2, h = LIP_H, center = true); + } + + //bottom + translate([0, 0, (TOP_H / 2) + (TOP_BASE_H / 2) + INNER_H + (SPROCKET_BASE_H / 2) + (TOP_BASE_H / 2) - (LIP_H / 2)]) { + cylinder(r = TOP_D / 2, h = TOP_H, center = true); + } + + //bottom base + translate([0, 0, (TOP_BASE_H / 2) +INNER_H + (SPROCKET_BASE_H / 2)]) { + cylinder(r = TOP_BASE_D / 2, h = TOP_BASE_H, center = true); + } + + for (i = [0: sprockets]) { + rotate([0, 0, i * 360 / sprockets]) translate([(D / 2) + (SPROCKET_H / 2) - .15, 0, (SPROCKET_BASE_H / 2) - (SPROCKET_L / 2)]) rotate([0, 90, 0]) sprocket(); + } +} + +//rotate([0, 0, time]) sprocketed_roller(sprockets = 13); + +module corner (sprockets = 8) { + +} + +module contact_printer_roller () { + union () { + sprocketed_roller(13); + translate([0, 0, 16]) cylinder(r = 12 / 2, h = 2, center = true); + translate([0, 0, 22]) { + difference () { + translate([0, 0, 3]) cylinder(r = 8 / 2, h = 26, center = true, $fn = 50); + translate([0, 6.5, 11]) cube([10, 10, 12], center = true); + } + } + + } +} +module contact_printer_roller2 () { + innerD = 8.05; + fuzz = 0.3; + translate([0, 0, 21]) cylinder(r = innerD / 2 - fuzz, h = 10, center = true); + sprocketed_roller(13); +} +//contact_printer_roller(); +//contact_printer_roller2(); \ No newline at end of file diff --git a/scad/contact_printer.scad b/scad/contact_printer.scad new file mode 100644 index 0000000..b0e791b --- /dev/null +++ b/scad/contact_printer.scad @@ -0,0 +1,773 @@ +include <16mm_sprocketed_roller_var.scad> +include <./lamp.scad>; +include <../box_laser/library.scad> +include <../readyCAD/ready.scad> + +AT = 25.4 * 0.22; +daylight_w = 92; +daylight_h = 18; + +INNER_BOX_X = 225; +INNER_BOX_Y = 400; +INNER_BOX_Z = 40; + +OUTER_BOX_X = INNER_BOX_X + (25.4 / 2) + .2; +OUTER_BOX_Y = INNER_BOX_Y + (25.4 / 2) + .2; +OUTER_BOX_Z = 70; + +REEL_SPACING = 250; +REEL_SPACING_X = 115; + +REEL_HOLDER_Z = 4; + +IDLE_SPACING = 120; +IDLE_OFFSET = 0; +IDLE_PLAY = 20; +IDLE_PLAY_ANGLE = 45; +IDLE_PLAY_SLOT = 8.1; + +SPROCKETED_SPACING = 45; +SPROCKETED_OFFSET = 40; +SPROCKETED_Z = 7.5; + +LAMP_Z = -3; + +SLIT = 1; + +BOLT_R = 2.55; //M5 25mm 0.8 +BOLT_Z = 25; + +INVOLUTE_SCALE = 1.45; +INVOLUTE_ROTATE = (360 / 12); + +PEG_INNER_D = 4; +PEG_OUTER_D = 7; +PEG_H = 10; + +PRESSURE_PEG_SPACING = 60; +PRESURE_PEG_OFFSET = -25; + +BREAK_PEG_SPACING = 190; +BREAK_PEG_OFFSET = -80; + +module m5_25 () { + cylinder(r = BOLT_R, h = BOLT_Z, center = true); +} + +module daylight_spool (DEBUG = false) { + //inner starting d = 31.5 or 32 + color([[255, 0, 0, 1]]) difference () { + cylinder(r=daylight_w / 2, h = daylight_h, center = true); + cylinder(r=(daylight_w / 2) + 1, h = daylight_h - 2, center = true); + cube([9, 9, 50], center=true); + translate([4.5, 4.5, 0]) { + rotate([0, 0, 45]) { + cube([3, 3, 50], center=true); + } + } + } + difference () { + cylinder(r = 32/2, h = daylight_h, center=true); + cylinder(r = 32/2 - 1, h = daylight_h + 1, center=true); + translate([0, 32/2, 0]) { + cube([1.3, 10, 18], center=true); + } + } + + if (DEBUG) { + color([0,0,1,0.5]) cylinder(r = 300, h = 16, center=true); + } +} + +module roller (DEBUG = false) { + $fn = 100; + H = 21; + echo("ROLLER_CLEARANCE"); + echo(H - 4); + //translate([0, 0, 9]) cube([16, 16, 20], center = true); + difference () { + union () { + cylinder(r = 24 / 2, h = 2, center = true); + translate([0, 0, 1]) cylinder(r = 16 / 2, h = 4, center = true); + translate([0, 0, 10]) cylinder(r = 14 / 2, h = 18, center = true); + translate([0, 0, H - 3.5]) cylinder(r = 16 / 2, h = 4, center = true); + translate([0, 0, H - 2]) cylinder(r = 24 / 2, h = 2, center = true); + } + cylinder(r = (IDLE_PLAY_SLOT / 2) + .1, h = 50, center = true); + if (DEBUG){ + translate([50, 0, 0]) cube([100, 100, 100], center = true); + } + } + //translate([0, 0, H/2 - 1]) cube([25, 25, H], center = true); +} + +module idle_roller_peg () { + translate([0, 0, -.6]) cylinder(r = (IDLE_PLAY_SLOT / 2) - .1, h = 39.25, center = true); + translate([0, 0, -6.75]) cylinder(r = 16 / 2, h = 2.4, center = true); +} + +module idle_roller_peg_top (DEBUG = false) { + difference() { + union () { + cylinder(r = (IDLE_PLAY_SLOT / 2) + 2, h = PEG_H, center = true);//inner peg + translate([0, 0, PEG_H / 2 - 1]) cylinder(r = (IDLE_PLAY_SLOT / 2) + 4, h = 2, center = true); + translate([0, 0, -PEG_H / 2 - 1]) cylinder(r = (IDLE_PLAY_SLOT / 2) + 4, h = 2, center = true); + } + translate([0, 0, (25.4 / 4)]) cylinder(r = (IDLE_PLAY_SLOT / 2), h = 15.5 , center = true); + if (DEBUG) { + translate([50, 0, 0]) cube([100, 100, 100], center = true); + } + } +} + +module idle_roller_peg_cap (DEBUG = false) { + difference() { + union () { + cylinder(r = (IDLE_PLAY_SLOT / 2) + 2, h = 5.5, center = true);//inner peg + translate([0, 0, -1.75]) cylinder(r = (IDLE_PLAY_SLOT / 2) + 4, h = 2, center = true); + } + translate([0, 0, -7.1 - .2]) cylinder(r = (IDLE_PLAY_SLOT / 2), h = 15.5 , center = true); + if (DEBUG) { + translate([50, 0, 0]) cube([100, 100, 100], center = true); + } + } +} + +module sprocketed_roller_peg () { + D = 4.7; + cylinder(r = (D / 2) - .1, h = 30, center = true); + translate([0, 0, -2.75]) cylinder(r = 16 / 2, h = 3, center = true); + translate([0, 0, -9.25]) cylinder(r = 6 / 2, h = 11.5, center = true); +} + +module sprocketed_roller_peg_cap (DEBUG = false) { + D = 4.7; + difference() { + translate([0, 0, 1.3]) cylinder(r = 5.92 - .1, h = 6, center = true); + cylinder(r = (D / 2) - .1, h = 6, center = true); + if (DEBUG) { + translate([50, 0, 0]) cube([100, 100, 100], center = true); + } + } +} + +module reel_holder (top = true) { + $fn = 60; + SQUARE_INNER = 8; + difference(){ + translate([0, 0, -1.5]) cube([SQUARE_INNER, SQUARE_INNER, 21.5], center= true); + for (i = [0:4]) { + rotate([0, 0, (i * 90)]){ + translate([(SQUARE_INNER / 2) + .4, (SQUARE_INNER / 2) + .4, 18.5 / 2]) rotate([0, -15, 45]) cube([2.5, SQUARE_INNER, SQUARE_INNER], center = true); + } + } + } + difference () { + union() { + translate([0, 0, (18.5 / 2) + (3.5 / 2)]) cylinder(r = SQUARE_INNER / 2, h = 3.5, center = true); + translate([0, 0, (18.5 / 2) + (7.5 / 2)]) sphere(SQUARE_INNER / 2, center = true); + } + translate ([0, 0, (18.5 / 2) + 7.5]) cube([10, 10, 2], center = true); + } + difference () { + translate([0, 0, -(18.5/ 2) - (3 / 2) - 3]) cylinder(r = 16 /2, h = 3, center = true); + //translate([0, 0, -14.3]) cube([4, 4, 2], center = true); //notch + difference() { + translate([0, 0, -14.3]) cylinder(r = 8 / 2, h = 2, center = true); + translate([0, 6, -14.3]) cube([8, 8, 2], center = true); + } + } +} + +module bearing_laser (x, y, z, width= 8, hole = true) { + innerD = 8.05; + outerD = 22.1 - .5; + fuzz = 0.1; + translate ([x, y, z]) { + difference () { + cylinder(r = outerD / 2 + fuzz, h = width, center = true); + if (hole) { + cylinder(r = innerD / 2 - fuzz, h = width, center = true); + } + } + } +} + +module inner_box (DUMMY = false) { + difference () { + //8.8 inches x 15 inches + if (DUMMY) { + color("lightblue") cube([INNER_BOX_X, INNER_BOX_Y, 6], center = true); + } else { + translate([0, -209.5, 0]) Box2D([INNER_BOX_X, INNER_BOX_Y, INNER_BOX_Z], SIDE_TABS = 1, TOP_TABS = 0, TOP = false, BOTTOM_TABS = 3, MATERIAL = 6); + //translate([INNER_BOX_X + 4, 14, 0]) cube([INNER_BOX_X, INNER_BOX_Y, INNER_BOX_Z], center = true); + } + idle_play_voids(); + bearing_voids(); + sprocketed_voids(); + elastic_peg_voids(); + //takeup motor mount point + translate([0, 157 + 1.25, 0]) { + cylinder(r = 6, h = 100, center = true); + //bolts + translate([(15.2 / 2), 19.14 + 1, 0]) cylinder(r = (3.75 / 2), h = 100, center = true); + translate([-(15.2 / 2), 19.14 +1, 0]) cylinder(r = (3.75 / 2), h = 100, center = true); + } + //drive motor mount point + translate([5, 0, 14.5]) rotate([0, 0, 90]) { + cylinder(r = 6, h = 100, center = true); + translate([(15.2 / 2), 19.14 + 1, 0]) cylinder(r = (3.75 / 2), h = 100, center = true); + translate([-(15.2 / 2), 19.14 +1, 0]) cylinder(r = (3.75 / 2), h = 100, center = true); + } + + //light mount points, 40mm spread + translate([75, 20, 0]) cylinder(r = 3, h = 7, center = true); + translate([75, -20, 0])cylinder(r = 3, h = 7, center = true); + + //Hole for light strip + translate([87, 0, 0]) cylinder(r = 5, h = 50, center = true); + + //Hole for power cable to motor + translate([-10, 195, 0]) cylinder(r = 2, h = 50, center = true); + + CENTER_ELEC = 546; + //Arduino USB B plug hole + translate([CENTER_ELEC, -205, 0]) cube([11.5, 11.5, 20], center = true); + + //DC power + translate([CENTER_ELEC + 30, -205, 0]) cylinder(r = (11.5 / 2), h = 20, center = true); + } +} + +module outer_box (DUMMY = false) { + difference () { + if (DUMMY) { + cube([OUTER_BOX_X, OUTER_BOX_Y, OUTER_BOX_Z], center = true); + } else { + translate([0, -209.5, 0]) Box2D([OUTER_BOX_X, OUTER_BOX_Y, OUTER_BOX_Z], SIDE_TABS = 1, TOP_TABS = 0, TOP = false, BOTTOM_TABS = 3, MATERIAL = 6); + } + CENTER_ELEC = 571; + //Arduino USB B plug hole + translate([CENTER_ELEC, -205, 0]) cube([11.5, 11.5, 20], center = true); + + //DC power + translate([CENTER_ELEC + 30, -205, 0]) cylinder(r = (11.5 / 2), h = 20, center = true); + } +} + +module light_source () { + //light mount points, 40mm spread + translate([0, 20, 0]) cylinder(r = 3, h = 7, center = true); + translate([0, -20, 0])cylinder(r = 3, h = 7, center = true); + + translate ([10, 0, (7 / 2) + (3 / 2)]) { + rounded_cube([55, 80, 3], d = 20, center = true); + translate ([0, 0, 0]) { + cube([55 / 2, 80, 3], d = 20, center = true); + } + } + +} + +module idle_play_voids () { + translate([IDLE_OFFSET, IDLE_SPACING / 2, 0]) { + rotate([0, 0, IDLE_PLAY_ANGLE]) { + cube([IDLE_PLAY, IDLE_PLAY_SLOT, 50], center = true); + translate([IDLE_PLAY / 2, 0, 0]) cylinder(r = IDLE_PLAY_SLOT / 2, h = 50, center = true); + translate([-IDLE_PLAY / 2, 0, 0]) cylinder(r = IDLE_PLAY_SLOT / 2, h = 50, center = true); + } + } + + translate([IDLE_OFFSET, -IDLE_SPACING / 2, 0]) { + rotate([0, 0, -IDLE_PLAY_ANGLE]) { + cube([IDLE_PLAY, IDLE_PLAY_SLOT, 50], center = true); + translate([IDLE_PLAY / 2, 0, 0]) cylinder(r = IDLE_PLAY_SLOT / 2, h = 50, center = true); + translate([-IDLE_PLAY / 2, 0, 0]) cylinder(r = IDLE_PLAY_SLOT / 2, h = 50, center = true); + } + } +} + +module bearing_voids () { + bearing_laser(REEL_SPACING_X / 2, REEL_SPACING / 2, 0, hole = false); + bearing_laser(REEL_SPACING_X / 2, -REEL_SPACING / 2, 0, hole = false); + + bearing_laser(-REEL_SPACING_X / 2, REEL_SPACING / 2, 0, hole = false); + bearing_laser(-REEL_SPACING_X / 2, -REEL_SPACING / 2, 0, hole = false); +} + +module sprocketed_voids () { + //translate([SPROCKETED_OFFSET, -SPROCKETED_SPACING / 2, 0]) { + //cylinder(r = 6 / 2, h = 50, center = true); + //} + //translate([SPROCKETED_OFFSET, SPROCKETED_SPACING / 2, 0]) { + //cylinder(r = 6 / 2, h = 50, center = true); + //} + bearing_laser(SPROCKETED_OFFSET, SPROCKETED_SPACING / 2, 0, hole=false); + bearing_laser(SPROCKETED_OFFSET, -SPROCKETED_SPACING / 2, 0, hole=false); +} + +module gate () { + H = 20; + GATE_D = 65; + BOX_X = 39; + BOX_Y = 100; + difference () { + intersection () { + translate([-1, 0, 0]) cube([4, 16, H + 4], center = true); + translate([GATE_D / 2 - 3, 0, 0]) cylinder(r = GATE_D / 2, h = H + 4, center = true); + } + translate([0, 0, -2]) cube([50, SLIT, H], center = true); + } + //side walls + translate([8, 10, 0]) rotate([0, 0, 20]) cube([20, 4, H + 4], center = true); + translate([8, -10, 0]) rotate([0, 0, -20]) cube([20, 4, H + 4], center = true); + + translate([BOX_X - 6, 0, 0]) { + difference () { + rounded_cube([BOX_X, BOX_Y, H + 4], d = 6, center = true); + cube([BOX_X - 8, BOX_Y - 8, H + 4 + 1], center = true); + translate([-BOX_X / 2, 0, 0]) cube([BOX_X, 24, H + 4 + 1], center = true); + translate([BOX_X / 2, 30, -9]) cube([20, 20, 8], center = true); + } + } +} + +module bearing_hobbled_rod () { + RH_CONNECT_R = 4; //inside of bearing + difference () { + cylinder(r = RH_CONNECT_R, h = 30, center = true); + translate([RH_CONNECT_R + 2, 0, 0]) cube([RH_CONNECT_R * 2, RH_CONNECT_R * 2, 31], center = true); + } +} + +module motor_hobbled_rod (h = 11) { + difference () { + translate([0, 0, 0]) cylinder(r = 5.9 / 2, h = h, center = true, $fn = 24); + translate([5.3, 0, 0]) cube([6, 6, h + .1], center = true); + } +} + +module motor_15RPM (DEBUG = false) { + H = 52; + ROD = 16; + difference () { + union(){ + cylinder(r = 37 / 2, h = H, center = true); + translate([0, -6, -(H / 2) - (6 / 2 )]) cylinder(r = 6, h = 6, center = true); + translate([0, -6, -(H / 2) - 6 - (ROD / 2)]) motor_hobbled_rod(ROD); + } + if (DEBUG) { + translate([50, 0, 0]) cube([100, 100, 100], center = true); + } + } +} + +module gears_to_cut () { + //http://hessmer.org/gears/InvoluteSpurGearBuilder.html + //settings 12 and 24 gears + //render with projection() + + GEAR_2_CENTER = 57.8 + 8.6; + difference () { + scale([INVOLUTE_SCALE, INVOLUTE_SCALE, INVOLUTE_SCALE]) { + union () { + linear_extrude(height = 1) import("../dxf/InvoluteGear_1.dxf"); + translate([0, 0, 0.5]) cube([20, 20, 1], center = true); + translate([GEAR_2_CENTER / INVOLUTE_SCALE, 0, 0.5]) cube([20, 20, 1], center = true); + } + } + bearing_hobbled_rod(); + translate([GEAR_2_CENTER, 0, 0]) { + //bearing_hobbled_rod(); + motor_hobbled_rod(); + } + } + //find gear 2 center + //translate([GEAR_2_CENTER, 0, 0])cylinder(r = 3, h = 30, center = true); +} + +module gears_to_cut_2 () { + //http://hessmer.org/gears/InvoluteSpurGearBuilder.html + //settings 20 and 12 gears + //render with projection() + + GEAR_2_CENTER = 40.75; + ORIENTATION = 0; + difference () { + union () { + linear_extrude(height = 1) import("../dxf/InvoluteGear_2.dxf"); + } + motor_hobbled_rod(); + translate([GEAR_2_CENTER, 0, 30]) { + rotate([180, 0, ORIENTATION]) contact_printer_roller(); + } + } + //find gear 2 center + //translate([GEAR_2_CENTER, 0, 0])cylinder(r = 1/2, h = 30, center = true); +} + +module drive_gear_cap () { + difference () { + union () { + cylinder(r = 5, h = 5, center = true); + translate([0, 0, -(5 / 2) + (1.5 / 2)]) cylinder(r = 8, h = 1.5, center = true); + } + motor_hobbled_rod(11); + } +} + +module temp_inner_walls () { + difference () { + cube([INNER_BOX_X, INNER_BOX_Y, INNER_BOX_Z], center = true); + cube([INNER_BOX_X - (25.4 / 2), INNER_BOX_Y - (25.4 / 2), INNER_BOX_Z + 1], center = true); + } +} + +module temp_outer_walls () { + difference () { + cube([OUTER_BOX_X, OUTER_BOX_Y, OUTER_BOX_Z], center = true); + cube([OUTER_BOX_X - (25.4 / 2), OUTER_BOX_Y - (25.4 / 2), OUTER_BOX_Z + 1], center = true); + } +} + +module temp_bottom () { + difference () { + cube([OUTER_BOX_X, OUTER_BOX_Y, 6], center = true); + } +} + +module elastic_peg_bottom (DEBUG = false) { + difference() { + union () { + cylinder(r = PEG_INNER_D / 2, h = PEG_H, center = true);//inner peg + translate([0, 0, PEG_H / 2 - 1]) cylinder(r = PEG_OUTER_D, h = 2, center = true); + } + if (DEBUG) { + translate([50, 0, 0]) cube([100, 100, 100], center = true); + } + } +} + +module elastic_peg_top (DEBUG = false) { + difference() { + union () { + cylinder(r = PEG_OUTER_D / 2, h = PEG_H, center = true);//inner peg + translate([0, 0, PEG_H / 2 - 1]) cylinder(r = PEG_OUTER_D, h = 2, center = true); + translate([0, 0, -PEG_H / 2 - 1]) cylinder(r = (PEG_OUTER_D / 2) + 2, h = 2, center = true); + } + translate([0, 0, (25.4 / 4)]) cylinder(r = (PEG_INNER_D / 2), h = PEG_H , center = true); + if (DEBUG) { + translate([50, 0, 0]) cube([100, 100, 100], center = true); + } + } +} + +module elastic_peg_voids () { + translate ([PRESURE_PEG_OFFSET, PRESSURE_PEG_SPACING / 2, 0]){ + cylinder(r = (PEG_INNER_D / 2) + .1, h = 50, center = true); + } + translate ([PRESURE_PEG_OFFSET, -PRESSURE_PEG_SPACING / 2, 0]) { + cylinder(r = (PEG_INNER_D / 2) + .1, h = 50, center = true); + } + translate ([BREAK_PEG_SPACING / 2, BREAK_PEG_OFFSET, 0]){ + cylinder(r = (PEG_INNER_D / 2) + .1, h = 50, center = true); + } + translate ([-BREAK_PEG_SPACING / 2, BREAK_PEG_OFFSET, 0]) { + cylinder(r = (PEG_INNER_D / 2) + .1, h = 50, center = true); + } +} + +module reel_holder_bearing () { + $fn = 40; + BASE_D = 14; + //translate([0, 0, -0.9]) cube([3.9, 3.9, 1.9], center = true); + difference() { + translate([0, 0, -0.9]) cylinder(r = 8 / 2, h = 1.9, center = true); + translate([0, 6, -0.9]) cube([8, 8, 1.9], center = true); + } + translate([0, 0, -5.8]) cylinder(r = 8 / 2, h = 8, center = true); + translate([0, 0, -9.9]) cylinder(r = BASE_D / 2, h = 2, center=true); +} + +module reel_holder_breaked () { + BREAK_D = 24; + BREAK_INNER_D = 20; + BREAK_VOID = 6; + reel_holder_bearing(); + + translate([0, 0, -11.5]) cylinder(r = BREAK_D / 2, h = 2, center = true); + translate([0, 0, -11.5 - BREAK_VOID / 2 - 1]) cylinder(r = BREAK_INNER_D / 2, h = BREAK_VOID, center = true); + translate([0, 0, -11.5 - BREAK_VOID - 2]) cylinder(r = BREAK_D / 2, h = 2, center = true); +} + +module break () { + BREAK_INNER_D = 20.5; + BREAK_H = 5; + THICKNESS = 8; + difference() { + cylinder(r = (BREAK_INNER_D / 2) + THICKNESS, h = BREAK_H, center = true); + cylinder(r = BREAK_INNER_D / 2, h = BREAK_H + 1, center = true); + + translate([0, 50, 0]) cube([100, 100, 100], center = true); + } + translate ([(BREAK_INNER_D / 2) + 11, 0, 0]) { + difference () { + translate([-2, 0, 0]) cylinder(r = 9, h = BREAK_H, center = true); + cylinder(r = 3, h = BREAK_H + 1, center = true); + + translate([0, -50, 0]) cube([100, 100, 100], center = true); + } + translate([5, 0, 0]) cylinder(r = 2, h = BREAK_H, center = true); + } + translate ([-(BREAK_INNER_D / 2) - 11, 0, 0]) { + difference () { + translate([2, 0, 0]) cylinder(r = 9, h = BREAK_H, center = true); + cylinder(r = 3, h = BREAK_H + 1, center = true); + + translate([0, -50, 0]) cube([100, 100, 100], center = true); + } + translate([-5, 0, 0]) cylinder(r = 2, h = BREAK_H, center = true); + } +} + +module reel_holder_gear () { + reel_holder_bearing(); + translate([0, 0, -13]) { + difference() { + translate([0, 0, -0.9]) cylinder(r = 8 / 2, h = 24.5 / 4, center = true); + translate([0, 6, -0.9]) cube([8, 8, (24.5 / 4) + 1], center = true); + } + } +} + +module idle_roller_plate () { + //translate([0, 0, -.5]) cube([70, 70, 1], center = true); + translate([0, 0, 1]) roller(); + translate([0, 30, (39.25 / 2) + .6]) idle_roller_peg(); + translate([30, 30, PEG_H / 2 + 2]) idle_roller_peg_top(); + translate([30, 0, 5.5 / 2]) rotate([180, 0, 0]) idle_roller_peg_cap(); +} + +module sprocketed_roller_plate () { + translate([0, 0, 15]) sprocketed_roller_peg(); + translate([20, 0, 4.5]) rotate([180, 0, 0]) sprocketed_roller_peg_cap(); +} + +module plate () { + //translate([0, 0, -.5]) cube([150, 150, 1], center = true); + //pressure elastic_pegs + translate([60, 60, PEG_H / 2]) rotate([180, 0, 0]) elastic_peg_bottom(); + translate([60, 45, (PEG_H / 2) + 2]) elastic_peg_top(); + translate([45, 60, PEG_H / 2]) rotate([180, 0, 0]) elastic_peg_bottom(); + translate([45, 45, (PEG_H / 2) + 2]) elastic_peg_top(); + //break elastic_pegs + translate([30, 60, PEG_H / 2]) rotate([180, 0, 0]) elastic_peg_bottom(); + translate([30, 45, (PEG_H / 2) + 2]) elastic_peg_top(); + translate([15, 60, PEG_H / 2]) rotate([180, 0, 0]) elastic_peg_bottom(); + translate([15, 45, (PEG_H / 2) + 2]) elastic_peg_top(); + //reel holders + translate([60, 25, 15.25]) reel_holder(); + translate([40, 25, 15.25]) reel_holder(); + translate([20, 25, 15.25]) reel_holder(); + translate([00, 25, 15.25]) reel_holder(); +} + +module sprocketed_roller_mold () { + //sprocketed_roller(); + //translate([0, 0, 5]) cube([32, 32, 22],center=true); + //(CUBE = [100, 200, 50], MATERIAL = 3, SIDE_TABS = 1, BOTTOM = true, BOTTOM_TABS = 3, TOP = true, TOP_TABS = 4, PADDING = 4, PROJECTION = false) + Box2D([32, 32, 22], MATERIAL = 3, SIDE_TABS = 2, BOTTOM = true, BOTTOM_TABS = 2, TOP = false, PROJECTION = true); +} + +module contact_printer (DEBUG = false) { + translate([0, 0, -15]) inner_box(true); + translate ([0, 15, 5 - (25.4 / 8)]) temp_inner_walls(); + translate ([0, 15, -8 + (25.4 / 4) ]) temp_outer_walls(); + //translate ([0, 15, -(25.4 / 4) - 12]) temp_bottom(); + //projection() + //gears_to_cut(); + //translate([0, 0, 20]) reel_holder(); + //rotate([0, 0, 90]) bearing_hobbled_rod(); + + //translate([53, 0, .25]) gate(); + + translate ([PRESURE_PEG_OFFSET, PRESSURE_PEG_SPACING / 2, -14.25]) { + elastic_peg_bottom(); + translate([0, 0, -25.4 / 4 - 2.2]) elastic_peg_top(); + } + + translate ([PRESURE_PEG_OFFSET, -PRESSURE_PEG_SPACING / 2, -14.25]) { + elastic_peg_bottom(); + translate([0, 0, -25.4 / 4 - 2.2]) elastic_peg_top(); + } + + translate ([BREAK_PEG_SPACING / 2, BREAK_PEG_OFFSET, -14.25]) { + elastic_peg_bottom(); + translate([0, 0, -25.4 / 4 - 2.2]) elastic_peg_top(); + } + + translate ([-BREAK_PEG_SPACING / 2, BREAK_PEG_OFFSET, -14.25]) { + elastic_peg_bottom(); + translate([0, 0, -25.4 / 4 - 2.2]) elastic_peg_top(); + } + + //negative feed + translate([REEL_SPACING_X / 2, -REEL_SPACING / 2, 0]) { + translate([0, 0, 1]) daylight_spool(); + translate([0, 0, REEL_HOLDER_Z]) reel_holder(); + //translate([0, 0, -10]) reel_holder_breaked(); + + translate([0, 0, -25.5]) rotate([0, 0, -40]) break(); + } + + //negative takeup + translate([REEL_SPACING_X / 2, REEL_SPACING / 2, 0]) { + translate([0, 0, 1]) daylight_spool(); + translate([0, 0, REEL_HOLDER_Z]) reel_holder(); + translate([0, 0, -10]) reel_holder_gear(); + } + + //print stock feed + translate([-REEL_SPACING_X / 2, -REEL_SPACING / 2, 0]) { + translate([0, 0, 1]) daylight_spool(); + if (DEBUG) { + translate([0, 0, 1]) color([1, 1, 1, .5]) cylinder(r = 150, h = 16, center = true); + } + translate([0, 0, REEL_HOLDER_Z]) reel_holder(); + //translate([0, 0, -10]) reel_holder_breaked(); + + translate([0, 0, -25.5]) rotate([0, 0, 40]) break(); + } + + //print stock takeup + translate([-REEL_SPACING_X / 2, REEL_SPACING / 2, 0]) { + //translate([0, 0, 1]) daylight_spool(); + translate([0, 0, REEL_HOLDER_Z]) reel_holder(); + translate([0, 0, -10]) reel_holder_gear(); + } + + translate([IDLE_OFFSET - 7, (IDLE_SPACING / 2) - 7, -9]) { + roller(); + translate([0, 0, 5]) idle_roller_peg(); + translate([0, 0, -14]) idle_roller_peg_top(); + translate([0, 0, 23]) idle_roller_peg_cap(); + } + translate([IDLE_OFFSET, -(IDLE_SPACING / 2), -9]) { + translate([0, 0, 0.5]) roller(DEBUG); + translate([0, 0, 5]) idle_roller_peg(); + translate([0, 0, -14]) idle_roller_peg_top(DEBUG); + translate([0, 0, 23.5]) idle_roller_peg_cap(DEBUG); + } + + translate([SPROCKETED_OFFSET, -SPROCKETED_SPACING / 2, SPROCKETED_Z]) { + rotate([180, 0 ,0]) { + //difference () { + contact_printer_roller(); + //translate([50, 0, 0]) cube([100, 100, 100], center = true); + //} + } + //translate([0, 0, -15]) sprocketed_roller_peg(); + //translate([0, 0, -3]) sprocketed_roller_peg_cap(); + } + translate([SPROCKETED_OFFSET, SPROCKETED_SPACING / 2, SPROCKETED_Z]) { + rotate([180, 0 ,0]) contact_printer_roller(); + //translate([0, 0, -15]) sprocketed_roller_peg(); + //translate([0, 0, -3]) sprocketed_roller_peg_cap(); + } + + //find motor mount point + //translate([0, 157, 0]) cylinder(r = 3, h = 100, center = true); + //takeup motor + translate([0, 157 + 6 + 1.25, 14 + .5]) motor_15RPM(); + translate([0, 0, 14.5]) rotate([0, 0, 90]) motor_15RPM(); + + echo("ROTATING GEARS"); + echo(INVOLUTE_ROTATE); + translate([-REEL_SPACING_X / 2, REEL_SPACING / 2, -23]) rotate([0, 0, INVOLUTE_ROTATE]) gears_to_cut(); + //translate([REEL_SPACING_X / 2, REEL_SPACING / 2, -23]) rotate([0, 0, 180 - INVOLUTE_ROTATE ]) gears_to_cut(); + + //translate([75, 0, -15]) light_source(); +} + +module reel_holder_plate () { + reel_holder(); + translate([0, 20, 0]) reel_holder(); + translate([20, 20, 0]) reel_holder(); + translate([20, 0, 0]) reel_holder(); +} + +//corner pieces for outer box to support inner box +/* +___________ +|/ \| +| | +|\_______/| +*/ +module spacer () { + H = 16.3; + W = 25; + difference () { + rotate([0, 0, 45]) cube([W, W, H], center = true); + translate([150, 0, 0]) cube([300, 300, 300], center = true); + } +} + +module four_point_connector () { + $fn = 120; + X = 35; + Y = 40; + H = 8.5; + Z = ((H - 6) / 2) - 1; + translate([0, 0, -4.5]) { + difference () { + //plate + rounded_cube([X + 5.6 + 2, Y + 5.6 + 2, 3], d = 2.8 * 2, center = true); + //negative + rounded_cube([X - 7, Y - 7, 4], d = 20, center = true); + } + } + translate([X / 2, Y / 2, Z + 2.5]) cylinder(r = 2.8, h = H + 5, center = true); + translate([X / 2, -Y / 2, Z + 2.5]) cylinder(r = 2.8, h = H + 5, center = true); + + translate([-X / 2, Y / 2, Z + .5]) cylinder(r = 2.8, h = H + 1, center = true); + translate([-X / 2, -Y / 2, Z + .5]) cylinder(r = 2.8, h = H + 1, center = true); +} + +//contact_printer(); +/*projection() { + intersection () { + inner_box(); + translate([30, 0, 0]) cube([130, 160, 50], center = true); + } +}*/ +//translate([23, 0, 0]) cube([35, 45, 5], center = true); +//translate([8, 0, -26]) rotate([0, 0, 34]) import("/home/mathias/Desktop/InvoluteGear_2.dxf"); +//translate([20, 0, -20]) cube([41.6, 0.5, 2], center = true); +//translate([0, 0, 6]) outer_box(); +//translate([57.5, 0, 0]) four_point_connector(); +translate([40, 0, LAMP_Z]) rotate([0, 0, -90]) { + lamp_plate(); + //light_housing(); + //light_housing(); +} +//reel_holder_plate(); +//reel_holder(); +//translate([60, 45, PEG_H / 2]) rotate([180, 0, 0]) elastic_peg_top(); +//reel_holder_breaked(); +//projection() gears_to_cut(); +//projection() gears_to_cut_2(); +//drive_gear_cap(); +//break(); +//sprocketed_roller(); +//sprocketed_roller_plate(); +//projection() +//translate([0, 0, 15 - 6]) inner_box(true); +//projection() outer_box(); +//idle_roller_plate(); +//plate(); +//roller(); +//light_source(); +//spacer(); +//contact_printer_roller(); + +//sprocketed_roller_mold(); \ No newline at end of file diff --git a/scad/contact_printer_block.scad b/scad/contact_printer_block.scad new file mode 100644 index 0000000..bbb5cf6 --- /dev/null +++ b/scad/contact_printer_block.scad @@ -0,0 +1,8 @@ +difference () { + union () { + translate([0, 0, 9.5/4]) cube([25.4, 9.5 * 2, 25.4 + (9.5 / 2)], center = true); + translate([0, (25.4 * 3) / 2, 0]) cube([25.4, 25.4 * 3, 25.4], center = true); + } + cube([25.4, 9.7, 25.4], center = true); + translate([5, 9.5 + (25.4 * 3) / 2, 14]) rotate([0, 45, 0]) cube([25.4 * 2, 25.4 * 3, 25.4], center = true); +} diff --git a/scad/contact_printer_dial.scad b/scad/contact_printer_dial.scad new file mode 100644 index 0000000..c5d45ac --- /dev/null +++ b/scad/contact_printer_dial.scad @@ -0,0 +1,40 @@ +include <../readyCAD/ready.scad> + +in = 25.4; +$fn = 100; +module arrow () { + difference () { + cube([20, 10, 15], center=true); + translate([0, 0, 5]) rotate([0, 20, 0]) cube([230, 10, 15], center=true); + translate([0, -8, 0]) rotate([0, 0, 15]) cube([230, 10, 15], center=true); + translate([0, 8, 0]) rotate([0, 0, -15]) cube([230, 10, 15], center=true); + } +} + +module dial () { + rod_d = (3/8) * in; + outer_d1 = 58; + outer_d2 = 48; + + dial_d1 = 30; + dial_d2 = 25; + dial_h2 = 10; + + dial_h = 15; + difference () { + union(){ + translate([0, 0, dial_h/2]) cylinder(r1 = outer_d1/2, r2 = outer_d2/2, h = dial_h, center =true); + translate([0, 0, dial_h + (dial_h2/2)]) cylinder(r1 = dial_d1/2, r2 = dial_d2/2, h = dial_h2, center =true); + translate([33, 0, 7.5]) arrow(); + } + translate([0, 0, rod_d/2 - .5]) cylinder(r = rod_d/2, h = rod_d, center=true); + translate([rod_d - .5, 0, rod_d/2 - .5]) cube([rod_d, 3, rod_d], center=true); + translate([rod_d + 2.5, 0, rod_d/2 - .5]) cube([4, (in/4) + 2, rod_d], center=true); + } +} + +//intersection(){ + dial(); + rotate([0, 0, 20]) decoys(41, 2, 7); + //translate([0, 5.5, 7]) cube([32, 11, 14], center=true); +//} diff --git a/scad/contact_printer_light_holder.scad b/scad/contact_printer_light_holder.scad new file mode 100644 index 0000000..228070d --- /dev/null +++ b/scad/contact_printer_light_holder.scad @@ -0,0 +1,131 @@ +include <../ReadyCAD/ready.scad>; + +OUTER_D = 44.45; +CAP_D = 57.15; +WALL_THICKNESS = 3; +LENGTH = 95.25; +$fn = 100; + +module rail_neg () { + cube([17.4, 4, 120], center = true); + cube([35, 4, 95], center = true); + + translate([17.4, -1.5, 0]) cube([17.5, 4, 96], center = true); + translate([-17.4, -1.5, 0]) cube([17.5, 4, 96], center = true); +} + +module rail_guide () { + translate([10.2, 0, 0]) cube([3, 4, 72], center = true); + translate([-10.2, 0, 0]) cube([3, 4, 72], center = true); + translate([10.2 - .6, 1.5, 0]) cube([4.3, 1, 72], center = true); + translate([-10.2 + .6, 1.5, 0]) cube([4.3, 1, 72], center = true); +} + +module fan_holes () { + dist = 29; + cylinder(r = 34/2, h = 500, center = true); + translate([dist/2, dist/2, 0]) cylinder(r = 2.9/2, h = 500, center = true); + translate([dist/2, -dist/2, 0]) cylinder(r = 2.9/2, h = 500, center = true); + //translate([-dist/2, -dist/2, 0]) cylinder(r = 2.9/2, h = 500, center = true); + translate([-dist/2 + 2.1, -dist/2 + 2.1, 0]) rotate([0, 0, 45]) cube([5, 5, 500], center = true); + translate([-dist/2, dist/2, 0]) cylinder(r = 2.9/2, h = 500, center = true); +} + +module light_holder (DECOYS = false) { + //cap + $fn = 200; + difference () { + translate([0,0,(LENGTH / 2) + (WALL_THICKNESS / 2) ]) { + cylinder(r = CAP_D / 2, h = WALL_THICKNESS, center = true); + } + translate([0, 22, 0]) rail_neg(); + fan_holes(); + } + + //tube + difference () { + cylinder(r = OUTER_D / 2, h = LENGTH, center = true); + cylinder(r = (OUTER_D / 2) - WALL_THICKNESS, h = LENGTH + 10, center = true); + translate([0, 22, 0]) rail_neg(); + //light + translate([0, 20, -41 + 6]) rotate([90, 0, 0]) cylinder(r = 13/2, h = 25, center = true); + } + //rail + translate([0, 20.5, 12]) rail_guide(); + if (DECOYS) { + decoys(36, 48.6, 6); + } +} +module rail (DECOYS = false) { + difference () { + union () { + translate([0, 20.7, 2.4]) cube([17, 1.3, 100], center = true); + translate([0, 21.9, 2.4]) cube([14.2, 2.8, 100], center = true); + } + translate([0, 20, -41 + 6]) rotate([90, 0, 0]) cylinder(r = 9/2, h = 25, center = true); + translate([0, 23.4, -41 + 6]) rotate([90, 0, 0]) cylinder(r = 13/2, h = 3, center = true); + } + translate([0, 24, 52.2]) cube([24, 8, 3], center = true); + if (DECOYS) { + translate([0, 0, -35]) rotate([90, 45, 0]) decoys(25, -22.05); + translate([0, 0, 42]) rotate([90, 45, 0]) decoys(25, -22.05); + } +}; + +module baffle (DECOYS = false) { + //print 3 of these + difference () { + cylinder(r = (OUTER_D / 2) - WALL_THICKNESS - 0.3, h = 7, center = true); + cylinder(r = (OUTER_D / 2) - WALL_THICKNESS - 2, h = 8, center = true); + } + difference () { + translate([0, 0, 2.5]) cylinder(r = (OUTER_D / 2) - WALL_THICKNESS - 0.3, h = 2, center = true); + translate([58, 0, 0]) cube([100, 100, 100], center = true); + } + if (DECOYS) { + decoys(28, 1.5, 6); + } +} + +module LED_mount () { + $fn = 200; + difference () { + cylinder(r = (OUTER_D / 2) - WALL_THICKNESS - 0.015, h = 10, center = true); + cylinder(r = (OUTER_D / 2) - WALL_THICKNESS - 0.015 - 2, h = 11, center = true); + translate([0, (OUTER_D / 2) +4, 0]) cube([OUTER_D, OUTER_D, OUTER_D], center = true); + } + translate ([0, 0, -4.5]) { + intersection() { + difference () { + cylinder(r = (OUTER_D / 2) - WALL_THICKNESS - 0.015, h = 15, center = true); + cylinder(r = (OUTER_D / 2) - WALL_THICKNESS - 0.015 - 2, h = 16, center = true); + } + translate ([0, -17, -1]) cube([7, 7, 15], center = true); + } + } + difference () { + union () { + difference () { + translate([0, -6, 0]) cube([OUTER_D - 8, 2, 10], center = true); + translate([OUTER_D / 2 - 3.5, -6.5, 0]) rotate([0, 0, 60]) cube([4, 2, 10], center = true); + translate([-OUTER_D / 2 + 3.5, -6.5, 0]) rotate([0, 0, -60]) cube([4, 2, 10], center = true); + } + translate([7.5, -5, 0]) cube([4, 4, 10], center = true); + translate([-7.5, -5, 0]) cube([4, 4, 10], center = true); + } + translate([7.5, 0, 0]) rotate([90, 0, 0]) cylinder(r = 1, h = 40, center = true); + translate([0, 0, 0]) rotate([90, 0, 0]) cylinder(r = 1, h = 40, center = true); + translate([-7.5, 0, 0]) rotate([90, 0, 0]) cylinder(r = 1, h = 40, center = true); + } + translate([0, -8, 0]) scale([1.5, 1, 1]) decoys(20, 3); +} + +//rail(true); +/*difference() { + light_holder(false); + //translate([0, 0, -36]) LED_mount(); + translate([0, 0, 60]) cube([200, 200, 200], center = true); +} +decoys(30, -45.64, 6);*/ + +baffle(); \ No newline at end of file diff --git a/scad/lamp.scad b/scad/lamp.scad new file mode 100644 index 0000000..e3e3025 --- /dev/null +++ b/scad/lamp.scad @@ -0,0 +1,346 @@ +$fn = 80; + +include <../readyCAD/ready.scad>; +include <./16mm_sprocketed_roller_var.scad>; + + BRACE_L = 24; + PLATE_L = 47; + Z = 36; + X = 45; + OUTER_W = 34; + INNER_W = 22.3; + +module roller_base (X = 40) { + BEARING_OUTER_D = 22; + + BEARING_INNER_D = 8; + R = BEARING_OUTER_D / 2; + BEARING_H = 10; + EXTRA_1 = 1; + EXTRA_2 = 3; + + TEST_PAD = X; + MOUNT_HOLES = 27; + + OFFSET_H = 2; + + //cylinder(r = R, h = BEARING_H, center = true); + translate ([0, 0, -(BEARING_H / 2) - 1]) { + difference() { + translate([0, 0, -1]) cylinder(r = R + EXTRA_2, h = OFFSET_H, center = true); + cylinder(r = BEARING_OUTER_D / 2, h = OFFSET_H + 1, center = true); + } + } + translate ([0, 0, -(BEARING_H / 2) - (OFFSET_H / 2) - 2]) { + cylinder(r = TEST_PAD / 2.5, h = 2, center = true); + } +} + +module lamp_plate() { + //middle + difference () { + union () { + //round sides + translate([X / 2, 0, 0]) roller_base(X); + translate([-X / 2, 0, 0]) roller_base(X); + //corners + translate([12 + X / 2, 9, -8]) cube([PLATE_L / 2, PLATE_L / 2, 2], center = true); + translate([-12 - X / 2, 9, -8]) cube([PLATE_L / 2, PLATE_L / 2, 2], center = true); + //middle flat plane + translate([0, 0, -8]) cube([X, Z, 2], center = true); + //back flat plane + translate([0, Z, -8]) { + difference () { + cube([X + PLATE_L, Z, 2], center = true); + //back corner voids + translate([32, 5, 0]) cube([30, Z + 1, 3], center = true); + translate([-32, 5, 0]) cube([30, Z + 1, 3], center = true); + //void for lamp housing + translate([0, 0, 0]) cube([34.15, Z + 1, 3], center = true); + } + } + } + //laser voids + translate([X / 2, 0, 0]) cylinder(r = 22 / 2, h = 31, center = true); + translate([-X / 2, 0, 0]) cylinder(r = 22 / 2, h = 31, center = true); + } + + //pegs for corners + translate ([41, 20 - 4.5, 4 - 6]) { + difference () { + cylinder(r = 3 - .2, h = 12, center = true); + translate([0, 7, 0]) cube([10, 10, 50], center = true); + } + translate([0, 0, -6 + 2.4]) cylinder(r1 = 4, r2 = 3 - .2, h = 3, center =true); + } + translate ([-41, 20 - 4.5, 4 - 6]) { + difference () { + cylinder(r = 3 - .2, h = 12, center = true); + translate([0, 7, 0]) cube([10, 10, 50], center = true); + } + translate([0, 0, -6 + 2.4]) cylinder(r1 = 4, r2 = 3 - .2, h = 3, center =true); + } + //slide holder + +} + +module light_housing () { + color("red") translate([0, 32, -8]) cube([34, 28, 2], center = true); + translate([0, 31, 3]) { + difference () { + cube([OUTER_W, 15 + 8, BRACE_L], center = true); + cube([INNER_W, 15 + 8 + 1, BRACE_L + 1], center = true); + //set screw holes + translate([0, -7, 7]) rotate([0, 90, 0]) cylinder(r = 1, h = 50, center = true, $fn = 40); + //gaps for slide wings + translate([(INNER_W / 2) + 1, (BRACE_L / 2) - 10, 3]) color("green") cube([2, BRACE_L, 20], center = true); + translate([-(INNER_W / 2) - 1, (BRACE_L / 2) - 10, 3]) color("green") cube([2, BRACE_L, 20], center = true); + } + + } + //light + acrylic holder + translate([0, 45, 5]) { + rotate([0, 0, 180]) light_holder(); + translate([0, -7.5, -11.5]) cube([10, 17, 2], center = true); + + translate([0, -1.5, -1]) { + difference () { + cube([OUTER_W, 2, 22], center = true); + cube([9, 2, 22], center = true); + } + } + } + //extended tabs from light housing + translate([20, 35.5, -4]) { + difference () { + union () { + cylinder(r = 5, h = 10, center = true, $fn = 60); + translate([-2.5, 0, 0]) cube([5, 10, 10], center = true); + } + // + difference() { + cylinder(r = 3.05, h = 20, center = true); + translate([-4, 0, 0]) cube([6, 6, 21], center = true); + } + } + } + translate([-20, 35.5, -4]) { + difference() { + union () { + cylinder(r = 5, h = 10, center = true, $fn = 60); + translate([2.5, 0, 0]) cube([5, 10, 10], center = true); + } + // + difference() { + cylinder(r = 3.05, h = 20, center = true); + translate([4, 0, 0]) cube([6, 6, 21], center = true); + } + } + } + +} + +module lamp_plate_attached () { + difference () { + lamp_plate(.2); + translate([0, 18, -6 - 5.5]) rotate([0, 0, 90]) four_point_connector(); + } +} + +module corner () { + H = 22; + W = 26; + L = 19; + D = 36; + difference () { + translate([3, 3, 0]) cube([L, W, H], center = true); + //top negative + translate ([-12, -12, 0]) cylinder(r = D / 2, h = H + 1, center = true); + //inner negative + translate ([-10.2, -6, -2.5]) cylinder(r = D / 2, h = H + 1, center = true); + //pin + translate ([7, 9, -(H / 4) - .01]) { + difference() { + cylinder(r = 3.1, h = H / 2, center = true); + translate([0, 7, 0]) cube([10, 10, 50], center = true); + } + //pyramidic cylinder + translate ([0, 0, -4.01]) cylinder(r1 = 4, r2 = 3 - .2, h = 3, center =true); + } + + translate([10, -10, 0]) rotate([0, 0, 8]) cube([10, 10, 40], center = true); + } +} + +module lamp_front () { + + R = 70; + T = 2; + W = 22; + H = 22; + + SLIDE_L = 15; + BOT_H = 2; + + translate ([0, R, 0]) { + difference () { + intersection () { + difference () { + cylinder(r = R, h = H, center = true, $fn = 360); + cylinder(r = (R - T), h = H + 1, center = true, $fn = 360); + } + translate([0, -R, 0]) cube([W, W, H], center = true); + } + //gate gap + translate([0, -R, 0]) cube([6, W + 1, 18], center = true); + translate ([0, -R - .5, 0]) cube([80, 2, 16.25], center = true); + } + translate([0, -R, 0]) { + //slide sides + translate([(W / 2) - (T / 2), (SLIDE_L / 2) + (T / 2), 0]) { + cube([T, SLIDE_L, H], center = true); + translate([2, 5.25, 1.5]) cube([2, 4.5, 19], center = true); + } + translate([-(W / 2) + (T / 2), (SLIDE_L / 2) + (T / 2), 0]){ + cube([T, SLIDE_L, H], center = true); + translate([-2, 5.25, 1.5]) cube([2, 4.5, 19], center = true); + } + + + //bottom + translate([0, (SLIDE_L / 2) + (T / 2), -(H / 2) + (BOT_H / 2) ]) { + difference () { + cube([W - (T * 2), SLIDE_L, BOT_H], center = true); + translate([0, 8, 0]) cube([11, SLIDE_L, BOT_H + 1], center = true); + } + } + + } + } +} + +module gate (TYPE = "full", WIDTH = 2) { + $fn = 600; + R = 70 - 2; + T = 2; + W = 17.8; + H = 20; + difference () { + union() { + intersection () { + difference () { + cylinder(r = R, h = H, center = true); + cylinder(r = (R - T), h = H + 1, center = true); + } + translate([0, -R, 0]) cube([W, W, H], center = true); + } + translate([0, -R + 3, 0]) cube([W, T, H], center = true); + translate([0, -R - 0.5, -1]) cube([5.9, 2, 17.9], center = true); + } + if (TYPE == "full") { + translate([0, -R, -.5]) cube([WIDTH, 20, 16], center = true); + } + } +} + + + +module ws2812b (H = 1.4) { + W = 4.91 + .25; + Z = H; + + cube([W, W, Z], center = true); +} + +module light_holder () { + // + difference () { + translate([0, 0, 0]) cube([10, 2, 18 + 4], center = true); + rotate ([90, 0, 0]) { + ws2812b(9); + translate([0,6.75,0]) ws2812b(9); + translate([0,-6.75,0]) ws2812b(9); + } + } + difference () { + translate([0, 8.5, -1]) color("blue") cube([10, 15, 18 + 2], center = true); + translate([0, 8.501, 0.01]) cube([6, 65, 18], center = true); + } +} + + +module acrylic_piece (PROJ = false) { + H = 18; + W = 6; + L = 15; + + if (PROJ) { + projection() cube([H, L, W], center = true); + } else { + cube([W, L, H], center = true); + } +} + +//sync with other file +module four_point_connector (fuzz = 0) { + $fn = 120; + X = 35; + Y = 40; + H = 8.5; + Z = ((H - 6) / 2) - 1; + translate([0, 0, -4.5]) { + difference () { + //plate + rounded_cube([X + 5.6 + 2, Y + 5.6 + 2, 3], d = 2.8 * 2, center = true); + //negative + rounded_cube([X - 7, Y - 7, 4], d = 20, center = true); + } + } + translate([X / 2, Y / 2, Z + 2.5]) cylinder(r = 2.8 + fuzz, h = H + 5, center = true); + translate([X / 2, -Y / 2, Z + 2.5]) cylinder(r = 2.8 + fuzz, h = H + 5, center = true); + + translate([-X / 2, Y / 2, Z + .5]) cylinder(r = 2.8 + fuzz, h = H + 1, center = true); + translate([-X / 2, -Y / 2, Z + .5]) cylinder(r = 2.8 + fuzz, h = H + 1, center = true); +} + +//translate([22.5, 0, 0]) contact_printer_roller(); +//translate([-20, 0, 0]) contact_printer_roller(); + +module lamp_cover () { + difference () { + //base solid + cube([40, 35, 7], center = true); + //inner negative + translate([0, -3, -2]) cube([34.2, 35, 7], center = true); + //lamp/led negative + translate([0, 3, -.75]) cube([10, 35, 6], center = true); + //front side negative + translate([19, -18, 0]) cube([15, 15, 10], center = true); + translate([-19, -18, 0]) cube([15, 15, 10], center = true); + //screws negative + translate([0, -6, -3.5]) rotate([0, 90, 0]) cylinder(r = 3.5, h = 50, center = true); + } +} +//corner(); +translate ([0, 0, 11]) { + rotate([0, 180, 0]) { + //difference() { + //lamp_plate(); + //translate([250, 0, 0]) cube([500, 500, 500], center = true); + //rotate([0, 0, 60]) translate([255, 0, 0]) cube([500, 500, 500], center = true); + //} + //translate([0, 30, 14]) lamp_cover(); + //lamp_plate_attached(); + //translate([0, 18, -6 - 6]) rotate([0, 0, 90]) four_point_connector(); + //translate ([34, 6.5, 24]) corner(); + //translate ([-34, 6.5, 24]) mirror() corner(); + + //film plane + //#translate ([0, 16, 4.5]) color("yellow") cube([80, 0.4, 16], center = true); + //moves up to 2.5mm forward + //translate ([0, 16 - 2.5, 4]) color("blue") lamp_front(); + //translate ([0, 86.1, 5]) gate(WIDTH = 1); + //acrylic_piece(true); + } + //translate([0, 0, 12]) cube([90, 90, 6], center = true); +}