├── .gitignore
├── docs
├── code
│ ├── README.md
│ ├── config.js
│ ├── metric.md
│ ├── hardware.md
│ └── imperial.md
├── .vuepress
│ ├── dist
│ │ ├── assets
│ │ │ ├── js
│ │ │ │ ├── 9.e4b84b16.js
│ │ │ │ ├── 5.13c5e1fd.js
│ │ │ │ ├── 3.fe9e1b4e.js
│ │ │ │ ├── 4.7d932259.js
│ │ │ │ ├── 8.362e9d24.js
│ │ │ │ ├── 7.02f8640a.js
│ │ │ │ └── 6.4b3ce8a0.js
│ │ │ ├── img
│ │ │ │ └── search.83621669.svg
│ │ │ └── css
│ │ │ │ └── 0.styles.617c345f.css
│ │ ├── 404.html
│ │ └── code
│ │ │ ├── index.html
│ │ │ ├── metric.html
│ │ │ ├── imperial.html
│ │ │ └── hardware.html
│ └── config.js
└── README.md
├── githubdocs
├── _config.yml
├── bolt.png
├── imgs
│ └── busy.gif
├── jscad-hardware.png
├── themes
│ └── architect
│ │ ├── images
│ │ ├── body-bg.jpg
│ │ ├── header-bg.jpg
│ │ ├── sidebar-bg.jpg
│ │ ├── github-button.png
│ │ ├── download-button.png
│ │ └── hr.png
│ │ └── css
│ │ └── style.css
├── themes.sh
├── layout.css
├── index.tmpl
├── jscad-function.js
├── index.html
├── jscad-worker.js
└── formats.js
├── jscad.json
├── .vscode
└── settings.json
├── test
├── snapshots
│ ├── hardware.js.snap
│ └── hardware.js.md
├── hardware.js
└── helpers
│ └── compat-env.js
├── examples
├── nut.jscad
├── washer.jscad
├── bolt.jscad
└── example.jscad
├── .gitlab-ci.yml
├── src
├── index.js
├── v1compat.js
├── hardware.js
├── metric.js
└── imperial.js
├── .eslintrc.json
├── v1
├── metric.jscad
├── imperial.jscad
└── jscad-hardware.jscad
├── README.md
├── jsdoc2md
└── README.hbs
├── package.json
└── gulpfile.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
3 | public
--------------------------------------------------------------------------------
/docs/code/README.md:
--------------------------------------------------------------------------------
1 | ### Welcome to API
--------------------------------------------------------------------------------
/githubdocs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-architect
--------------------------------------------------------------------------------
/jscad.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": ["dist/index.js"]
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "standard.enable": false
3 | }
--------------------------------------------------------------------------------
/githubdocs/bolt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/bolt.png
--------------------------------------------------------------------------------
/githubdocs/imgs/busy.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/imgs/busy.gif
--------------------------------------------------------------------------------
/githubdocs/jscad-hardware.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/jscad-hardware.png
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/js/9.e4b84b16.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[9],{225:function(n,w,o){}}]);
--------------------------------------------------------------------------------
/test/snapshots/hardware.js.snap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/test/snapshots/hardware.js.snap
--------------------------------------------------------------------------------
/githubdocs/themes/architect/images/body-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/themes/architect/images/body-bg.jpg
--------------------------------------------------------------------------------
/githubdocs/themes/architect/images/header-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/themes/architect/images/header-bg.jpg
--------------------------------------------------------------------------------
/githubdocs/themes/architect/images/sidebar-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/themes/architect/images/sidebar-bg.jpg
--------------------------------------------------------------------------------
/githubdocs/themes/architect/images/github-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/themes/architect/images/github-button.png
--------------------------------------------------------------------------------
/githubdocs/themes/architect/images/download-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnwebbcole/jscad-hardware/HEAD/githubdocs/themes/architect/images/download-button.png
--------------------------------------------------------------------------------
/examples/nut.jscad:
--------------------------------------------------------------------------------
1 | function main() {
2 | util.init(CSG);
3 | var nut = Hardware.Nut(ImperialNuts['1/4 hex'], 'close').color('gray');
4 |
5 | return nut;
6 | }
7 |
8 | // include:js
9 | // endinject
10 |
--------------------------------------------------------------------------------
/examples/washer.jscad:
--------------------------------------------------------------------------------
1 | function main() {
2 | util.init(CSG);
3 | var washer = Hardware.Washer(ImperialWashers['1/4']);
4 |
5 | return washer.combine('washer');
6 | }
7 |
8 | // include:js
9 | // endinject
10 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: node:lts-alpine
2 |
3 | pages:
4 | script:
5 | - npm ci
6 | - npm run docs
7 | - ls -al -R public
8 | artifacts:
9 | paths:
10 | - public
11 | only:
12 | - master
13 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/img/search.83621669.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * JsCad Hardware es6
3 | */
4 | import * as hardware from './hardware';
5 | import * as imperial from './imperial';
6 | import * as metric from './metric';
7 |
8 | export { hardware, imperial, metric };
9 |
10 | // export const Hardware = {
11 | // ...hardware,
12 | // ...imperial,
13 | // ...metric
14 | // };
15 |
--------------------------------------------------------------------------------
/docs/code/config.js:
--------------------------------------------------------------------------------
1 | exports.fileTree=[{"name":"hardware","path":"/hardware","fullPath":"./docs/code/hardware"},{"name":"imperial","path":"/imperial","fullPath":"./docs/code/imperial"},{"name":"metric","path":"/metric","fullPath":"./docs/code/metric"}];exports.sidebarTree = (title = 'Mainpage') => ({"/code/":[{"title":"API","collapsable":false,"children":[["",""+title+""],"hardware","imperial","metric"]}]});
--------------------------------------------------------------------------------
/examples/bolt.jscad:
--------------------------------------------------------------------------------
1 | function main() {
2 | util.init(CSG, { debug: '*' });
3 | var bolt = Hardware.Bolt(util.inch(1), ImperialBolts['1/4 hex'], 'close');
4 | var bolt2 = Hardware.Bolt(
5 | util.inch(1),
6 | MetricBolts['m8 socket'],
7 | 'close'
8 | ).snap('head', bolt.parts.head, 'x', 'outside+', -10);
9 |
10 | return [bolt.combine('head,thread'), bolt2.combine('head,thread')];
11 | }
12 |
13 | // include:js
14 | // endinject
15 |
--------------------------------------------------------------------------------
/test/snapshots/hardware.js.md:
--------------------------------------------------------------------------------
1 | # Snapshot report for `test/hardware.js`
2 |
3 | The actual snapshot is saved in `hardware.js.snap`.
4 |
5 | Generated by [AVA](https://ava.li).
6 |
7 | ## import util
8 |
9 | > Snapshot 1
10 |
11 | [
12 | 'Bolt',
13 | 'Clearances',
14 | 'CreateScrew',
15 | 'FlatHeadScrew',
16 | 'HexHeadScrew',
17 | 'Nut',
18 | 'Orientation',
19 | 'PanHeadScrew',
20 | 'Screw',
21 | 'Washer',
22 | ]
23 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/js/5.13c5e1fd.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[5],{266:function(t,e,s){"use strict";s.r(e);var a=s(38),o=Object(a.a)({},function(){var t=this.$createElement,e=this._self._c||t;return e("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[e("h3",{attrs:{id:"welcome-to-api"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#welcome-to-api","aria-hidden":"true"}},[this._v("#")]),this._v(" Welcome to API")])])},[],!1,null,null,null);e.default=o.exports}}]);
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/js/3.fe9e1b4e.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[3],{239:function(t,e,n){},263:function(t,e,n){"use strict";var i=n(239);n.n(i).a},270:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,e){var n=e.props,i=e.slots;return t("span",{class:["badge",n.type],style:{verticalAlign:n.vertical}},n.text||i().default)}},r=(n(263),n(38)),a=Object(r.a)(i,void 0,void 0,!1,null,"c13ee5b0",null);e.default=a.exports}}]);
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/js/4.7d932259.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[4],{265:function(t,e,s){"use strict";s.r(e);var o=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],n={methods:{getMsg:function(){return o[Math.floor(Math.random()*o.length)]}}},i=s(38),h=Object(i.a)(n,function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"theme-container"},[e("div",{staticClass:"theme-default-content"},[e("h1",[this._v("404")]),this._v(" "),e("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),e("router-link",{attrs:{to:"/"}},[this._v("Take me home.")])],1)])},[],!1,null,null,null);e.default=h.exports}}]);
--------------------------------------------------------------------------------
/test/hardware.js:
--------------------------------------------------------------------------------
1 | import test from 'ava';
2 | // import { nearlyEqual } from './helpers/nearlyEqual';
3 | import * as Hardware from '../src/hardware';
4 | import { ImperialBolts } from '../src/imperial';
5 |
6 | // import { util, init as utilInit } from '@jwc/jscad-utils';
7 | // console.warn('utilInit', utilInit.default);
8 |
9 | test('import util', t => {
10 | // console.log(
11 | // Object.keys(util)
12 | // .map(k => `test.todo('${k}');`)
13 | // .join('\n')
14 | // );
15 |
16 | t.snapshot(Object.keys(Hardware).sort());
17 | });
18 |
19 | // test('imperial bolt', t => {
20 | // // utilInit.default(CSG);
21 | // var bolt = Hardware.Bolt(util.inch(1), ImperialBolts['1/4 hex'], 'close');
22 | // });
23 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true
4 | },
5 | "globals": {
6 | "CSG": true,
7 | "CAG": true,
8 | "echo": true,
9 | "util": true,
10 | "include": true,
11 | "union": true,
12 | "Colors": true,
13 | "RaspberryPi": true,
14 | "Boxes": true,
15 | "Parts": true,
16 | "_": true,
17 | "vector_text": true,
18 | "rectangular_extrude": true,
19 | "_boardutils": true
20 | },
21 | "extends": "eslint:recommended",
22 | "rules": {
23 | "no-console": [2, {"allow": ["warn", "error"]}],
24 | "linebreak-style": [
25 | 2,
26 | "unix"
27 | ],
28 | "quotes": [
29 | 2,
30 | "single"
31 | ],
32 | "semi": [
33 | 2,
34 | "always"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/test/helpers/compat-env.js:
--------------------------------------------------------------------------------
1 | import jsCadCSG from '@jscad/csg';
2 | import scadApi from '@jscad/scad-api';
3 | const { CSG, CAG } = jsCadCSG;
4 | // console.warn('scadApi', scadApi);
5 | // import { init as utilInit } from '@jwc/jscad-utils';
6 | import '@jwc/jscad-utils/dist/compat.js';
7 |
8 | global.CSG = CSG;
9 | global.CAG = CAG;
10 | global.jsCadCSG = jsCadCSG;
11 | global.scadApi = scadApi;
12 | global.vector_text = scadApi.text.vector_text;
13 | global.vector_char = scadApi.text.vector_char;
14 | global.rectangular_extrude = scadApi.extrusions.rectangular_extrude;
15 | global.cube = scadApi.primitives3d.cube;
16 | global.sphere = scadApi.primitives3d.sphere;
17 | global.cylinder = scadApi.primitives3d.cylinder;
18 |
19 | global.union = scadApi.booleanOps.union;
20 | global.jscadUtilsDebug = { enabled: [], disabled: [] };
21 |
22 | util.init(CSG);
23 |
24 | // console.warn('CSG', CSG);
25 | // console.warn('jscadUtils', util, util.init);
26 |
--------------------------------------------------------------------------------
/githubdocs/themes.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 | rm -rf themes
5 | mkdir -p themes
6 |
7 | dl() {
8 | URL=https://pages-themes.github.io/$1/assets/css/style.css
9 | FILE=themes/$1/css/style.css
10 |
11 | mkdir -p themes/$1/css
12 |
13 | curl -Ss $URL -o $FILE && {
14 | echo "$1 ok"
15 | pushd themes/$1/css
16 | for url in `sed -n -e 's/.*url(\([^)]*\).*/\1/p' style.css`; do
17 | # echo "$(dirname $url)"
18 | ASSET=${url//\"}
19 | DIRNAME=$(dirname $ASSET)
20 | echo "downloading $ASSET into $DIRNAME"
21 | mkdir -p $DIRNAME
22 | curl -Ss https://pages-themes.github.io/$1/assets/css/$ASSET -o $ASSET
23 | done
24 | popd
25 | } || {
26 | echo "$1 error$?"
27 | }
28 | }
29 |
30 | dl architect
31 | # dl caymen
32 | # dl dinky
33 | # dl hacker
34 | # dl leap-day
35 | # dl merlot
36 | # dl midnight
37 | # dl minima
38 | # dl minimal
39 | # dl modernist
40 | # dl slate
41 | # dl tactile
42 | # dl time-machine
43 |
--------------------------------------------------------------------------------
/src/v1compat.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | var Hardware,
3 | ImperialBolts,
4 | ImperialNuts,
5 | ImperialWashers,
6 | ImperialWoodScrews,
7 | MetricBolts,
8 | MetricNuts,
9 | MetricWashers,
10 | MetricWoodScrews;
11 | function initJscadHardware() {
12 | var Debug = util.Debug;
13 | var debug = Debug('jscadHardware:initJscadHardware');
14 | var jscadUtils = { util, Debug, parts: Parts, Group };
15 | var jsCadCSG = { CSG, CAG };
16 | debug('initJscadHardware:jscadUtils', jscadUtils);
17 |
18 | // include:compat
19 | // end:compat
20 |
21 | debug('jscadHardware', jscadHardware);
22 | Hardware = jscadHardware.hardware;
23 |
24 | ImperialBolts = jscadHardware.imperial.ImperialBolts;
25 | ImperialNuts = jscadHardware.imperial.ImperialNuts;
26 | ImperialWashers = jscadHardware.imperial.ImperialWashers;
27 | ImperialWoodScrews = jscadHardware.imperial.ImperialWoodScrews;
28 |
29 | MetricBolts = jscadHardware.metric.MetricBolts;
30 | MetricNuts = jscadHardware.metric.MetricNuts;
31 | MetricWashers = jscadHardware.metric.MetricWashers;
32 | MetricWoodScrews = jscadHardware.metric.MetricWoodScrews;
33 | }
34 |
35 | /**
36 | * Add `initJscadHardware` to the init queue for `util.init`.
37 | */
38 | jscadUtilsPluginInit.push(initJscadHardware);
39 | /* eslint-enable */
40 |
--------------------------------------------------------------------------------
/docs/.vuepress/config.js:
--------------------------------------------------------------------------------
1 | // auto generated sidebar
2 | const { fileTree } = require('../code/config');
3 | console.log('foo', fileTree);
4 | module.exports = {
5 | base: process.env.CI ? '/jscad-hardware/' : '/',
6 | dest: 'public',
7 | locales: {
8 | '/': {
9 | title: 'JsCad Hardware',
10 | description: 'jscad parts library for screws, washers and nuts'
11 | }
12 | },
13 |
14 | // plugins: [
15 | // [
16 | // '@vuepress/google-analytics',
17 | // {
18 | // ga: 'UA-135958052-3'
19 | // }
20 | // ]
21 | // ],
22 |
23 | themeConfig: {
24 | nav: [
25 | { text: 'Home', link: '/' },
26 | { text: 'API', link: '/code/' },
27 | { text: 'GitLab', link: 'https://gitlab.com/johnwebbcole/jscad-hardware' }
28 | ],
29 | displayAllHeaders: true,
30 | editLinks: true,
31 | sidebarDepth: 3,
32 | docsDir: 'code',
33 | sidebar: [
34 | ['/', 'Readme'],
35 | // {
36 | // title: 'Home',
37 | // path: '/',
38 | // collapsable: false,
39 | // children: [['/', 'Readme']]
40 | // },
41 | {
42 | title: 'Code',
43 | path: '/code/',
44 | collapsable: false,
45 | children: fileTree.map(api => `/code${api.path}`)
46 | }
47 | ]
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | VuePress
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/v1/metric.jscad:
--------------------------------------------------------------------------------
1 | /* exported MetricBolts, MetricScrews, MetricNuts */
2 | /**
3 | * http://www.atlrod.com/metric-hex-bolt-dimensions/
4 | * E - Body Diameter (D)
5 | * F - Width Across Flats
6 | * G - Width Across Corners (C)
7 | * H - Head Height
8 | * D - Head Diameter
9 | *
10 | * tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
11 | * @type {Object}
12 | */
13 | var MetricBolts = {
14 | 'm10 hex': {
15 | E: 10, // 10-9.78
16 | tap: 8.5,
17 | close: 10.5,
18 | loose: 11,
19 | H: 6.5, // 6.63-6.17
20 | G: 18, // 18.48-17.77
21 | F: 17, // 17-15.73
22 | type: 'HexHeadScrew'
23 | },
24 | 'm12 hex': {
25 | E: 12, // 12-11.73
26 | tap: 10.3,
27 | close: 12.6,
28 | loose: 13.2,
29 | H: 7.5, // 7.76-4.24
30 | G: 20, // 20.78-20.03
31 | F: 19, // 19-17.73
32 | type: 'HexHeadScrew'
33 | }
34 | };
35 |
36 | // headDiameter, headLength, diameter, tap, countersink
37 | var MetricScrews = {
38 | 'm4': [8, 3.1, 4]
39 | };
40 |
41 | /**
42 | * Dimensions of nuts for imperial bolts.
43 | * F is the width across the faces, C is the width
44 | * across the points, and H is the height. D is the
45 | * basic diameter.
46 | *
47 | * [F, C, H, D]
48 | *
49 | * @see https://en.wikipedia.org/wiki/Nut_(hardware)
50 | * @type {Object}
51 | */
52 | var MetricNuts = {
53 | 'm4': [7, 8.1, 3.2, 4]
54 | };
--------------------------------------------------------------------------------
/githubdocs/layout.css:
--------------------------------------------------------------------------------
1 | /*
2 | * layout.css for OpenJSCAD.org viewer
3 | */
4 |
5 | body {
6 | display: flex;
7 | }
8 |
9 | .jscad-container {
10 | }
11 |
12 | #header {
13 | }
14 |
15 | #viewerContext {
16 | background: white;
17 | width: 480px;
18 | height: 340px;
19 | }
20 |
21 | #README {
22 | padding-left: 10px;
23 | flex: 1 1 auto;
24 | }
25 |
26 | canvas {
27 | margin: 0px;
28 | padding: 0px;
29 |
30 | width: 100%;
31 | height: 100%;
32 |
33 | cursor: move;
34 | }
35 |
36 | #parametersdiv {
37 | margin: 5px; /* not inherited */
38 | border: thin solid rgb(200,200,200);
39 | border-radius: 1em;
40 | padding: 10px;
41 |
42 | background: white;
43 | opacity: 0.8;
44 | }
45 |
46 | #parametersdiv table {
47 | margin-bottom: 5px;
48 |
49 | text-align: left;
50 | font-size: 0.8em;
51 | font-weight: normal;
52 | }
53 |
54 | #parametersdiv th {
55 | margin: 0px; /* not inherited */
56 | border: 0px none gray; /* not inherited */
57 | padding: 5px; /* not inherited */
58 |
59 | font-weight: bold;
60 | }
61 |
62 | #parametersdiv th.caption {
63 | text-decoration: underline;
64 | }
65 |
66 | #parametersdiv td.caption {
67 | text-align: right;
68 | font-weight: bold;
69 | }
70 |
71 | #parametersdiv td {
72 | margin: 0px; /* not inherited */
73 | border: 0px none gray; /* not inherited */
74 | padding: 0px; /* not inherited */
75 | }
76 |
77 | #parametersdiv input, #parametersdiv textarea, #parametersdiv select {
78 | font-size: 0.9em;
79 | background: #fea;
80 | border: none;
81 | }
82 |
83 | #updateButton {
84 | margin: 5px; /* not inherited */
85 | border: thin solid Black; /* not inherited */
86 | padding: 2px; /* not inherited */
87 | border-radius: 4px;
88 | background: white;
89 |
90 | margin-left: 1em;
91 | }
92 |
93 | #tail {
94 | margin: 5px; /* not inherited */
95 | }
96 |
97 | #busy {
98 | vertical-align: middle;
99 | }
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.npmjs.org/package/jscad-hardware) [](https://www.npmjs.org/package/jscad-hardware)
2 |
3 | # jscad-hardware
4 |
5 | > https://johnwebbcole.github.io/jscad-hardware/
6 |
7 | 
8 |
9 | This is a collection of jscad parts that model a common Imperial and Metric bolts and washers. These models use the [jscad-utils](https://github.com/johnwebbcole/jscad-utils) library and return jscad-utils [`group` objects](https://github.com/johnwebbcole/jscad-utils#utilgroupnames-objects--object).
10 |
11 |
12 | ## Installation
13 | Install `jscad-hardware` using NPM:
14 |
15 | ```bash
16 | npm install --save jscad-hardware
17 | ```
18 |
19 | ## Basic usage
20 | To use the utilities, you need to include the `jscad-hardware.jscad`.
21 |
22 | ```javascript
23 | include('node_modules/jscad-utils/jscad-utils.jscad');
24 | include('node_modules/jscad-hardware/jscad-hardware.jscad');
25 |
26 | main() {
27 | util.init(CSG);
28 |
29 | var bolt = Hardware.Bolt(
30 | util.inch(1),
31 | ImperialBolts['5/16 hex'],
32 | 'close'
33 | )
34 |
35 | return bolt.combine('head,thread');
36 | }
37 | ```
38 |
39 | ## Yeoman Generator
40 | You can use the [yeoman jscad generator](https://www.npmjs.com/package/generator-jscad) which will create a project that uses this library.
41 |
42 | Once you create your project, install `jscad-hardware`, and run `gulp`. Dragging the `dist` directory into [http://openjscad.org/](http://openjscad.org/) will include this library.
43 |
44 | Modify your `main.jscad` file to return a bolt object.
45 |
46 | ```javascript
47 | function main() {
48 | util.init(CSG);
49 |
50 | var bolt = Hardware.Bolt(
51 | util.inch(1),
52 | ImperialBolts['5/16 hex'],
53 | 'close'
54 | )
55 |
56 | return bolt.combine('head,thread');
57 | }
58 |
59 | // include:js
60 | // endinject
61 | ```
62 |
63 | 
64 |
--------------------------------------------------------------------------------
/jsdoc2md/README.hbs:
--------------------------------------------------------------------------------
1 | [](https://www.npmjs.org/package/jscad-hardware) [](https://www.npmjs.org/package/jscad-hardware)
2 |
3 | # jscad-hardware
4 |
5 | > https://johnwebbcole.github.io/jscad-hardware/
6 |
7 | 
8 |
9 | This is a collection of jscad parts that model a common Imperial and Metric bolts and washers. These models use the [jscad-utils](https://github.com/johnwebbcole/jscad-utils) library and return jscad-utils [`group` objects](https://github.com/johnwebbcole/jscad-utils#utilgroupnames-objects--object).
10 |
11 |
12 | ## Installation
13 | Install `jscad-hardware` using NPM:
14 |
15 | ```bash
16 | npm install --save jscad-hardware
17 | ```
18 |
19 | ## Basic usage
20 | To use the utilities, you need to include the `jscad-hardware.jscad`.
21 |
22 | ```javascript
23 | include('node_modules/jscad-utils/jscad-utils.jscad');
24 | include('node_modules/jscad-hardware/jscad-hardware.jscad');
25 |
26 | main() {
27 | util.init(CSG);
28 |
29 | var bolt = Hardware.Bolt(
30 | util.inch(1),
31 | ImperialBolts['5/16 hex'],
32 | 'close'
33 | )
34 |
35 | return bolt.combine('head,thread');
36 | }
37 | ```
38 |
39 | ## Yeoman Generator
40 | You can use the [yeoman jscad generator](https://www.npmjs.com/package/generator-jscad) which will create a project that uses this library.
41 |
42 | Once you create your project, install `jscad-hardware`, and run `gulp`. Dragging the `dist` directory into [http://openjscad.org/](http://openjscad.org/) will include this library.
43 |
44 | Modify your `main.jscad` file to return a bolt object.
45 |
46 | ```javascript
47 | function main() {
48 | util.init(CSG);
49 |
50 | var bolt = Hardware.Bolt(
51 | util.inch(1),
52 | ImperialBolts['5/16 hex'],
53 | 'close'
54 | )
55 |
56 | return bolt.combine('head,thread');
57 | }
58 |
59 | // include:js
60 | // endinject
61 | ```
62 |
63 | 
64 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.npmjs.org/package/jscad-hardware) [](https://www.npmjs.org/package/jscad-hardware)
2 |
3 | # jscad-hardware
4 |
5 | > https://johnwebbcole.github.io/jscad-hardware/
6 |
7 | 
8 |
9 | This is a collection of jscad parts that model a common Imperial and Metric bolts and washers. These models use the [jscad-utils](https://github.com/johnwebbcole/jscad-utils) library and return jscad-utils [`group` objects](https://github.com/johnwebbcole/jscad-utils#utilgroupnames-objects--object).
10 |
11 | ## Installation
12 |
13 | Install `jscad-hardware` using NPM:
14 |
15 | ```bash
16 | npm install --save @jwc/jscad-hardware
17 | ```
18 |
19 | ## Basic usage
20 |
21 | > Note: these instrucitons are for version 1.
22 |
23 | To use the utilities, you need to include the `jscad-hardware.jscad`.
24 |
25 | ```javascript
26 | include('node_modules/jscad-utils/jscad-utils.jscad');
27 | include('node_modules/jscad-hardware/jscad-hardware.jscad');
28 |
29 | main() {
30 | util.init(CSG);
31 |
32 | var bolt = Hardware.Bolt(
33 | util.inch(1),
34 | ImperialBolts['5/16 hex'],
35 | 'close'
36 | )
37 |
38 | return bolt.combine('head,thread');
39 | }
40 | ```
41 |
42 | ## Yeoman Generator
43 |
44 | You can use the [yeoman jscad generator](https://www.npmjs.com/package/generator-jscad) which will create a project that uses this library.
45 |
46 | Once you create your project, install `jscad-hardware`, and run `gulp`. Dragging the `dist` directory into [http://openjscad.org/](http://openjscad.org/) will include this library.
47 |
48 | Modify your `main.jscad` file to return a bolt object.
49 |
50 | ```javascript
51 | function main() {
52 | util.init(CSG);
53 |
54 | var bolt = Hardware.Bolt(util.inch(1), ImperialBolts["5/16 hex"], "close");
55 |
56 | return bolt.combine("head,thread");
57 | }
58 |
59 | // include:js
60 | // endinject
61 | ```
62 |
63 | 
64 |
--------------------------------------------------------------------------------
/examples/example.jscad:
--------------------------------------------------------------------------------
1 | function main() {
2 | util.init(CSG);
3 |
4 | var ibolts = makeSet(makeBolt, ImperialBolts);
5 | var iwood = makeSet(makeWoodScrew, ImperialWoodScrews);
6 | var mbolts = makeSet(makeBolt, MetricBolts);
7 | var iwasher = makeSet(makeWasher, ImperialWashers);
8 |
9 | return [
10 | union(ibolts)
11 | .center('x')
12 | .translate([0, -50, 0]),
13 | union(iwood)
14 | .center('x')
15 | .translate([0, -25, 0]),
16 | union(mbolts)
17 | .center('x')
18 | .translate([0, 0, 0]),
19 | union(iwasher)
20 | .center('x')
21 | .translate([0, 50, 0])
22 | ];
23 | }
24 |
25 | function makeWasher(washer) {
26 | return Hardware.Washer(washer).combine('washer');
27 | }
28 |
29 | function makeBolt(bolt) {
30 | return Hardware.Bolt(util.inch(1), bolt).combine('head,thread');
31 | }
32 |
33 | function makeWoodScrew(args) {
34 | [h, l, d] = args;
35 | return Hardware.FlatHeadScrew(h, l, d, util.inch(1)).combine();
36 | }
37 |
38 | function makeSet(maker, set, offset, width) {
39 | var g = util.group();
40 | Object.keys(set)
41 | .sort(function(a, b) {
42 | return (set[a].E || set[a].od) > (set[b].E || set[b].od) ? 1 : -1;
43 | })
44 | .slice(0, 10)
45 | .forEach(function(key, idx) {
46 | var item = maker(set[key]);
47 | if (idx == 0) {
48 | g.add(item.translate([0, 0, 0]), key);
49 | } else {
50 | var gsize = util.size(g.combine());
51 | var isize = util.size(item);
52 | g.add(item.translate([gsize.x + isize.x / 2, 0, 0]), key);
53 | }
54 | // var gsize = util.size(g.combine());
55 | // g.translate([gsize.x, 0, 0]);
56 |
57 | // var label = util
58 | // .label(key)
59 | // .fit([width - 5, 10, 10], true)
60 | // .rotateX(90)
61 | // .rotateZ(180)
62 | // .snap(item, 'z', 'outside-')
63 | // .align(item, 'xy')
64 | // .translate([0,0,5]);
65 |
66 | // return item.translate([width * idx, offset, 0]);
67 | });
68 |
69 | return g.combine();
70 | }
71 |
72 | // include:js
73 | // endinject
74 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@jwc/jscad-hardware",
3 | "version": "2.0.2",
4 | "description": "jscad parts library for screws, washers and nuts",
5 | "main": "jscad-hardware.jscad",
6 | "scripts": {
7 | "test": "ava",
8 | "build": "gulp all",
9 | "start": "gulp",
10 | "docs": "vuepress-jsdoc --source ./src --dist ./docs && npx vuepress build ./docs"
11 | },
12 | "keywords": [
13 | "jscad",
14 | "hardware"
15 | ],
16 | "author": {
17 | "name": "John Cole",
18 | "email": "johnwebbcole@gmail.com",
19 | "url": "http://github.com/johnwebbcole@gmail.com"
20 | },
21 | "homepage": "https://github.com/johnwebbcole/jscad-hardware",
22 | "bugs": "https://github.com/johnwebbcole/jscad-hardware/issues",
23 | "repository": {
24 | "type": "git",
25 | "url": "git://github.com/johnwebbcole/jscad-hardware.git"
26 | },
27 | "license": "ISC",
28 | "devDependencies": {
29 | "@babel/core": "^7.5.5",
30 | "@babel/preset-env": "^7.5.5",
31 | "@babel/register": "^7.5.5",
32 | "@vuepress/plugin-active-header-links": "^1.0.3",
33 | "@vuepress/plugin-google-analytics": "^1.0.3",
34 | "ava": "^2.3.0",
35 | "del": "^5.0.0",
36 | "esm": "^3.2.25",
37 | "gulp": "^4.0.2",
38 | "gulp-concat": "^2.6.0",
39 | "gulp-debug": "^4.0.0",
40 | "gulp-eslint": "^6.0.0",
41 | "gulp-inject": "^5.0.4",
42 | "gulp-jscad-files": "^3.0.1",
43 | "gulp-jsdoc-to-markdown": "^1.2.1",
44 | "gulp-merge": "^0.1.1",
45 | "gulp-plumber": "^1.2.1",
46 | "gulp-terser": "^1.2.0",
47 | "gulp-util": "^3.0.7",
48 | "gulp-watch": "^5.0.1",
49 | "rollup": "^1.19.4",
50 | "rollup-plugin-babel": "^4.3.3",
51 | "rollup-plugin-node-resolve": "^5.2.0",
52 | "vuepress-jsdoc": "^1.8.1"
53 | },
54 | "dependencies": {
55 | "@jscad/csg": "^0.7.0",
56 | "@jscad/scad-api": "^0.5.1",
57 | "@jwc/jscad-utils": "^4.2.1"
58 | },
59 | "ava": {
60 | "files": [
61 | "test/**/*.js",
62 | "!test/helpers/**/*.js"
63 | ],
64 | "sources": [
65 | "src/**/*.js"
66 | ],
67 | "require": [
68 | "esm",
69 | "@babel/register",
70 | "babel-polyfill",
71 | "./test/helpers/compat-env.js"
72 | ]
73 | },
74 | "babel": {
75 | "presets": [
76 | "@babel/preset-env"
77 | ]
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/githubdocs/index.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= title %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | <%= theme %>
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 | <%= readme %>
46 |
47 |
48 |
49 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/code/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Welcome to API
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/githubdocs/jscad-function.js:
--------------------------------------------------------------------------------
1 | // jscad-function.js
2 | //
3 | // == OpenJSCAD.org, Copyright (c) 2013-2016, Licensed under MIT License
4 | //
5 | // History:
6 | // 2016/02/02: 0.4.0: GUI refactored, functionality split up into more files, mostly done by Z3 Dev
7 |
8 | // Create an function for processing the JSCAD script into CSG/CAG objects
9 | //
10 | // fullurl - URL to original script
11 | // script - FULL script with all possible support routines, etc
12 | // callback - function to call, returning results or errors
13 | //
14 | // This function creates an anonymous Function, which is invoked to execute the thread.
15 | // The function executes in the GLOBAL context, so all necessary parameters are provided.
16 | //
17 | OpenJsCad.createJscadFunction = function(fullurl, script, callback) {
18 | //console.log("createJscadFunction()");
19 |
20 | // determine the relative base path for include()
21 | var relpath = fullurl;
22 | if (relpath.lastIndexOf('/') >= 0) {
23 | relpath = relpath.substring(0,relpath.lastIndexOf('/')+1);
24 | }
25 |
26 | var source = "// SYNC WORKER\n";
27 | source += ' var relpath = "'+relpath+'";\n'
28 | source += ' var include = includeJscadSync;\n';
29 | source += '\n';
30 | source += includeJscadSync.toString()+'\n';
31 | source += '\n';
32 | source += script+'\n';
33 | source += '\n';
34 | source += "return main(params);\n";
35 |
36 | //console.log("SOURCE: "+source);
37 |
38 | var f = new Function("params", source);
39 | return f;
40 | };
41 |
42 | //
43 | // THESE FUNCTIONS ARE SERIALIZED FOR INCLUSION IN THE FULL SCRIPT
44 | //
45 | // TODO It might be possible to cache the serialized versions
46 | //
47 |
48 | // Include the requested script via MemFs (if available) or HTTP Request
49 | //
50 | // (Note: This function is appended together with the JSCAD script)
51 | //
52 | function includeJscadSync(fn) {
53 | // include the requested script via MemFs if possible
54 | if (typeof(gMemFs) == 'object') {
55 | for(var fs in gMemFs) {
56 | if (gMemFs[fs].name == fn) {
57 | eval(gMemFs[fs].source);
58 | return;
59 | }
60 | }
61 | }
62 | // include the requested script via webserver access
63 | var xhr = new XMLHttpRequest();
64 | var url = relpath+fn;
65 | if (fn.match(/^(https:|http:)/i)) {
66 | url = fn;
67 | }
68 | xhr.open('GET',url,false);
69 | xhr.onload = function() {
70 | var src = this.responseText;
71 | eval(src);
72 | };
73 | xhr.onerror = function() {
74 | };
75 | xhr.send();
76 | };
77 |
78 |
--------------------------------------------------------------------------------
/v1/imperial.jscad:
--------------------------------------------------------------------------------
1 | /* exported ImperialBolts, ImperialWashers */
2 | /**
3 | * http://www.americanfastener.com/cap-screws/
4 | * E - Body Diameter
5 | * F - Width Across Flats
6 | * G - Width Across Corners
7 | * H - Head Height
8 | * D - Head Diameter
9 | *
10 | * tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
11 | * @type {Object}
12 | */
13 | ImperialBolts = {
14 | '1/4 hex': {
15 | name: '1/4 hex',
16 | E: util.inch(0.25),
17 | tap: util.inch(0.201),
18 | close: util.inch(0.257),
19 | loose: util.inch(0.266),
20 | H: util.inch(5 / 32),
21 | G: util.inch(0.505),
22 | F: util.inch(7 / 16),
23 | type: 'HexHeadScrew'
24 | },
25 | '1/4 socket': {
26 | name: '1/4 socket',
27 | E: util.inch(0.25),
28 | tap: util.inch(0.201),
29 | close: util.inch(0.257),
30 | loose: util.inch(0.266),
31 | H: util.inch(0.25),
32 | D: util.inch(0.375),
33 | type: 'PanHeadScrew'
34 | },
35 | '5/16 hex': {
36 | name: '5/16 hex',
37 | E: util.inch(0.3125),
38 | tap: util.inch(0.257),
39 | close: util.inch(0.323),
40 | loose: util.inch(0.332),
41 | H: util.inch(0.203125),
42 | G: util.inch(0.577), // 0.577-0.557
43 | F: util.inch(0.5),
44 | type: 'HexHeadScrew'
45 | }
46 | };
47 |
48 | /**
49 | * Imperial washer sizes
50 | *
51 | * @see http://almabolt.com/pages/catalog/washers/fender.htm
52 | * @type {Object}
53 | */
54 | var ImperialWashers = {
55 | '1/4': {
56 | od: util.inch(0.734),
57 | id: util.inch(0.312),
58 | thickness: util.inch(0.08) // .051/.080
59 | },
60 | '1/4 fender': {
61 | od: util.inch(1.25),
62 | id: util.inch(0.28125),
63 | thickness: util.inch(0.08) // .051/.080
64 | },
65 | '5/16': {
66 | od: util.inch(1.25),
67 | id: util.inch(0.34375),
68 | thickness: util.inch(0.08) // .051/.080
69 | }
70 | };
71 |
72 | // headDiameter, headLength, diameter, tap, countersink
73 | var ImperialWoodScrews = {
74 | '#4': [util.inch(0.225), util.inch(0.067), util.inch(0.112)],
75 | '#6': [util.inch(0.279), util.inch(0.083), util.inch(0.138)],
76 | '#8': [util.inch(0.332), util.inch(0.1), util.inch(0.164)],
77 | '#10': [util.inch(0.385), util.inch(0.116), util.inch(0.19)],
78 | '#12': [util.inch(0.438), util.inch(0.132), util.inch(0.216)]
79 | };
80 |
81 | /**
82 | * Dimensions of nuts for imperial bolts.
83 | * F is the width across teh faces, C is the width
84 | * across the points, and H is the height. D is the
85 | * basic diameter.
86 | *
87 | * [F, C, H, D]
88 | *
89 | * @see https://en.wikipedia.org/wiki/Nut_(hardware)
90 | * @type {Object}
91 | */
92 | var ImperialNuts = {
93 | '1/4 hex': [11.113, 12.8, 5.56, 6.35]
94 | };
95 |
--------------------------------------------------------------------------------
/docs/code/metric.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: metric
3 | ---
4 |
5 | # metric
6 |
7 | ## Constants
8 |
9 |
10 | MetricHexBoltDimensions
11 |
12 | SocketCapScrewDimensions
13 |
14 | MetricBolts : Object
15 | http://www.atlrod.com/metric-hex-bolt-dimensions/
16 | E - Body Diameter (D)
17 | F - Width Across Flats
18 | G - Width Across Corners (C)
19 | H - Head Height
20 | D - Head Diameter
21 | tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
22 |
23 | MetricNuts : Object
24 | Dimensions of nuts for imperial bolts.
25 | F is the width across the faces, C is the width
26 | across the points, and H is the height. D is the
27 | basic diameter.
28 | [F, C, H, D]
29 |
30 | MetricWashers : Object
31 | Metric washer sizes
32 | Size Inside Diameter Outside Diameter Thickness
33 |
34 |
35 |
36 |
37 |
38 | ## MetricHexBoltDimensions
39 | **Kind**: global constant
40 | **See**: http://www.atlrod.com/metric-hex-bolt-dimensions/
41 |
42 | E - Body Diameter
43 | F - Width Across Flats
44 | G - Width Across Corners
45 | H - Head Height
46 | D - Head Diameter
47 |
48 | NOMINAL SIZE (D) BODY DIAMETER HEAD THICKNESS ACROSS THE FLATS ACROSS CORNERS
49 |
50 |
51 | ## SocketCapScrewDimensions
52 | **Kind**: global constant
53 | **See**: https://www.fastenal.com/content/product_specifications/M.SHCS.4762.8.8.Z.pdf
54 |
55 | Nominal Size (d), Body Diameter Max, min, Head Diameter max, min, Head Height max, min, Socket Size max, min, Key Engagement min
56 |
57 | E - Body Diameter
58 | H - Head Height
59 | D - Head Diameter
60 |
61 |
62 | ## MetricBolts : Object
63 | http://www.atlrod.com/metric-hex-bolt-dimensions/
64 | E - Body Diameter (D)
65 | F - Width Across Flats
66 | G - Width Across Corners (C)
67 | H - Head Height
68 | D - Head Diameter
69 |
70 | tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
71 |
72 | **Kind**: global constant
73 |
74 |
75 | ## MetricNuts : Object
76 | Dimensions of nuts for imperial bolts.
77 | F is the width across the faces, C is the width
78 | across the points, and H is the height. D is the
79 | basic diameter.
80 |
81 | [F, C, H, D]
82 |
83 | **Kind**: global constant
84 | **See**: https://en.wikipedia.org/wiki/Nut_(hardware)
85 |
86 |
87 | ## MetricWashers : Object
88 | Metric washer sizes
89 | Size Inside Diameter Outside Diameter Thickness
90 |
91 | **Kind**: global constant
92 | **See**: https://armstrongmetalcrafts.com/Reference/WasherSizes.aspx
93 |
--------------------------------------------------------------------------------
/docs/code/hardware.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: hardware
3 | ---
4 |
5 | # hardware
6 |
7 |
8 |
9 | ## jscad-hardware : Object
10 | A gear moduel for openJSCAD.
11 | 
12 |
13 | **Example**
14 | ```js
15 | include('jscad-utils-color.jscad');
16 |
17 | function mainx(params) {
18 | util.init(CSG);
19 |
20 | // draws a blue hexagon
21 | return Parts.Hexagon(10, 5).color('blue');
22 | }
23 | ```
24 |
25 | * [jscad-hardware](#module_jscad-hardware) : Object
26 | * [.Washer(washer, fit)](#module_jscad-hardware.Washer)
27 | * [.PanHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)](#module_jscad-hardware.PanHeadScrew)
28 | * [.HexHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)](#module_jscad-hardware.HexHeadScrew)
29 | * [.FlatHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)](#module_jscad-hardware.FlatHeadScrew)
30 |
31 |
32 |
33 | ### jscad-hardware.Washer(washer, fit)
34 | Create a washer group from a washer type.
35 |
36 | **Kind**: static method of [jscad-hardware](#module_jscad-hardware)
37 |
38 | | Param | Type | Description |
39 | | --- | --- | --- |
40 | | washer | Object | Washer type object. |
41 | | fit | String | Clearance to add to group (tap|close|loose). |
42 |
43 |
44 |
45 | ### jscad-hardware.PanHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)
46 | Creates a `Group` object with a Pan Head Screw.
47 |
48 | **Kind**: static method of [jscad-hardware](#module_jscad-hardware)
49 |
50 | | Param | Type | Description |
51 | | --- | --- | --- |
52 | | headDiameter | number | Diameter of the head of the screw |
53 | | headLength | number | Length of the head |
54 | | diameter | number | Diameter of the threaded shaft |
55 | | length | number | Length of the threaded shaft |
56 | | clearLength | number | Length of the clearance section of the head. |
57 | | options | object | Screw options include orientation and clerance scale. |
58 |
59 |
60 |
61 | ### jscad-hardware.HexHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)
62 | Creates a `Group` object with a Hex Head Screw.
63 |
64 | **Kind**: static method of [jscad-hardware](#module_jscad-hardware)
65 |
66 | | Param | Type | Description |
67 | | --- | --- | --- |
68 | | headDiameter | number | Diameter of the head of the screw |
69 | | headLength | number | Length of the head |
70 | | diameter | number | Diameter of the threaded shaft |
71 | | length | number | Length of the threaded shaft |
72 | | clearLength | number | Length of the clearance section of the head. |
73 | | options | object | Screw options include orientation and clerance scale. |
74 |
75 |
76 |
77 | ### jscad-hardware.FlatHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)
78 | Create a Flat Head Screw
79 |
80 | **Kind**: static method of [jscad-hardware](#module_jscad-hardware)
81 |
82 | | Param | Type | Description |
83 | | --- | --- | --- |
84 | | headDiameter | number | head diameter |
85 | | headLength | number | head length |
86 | | diameter | number | thread diameter |
87 | | length | number | thread length |
88 | | clearLength | number | clearance length |
89 | | options | object | options |
90 |
91 |
--------------------------------------------------------------------------------
/docs/code/imperial.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: imperial
3 | ---
4 |
5 | # imperial
6 |
7 | ## Constants
8 |
9 |
10 | HexBoltDimensions : Object
11 | Screw Size, Major Diameter, Threads Per Inch, Minor Diameter, Tap Plastic Drill Size, Tap Plastic Decimal Equiv., Tap Steel Drill Size, Tap Steel Decimal Equiv., Close Fit Drill Size, Close Fit Decimal Equiv., Free Fit Drill Size, Free Fit Decimal Equiv.
12 |
13 | SocketCapScrewDimensions
14 | Socket cap screw dimensions.
15 | E - Body Diameter
16 | H - Head Height
17 | D - Head Diameter
18 |
19 | ImperialBolts : Object
20 | http://www.americanfastener.com/cap-screws/
21 | E - Body Diameter
22 | F - Width Across Flats
23 | G - Width Across Corners
24 | H - Head Height
25 | D - Head Diameter
26 | tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
27 |
28 | ImperialWashers : Object
29 | Imperial washer sizes
30 | Size Inside Diameter Outside Diameter Thickness
31 |
32 | ImperialWoodScrews
33 | Imperial wood screws.
34 |
35 | ImperialNuts : Object
36 | Dimensions of nuts for imperial bolts.
37 | F is the width across teh faces, C is the width
38 | across the points, and H is the height. D is the
39 | basic diameter.
40 | [F, C, H, D]
41 |
42 |
43 |
44 |
45 |
46 | ## HexBoltDimensions : Object
47 | Screw Size, Major Diameter, Threads Per Inch, Minor Diameter, Tap Plastic Drill Size, Tap Plastic Decimal Equiv., Tap Steel Drill Size, Tap Steel Decimal Equiv., Close Fit Drill Size, Close Fit Decimal Equiv., Free Fit Drill Size, Free Fit Decimal Equiv.
48 |
49 | **Kind**: global constant
50 | **See**
51 |
52 | - http://www.americanfastener.com/cap-screws/
53 | - https://www.aftfasteners.com/fully-threaded-hex-tap-bolts-dimensions-mechanical-properties/
54 | E - Body Diameter
55 | F - Width Across Flats
56 | G - Width Across Corners
57 | H - Head Height
58 | D - Head Diameter
59 |
60 | tap sizes: @see https://littlemachineshop.com/reference/tapdrill.php
61 |
62 |
63 |
64 | ## SocketCapScrewDimensions
65 | Socket cap screw dimensions.
66 |
67 | E - Body Diameter
68 | H - Head Height
69 | D - Head Diameter
70 |
71 | **Kind**: global constant
72 | **See**: https://www.aftfasteners.com/socket-cap-screws-dimensions-and-mechanical-properties/
73 |
74 |
75 | ## ImperialBolts : Object
76 | http://www.americanfastener.com/cap-screws/
77 | E - Body Diameter
78 | F - Width Across Flats
79 | G - Width Across Corners
80 | H - Head Height
81 | D - Head Diameter
82 |
83 | tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
84 |
85 | **Kind**: global constant
86 |
87 |
88 | ## ImperialWashers : Object
89 | Imperial washer sizes
90 | Size Inside Diameter Outside Diameter Thickness
91 |
92 | **Kind**: global constant
93 | **See**
94 |
95 | - https://armstrongmetalcrafts.com/Reference/WasherSizes.aspx
96 | - http://almabolt.com/pages/catalog/washers/fender.htm
97 |
98 |
99 |
100 | ## ImperialWoodScrews
101 | Imperial wood screws.
102 |
103 | **Kind**: global constant
104 | **See**: https://www.aftfasteners.com/wood-screws-dimensions-mechanical-specs/
105 | headDiameter, headLength, diameter, tap, countersink
106 |
107 |
108 | ## ImperialNuts : Object
109 | Dimensions of nuts for imperial bolts.
110 | F is the width across teh faces, C is the width
111 | across the points, and H is the height. D is the
112 | basic diameter.
113 |
114 | [F, C, H, D]
115 |
116 | **Kind**: global constant
117 | **See**
118 |
119 | - https://en.wikipedia.org/wiki/Nut_(hardware)
120 | - https://www.boltdepot.com/fastener-information/nuts-washers/us-nut-dimensions.aspx
121 |
122 |
--------------------------------------------------------------------------------
/githubdocs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | jscad parts library for screws, washers and nuts
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
46 |
jscad-hardware
47 |
48 | https://johnwebbcole.github.io/jscad-hardware/
49 |
50 |
51 |
This is a collection of jscad parts that model a common Imperial and Metric bolts and washers. These models use the jscad-utils library and return jscad-utils group objects .
52 |
Installation
53 |
Install jscad-hardware using NPM:
54 |
npm install --save jscad-hardware
55 |
56 |
Basic usage
57 |
To use the utilities, you need to include the jscad-hardware.jscad.
58 |
include('node_modules/jscad-utils/jscad-utils.jscad');
59 | include('node_modules/jscad-hardware/jscad-hardware.jscad');
60 |
61 | main() {
62 | util.init(CSG);
63 |
64 | var BPlus = RaspberryPi.BPlus();
65 |
66 | return BPlus.combine();
67 | }
68 |
69 |
Yeoman Generator
70 |
You can use the yeoman jscad generator which will create a project that uses this library.
71 |
Once you create your project, install jscad-hardware, and run gulp. Dragging the dist directory into http://openjscad.org/ will include this library.
72 |
Modify your main.jscad file to return a RaspberryPi object.
73 |
function main() {
74 | util.init(CSG);
75 |
76 | var bolt = Hardware.Bolt(
77 | util.inch(1),
78 | ImperialBolts['5/16 hex'],
79 | 'close'
80 | )
81 |
82 | return bolt.combine('head,thread');
83 | }
84 |
85 | // include:js
86 | // endinject
87 |
88 |
89 |
90 |
91 |
92 |
93 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/js/8.362e9d24.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[8],{269:function(t,e,s){"use strict";s.r(e);var r=s(38),i=Object(r.a)({},function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"metric"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#metric","aria-hidden":"true"}},[t._v("#")]),t._v(" metric")]),t._v(" "),s("h2",{attrs:{id:"constants"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#constants","aria-hidden":"true"}},[t._v("#")]),t._v(" Constants")]),t._v(" "),s("dl",[s("dt",[s("a",{attrs:{href:"#MetricHexBoltDimensions"}},[t._v("MetricHexBoltDimensions")])]),t._v(" "),s("dd"),t._v(" "),s("dt",[s("a",{attrs:{href:"#SocketCapScrewDimensions"}},[t._v("SocketCapScrewDimensions")])]),t._v(" "),s("dd"),t._v(" "),s("dt",[s("a",{attrs:{href:"#MetricBolts"}},[t._v("MetricBolts")]),t._v(" : "),s("code",[t._v("Object")])]),t._v(" "),s("dd",[s("p",[s("a",{attrs:{href:"http://www.atlrod.com/metric-hex-bolt-dimensions/"}},[t._v("http://www.atlrod.com/metric-hex-bolt-dimensions/")]),t._v("\nE - Body Diameter (D)\nF - Width Across Flats\nG - Width Across Corners (C)\nH - Head Height\nD - Head Diameter")]),t._v(" "),s("p",[t._v("tap sizes: "),s("a",{attrs:{href:"https://littlemachineshop.com/reference/TapDrillSizes.pdf"}},[t._v("https://littlemachineshop.com/reference/TapDrillSizes.pdf")])])]),t._v(" "),s("dt",[s("a",{attrs:{href:"#MetricNuts"}},[t._v("MetricNuts")]),t._v(" : "),s("code",[t._v("Object")])]),t._v(" "),s("dd",[s("p",[t._v("Dimensions of nuts for imperial bolts.\nF is the width across the faces, C is the width\nacross the points, and H is the height. D is the\nbasic diameter.")]),t._v(" "),s("p",[t._v("[F, C, H, D]")])]),t._v(" "),s("dt",[s("a",{attrs:{href:"#MetricWashers"}},[t._v("MetricWashers")]),t._v(" : "),s("code",[t._v("Object")])]),t._v(" "),s("dd",[s("p",[t._v("Metric washer sizes\nSize Inside Diameter Outside Diameter Thickness")])])]),t._v(" "),s("p",[s("a",{attrs:{name:"MetricHexBoltDimensions"}})]),t._v(" "),s("h2",{attrs:{id:"metrichexboltdimensions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#metrichexboltdimensions","aria-hidden":"true"}},[t._v("#")]),t._v(" MetricHexBoltDimensions")]),t._v(" "),s("p",[s("strong",[t._v("Kind")]),t._v(": global constant"),s("br"),t._v(" "),s("strong",[t._v("See")]),t._v(": http://www.atlrod.com/metric-hex-bolt-dimensions/")]),t._v(" "),s("p",[t._v("E - Body Diameter\nF - Width Across Flats\nG - Width Across Corners\nH - Head Height\nD - Head Diameter")]),t._v(" "),s("p",[t._v("NOMINAL SIZE (D)\tBODY DIAMETER\t\tHEAD THICKNESS\t\tACROSS THE FLATS\t\tACROSS CORNERS"),s("br"),t._v(" "),s("a",{attrs:{name:"SocketCapScrewDimensions"}})]),t._v(" "),s("h2",{attrs:{id:"socketcapscrewdimensions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#socketcapscrewdimensions","aria-hidden":"true"}},[t._v("#")]),t._v(" SocketCapScrewDimensions")]),t._v(" "),s("p",[s("strong",[t._v("Kind")]),t._v(": global constant"),s("br"),t._v(" "),s("strong",[t._v("See")]),t._v(": https://www.fastenal.com/content/product_specifications/M.SHCS.4762.8.8.Z.pdf")]),t._v(" "),s("p",[t._v("Nominal Size (d), Body Diameter Max, min, Head Diameter max, min, Head Height max, min, Socket Size max, min, Key Engagement min")]),t._v(" "),s("p",[t._v("E - Body Diameter\nH - Head Height\nD - Head Diameter"),s("br"),t._v(" "),s("a",{attrs:{name:"MetricBolts"}})]),t._v(" "),s("h2",{attrs:{id:"metricbolts-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#metricbolts-object","aria-hidden":"true"}},[t._v("#")]),t._v(" MetricBolts : "),s("code",[t._v("Object")])]),t._v(" "),s("p",[t._v("http://www.atlrod.com/metric-hex-bolt-dimensions/\nE - Body Diameter (D)\nF - Width Across Flats\nG - Width Across Corners (C)\nH - Head Height\nD - Head Diameter")]),t._v(" "),s("p",[t._v("tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf")]),t._v(" "),s("p",[s("strong",[t._v("Kind")]),t._v(": global constant"),s("br"),t._v(" "),s("a",{attrs:{name:"MetricNuts"}})]),t._v(" "),s("h2",{attrs:{id:"metricnuts-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#metricnuts-object","aria-hidden":"true"}},[t._v("#")]),t._v(" MetricNuts : "),s("code",[t._v("Object")])]),t._v(" "),s("p",[t._v("Dimensions of nuts for imperial bolts.\nF is the width across the faces, C is the width\nacross the points, and H is the height. D is the\nbasic diameter.")]),t._v(" "),s("p",[t._v("[F, C, H, D]")]),t._v(" "),s("p",[s("strong",[t._v("Kind")]),t._v(": global constant"),s("br"),t._v(" "),s("strong",[t._v("See")]),t._v(": https://en.wikipedia.org/wiki/Nut_(hardware)"),s("br"),t._v(" "),s("a",{attrs:{name:"MetricWashers"}})]),t._v(" "),s("h2",{attrs:{id:"metricwashers-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#metricwashers-object","aria-hidden":"true"}},[t._v("#")]),t._v(" MetricWashers : "),s("code",[t._v("Object")])]),t._v(" "),s("p",[t._v("Metric washer sizes\nSize\tInside Diameter\tOutside Diameter\tThickness")]),t._v(" "),s("p",[s("strong",[t._v("Kind")]),t._v(": global constant"),s("br"),t._v(" "),s("strong",[t._v("See")]),t._v(": https://armstrongmetalcrafts.com/Reference/WasherSizes.aspx")])])},[],!1,null,null,null);e.default=i.exports}}]);
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /* eslint-env node */
3 | var fs = require('fs');
4 | var gulp = require('gulp');
5 | // var concat = require('gulp-concat');
6 | var del = require('del');
7 | // var gulpLoadPlugins = require('gulp-load-plugins');
8 | // var plugins = gulpLoadPlugins();
9 | // var runSequence = require('run-sequence');
10 | var rollup = require('rollup');
11 | var merge2 = require('merge2');
12 | var debug = require('gulp-debug');
13 | var inject = require('gulp-inject');
14 | var plumber = require('gulp-plumber');
15 | var terser = require('gulp-terser');
16 | var rollupResolve = require('rollup-plugin-node-resolve');
17 | var rollupBabel = require('rollup-plugin-babel');
18 | var jscadFiles = require('gulp-jscad-files');
19 | var pkg = require('./package.json');
20 |
21 | gulp.task('build', async function() {
22 | const bundle = await rollup.rollup({
23 | input: './src/index.js',
24 | external: ['@jscad/scad-api', '@jscad/csg', '@jwc/jscad-utils'],
25 | plugins: [
26 | rollupResolve({
27 | customResolveOptions: {
28 | moduleDirectory: 'node_modules'
29 | },
30 | browser: true
31 | }),
32 | rollupBabel({
33 | exclude: 'node_modules/**' // only transpile our source code
34 | })
35 | ]
36 | });
37 |
38 | await bundle.write({
39 | name: 'jscadHardware',
40 | file: 'dist/index.js',
41 | format: 'iife',
42 | exports: 'named',
43 | globals: {
44 | '@jscad/csg': 'jsCadCSG',
45 | '@jscad/scad-api': 'scadApi',
46 | '@jwc/jscad-utils': 'jscadUtils'
47 | },
48 | banner: `/*
49 | * ${pkg.name} version ${pkg.version}
50 | * ${pkg.homepage}
51 | */`,
52 | footer: `/* ${pkg.name} follow me on Twitter! @johnwebbcole */`
53 | });
54 | });
55 |
56 | gulp.task('v1compat', function() {
57 | return gulp
58 | .src('src/v1compat.js')
59 | .pipe(plumber())
60 | .pipe(
61 | inject(gulp.src('dist/index.js').pipe(debug({ title: 'injecting:' })), {
62 | relative: true,
63 | starttag: '// include:compat',
64 | endtag: '// end:compat',
65 | transform: function(filepath, file) {
66 | return '// ' + filepath + '\n' + file.contents.toString('utf8');
67 | }
68 | })
69 | )
70 | .pipe(gulp.dest('dist'));
71 | });
72 |
73 | // gulp.task('clean', function(done) {
74 | // del(['README.md', 'dist/*.jscad']).then(paths => {
75 | // console.log('Deleted files and folders:\n', paths.join('\n')); // eslint-disable-line no-console, no-undef
76 | // done();
77 | // });
78 | // });
79 |
80 | // gulp.task('lint', function() {
81 | // return gulp
82 | // .src(['*.jscad', 'gulpfile.js'])
83 | // .pipe(plugins.plumber())
84 | // .pipe(plugins.eslint())
85 | // .pipe(plugins.eslint.format());
86 | // // .pipe(plugins.eslint.failAfterError());
87 | // });
88 |
89 | // gulp.task('docs', function() {
90 | // return gulp
91 | // .src('*.jscad')
92 | // .pipe(plugins.plumber())
93 | // .pipe(plugins.concat('README.md'))
94 | // .pipe(
95 | // plugins.jsdocToMarkdown({
96 | // template: fs.readFileSync('./jsdoc2md/README.hbs', 'utf8')
97 | // })
98 | // )
99 | // .on('error', function(err) {
100 | // plugins.util.log('jsdoc2md failed:', err.message);
101 | // })
102 | // .pipe(gulp.dest('.'));
103 | // });
104 |
105 | gulp.task('examples', function() {
106 | return gulp
107 | .src('examples/*.jscad')
108 | .pipe(plumber())
109 | .pipe(
110 | inject(
111 | merge2(
112 | gulp
113 | .src('package.json')
114 | .pipe(jscadFiles())
115 | .pipe(
116 | terser({
117 | ecma: 6,
118 | keep_fnames: true,
119 | mangle: false,
120 | compress: false,
121 | output: {
122 | beautify: true,
123 | max_line_len: 80
124 | }
125 | })
126 | ),
127 | gulp.src(['dist/v1compat.js'])
128 | ).pipe(debug({ title: 'injecting:' })),
129 | {
130 | relative: true,
131 | starttag: '// include:js',
132 | endtag: '// endinject',
133 | transform: function(filepath, file) {
134 | return '// ' + filepath + '\n' + file.contents.toString('utf8');
135 | }
136 | }
137 | )
138 | )
139 | .pipe(gulp.dest('dist/examples'));
140 | });
141 |
142 | // gulp.task('github-page', ['docs', 'examples'], function() {
143 | // return gulp
144 | // .src('package.json')
145 | // .pipe(plugins.plumber())
146 | // .pipe(
147 | // plugins.openjscadStandalone({
148 | // filename: 'bolt.jscad',
149 | // filepath: __dirname + '/dist/bolt.jscad'
150 | // })
151 | // )
152 | // .pipe(gulp.dest('docs'));
153 | // });
154 |
155 | gulp.task('all', gulp.series(['build', 'v1compat', 'examples']));
156 |
157 | gulp.task(
158 | 'default',
159 | gulp.series(['build', 'v1compat', 'examples'], function() {
160 | gulp.watch(
161 | ['src/**/*.js', 'examples/*.jscad'],
162 | {
163 | verbose: true,
164 | followSymlinks: true,
165 | delay: 500,
166 | queue: false,
167 | ignoreInitial: false,
168 | ignored: ['**/*.*~', 'dist/*', '.vuepress/*']
169 | },
170 | gulp.series(['build', 'v1compat', 'examples'])
171 | );
172 | })
173 | );
174 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/code/metric.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | metric
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/githubdocs/jscad-worker.js:
--------------------------------------------------------------------------------
1 | // jscad-worker.js
2 | //
3 | // == OpenJSCAD.org, Copyright (c) 2013-2016, Licensed under MIT License
4 | //
5 | // History:
6 | // 2016/02/02: 0.4.0: GUI refactored, functionality split up into more files, mostly done by Z3 Dev
7 |
8 | // Create an worker (thread) for processing the JSCAD script into CSG/CAG objects
9 | //
10 | // fullurl - URL to original script
11 | // script - FULL script with all possible support routines, etc
12 | // callback - function to call, returning results or errors
13 | //
14 | // This function builds the Worker thread, which is started by a message
15 | // The Worker thread (below) executes, and returns the results via another message.
16 | // (KIND OF LAME but that keeps the scope of variables and functions clean)
17 | // Upon receiving the message, the callback routine is called with the results
18 | //
19 | OpenJsCad.createJscadWorker = function(fullurl, script, callback) {
20 | var source = buildJscadWorkerScript(fullurl, script);
21 | var blobURL = OpenJsCad.textToBlobUrl(source);
22 | var w = new Worker(blobURL);
23 |
24 | //console.log("createJscadWorker: "+source);
25 |
26 | // when the worker finishes
27 | // - call back the provided function with the results
28 | w.onmessage = function(e) {
29 | if (e.data instanceof Object) {
30 | var data = e.data;
31 | if(data.cmd == 'rendered') {
32 | if (data.objects && data.objects.length) {
33 | // convert the compact formats back to CSG/CAG form
34 | var objects = [];
35 | for(var i=0; i)
67 | var relpath = fullpath;
68 | if (relpath.lastIndexOf('/') >= 0) {
69 | relpath = relpath.substring(0,relpath.lastIndexOf('/')+1);
70 | }
71 | var source = "";
72 | source += 'onmessage = function(e) {\n';
73 | source += ' include = includeJscad;\n';
74 | source += ' self.relpath = "'+relpath+'";\n';
75 | source += '\n';
76 | source += fullscript+'\n';
77 | source += includeJscad.toString()+'\n';
78 | source += runJscadWorker.toString()+'\n';
79 | source += ' runJscadWorker(e);\n';
80 | source += '};';
81 | return source;
82 | }
83 |
84 | //
85 | // THESE FUNCTIONS ARE SERIALIZED FOR INCLUSION IN THE FULL SCRIPT
86 | //
87 | // TODO It might be possible to cache the serialized versions
88 | //
89 |
90 | // Implement include() generally for all scripts
91 | //
92 | // (Note: This function is appended together with the JSCAD script)
93 | //
94 | function includeJscad(fn) {
95 | // include the requested script via MemFs if possible
96 | if (typeof(gMemFs) == 'object') {
97 | for (var i = 0; i < gMemFs.length; i++) {
98 | if (gMemFs[i].name == fn) {
99 | eval(gMemFs[i].source);
100 | return;
101 | }
102 | }
103 | }
104 | // include the requested script via importScripts
105 | var url = self.relpath+fn;
106 | if (fn.match(/^(https:|http:)/i)) {
107 | url = fn;
108 | }
109 | importScripts(url);
110 | return true;
111 | };
112 |
113 | // Run the JSCAD script via main()
114 | //
115 | // The message (event) must contain:
116 | // data.cmd - 'render'
117 | // data.parameters - the parameter values to pass to main()
118 | // The message (event) can also supply:
119 | // data.libraries - the libraries (full URLs) to import
120 | //
121 | // (Note: This function is appended together with the JSCAD script)
122 | //
123 | function runJscadWorker(e) {
124 | var r = {cmd: "error", txt: "try again"};
125 | if (e.data instanceof Object) {
126 | var data = e.data;
127 | if(data.cmd == 'render') {
128 | // verify the command contents
129 | if(!data.parameters) { throw new Error("JSCAD Processor: missing 'parameters'"); }
130 | // setup the environment
131 | if(data.libraries && data.libraries.length) {
132 | data.libraries.map( function(l) { importScripts(l); } );
133 | }
134 | // setup the script
135 | if (typeof(main) == 'function') {
136 | var results = main( data.parameters );
137 | if (!results.length) { results = [results]; }
138 | // convert the results to a compact format for transfer back
139 | var objects = [];
140 | for(var i=0; i 0) {
148 | r.cmd = "rendered";
149 | r.objects = objects;
150 | } else {
151 | r.err = 'The JSCAD script must return one or more CSG or CAG solids.';
152 | }
153 | } else {
154 | r.err = 'The JSCAD script must contain a function main() which returns one or more CSG or CAG solids.';
155 | }
156 | } else {
157 | throw new Error('JSCAD Processor: invalid worker command: '+data.cmd);
158 | }
159 | }
160 | postMessage(r);
161 | };
162 |
163 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/js/7.02f8640a.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[7],{268:function(e,t,a){"use strict";a.r(t);var s=a(38),i=Object(s.a)({},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"imperial"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#imperial","aria-hidden":"true"}},[e._v("#")]),e._v(" imperial")]),e._v(" "),a("h2",{attrs:{id:"constants"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#constants","aria-hidden":"true"}},[e._v("#")]),e._v(" Constants")]),e._v(" "),a("dl",[a("dt",[a("a",{attrs:{href:"#HexBoltDimensions"}},[e._v("HexBoltDimensions")]),e._v(" : "),a("code",[e._v("Object")])]),e._v(" "),a("dd",[a("p",[e._v("Screw Size, Major Diameter, Threads Per Inch, Minor Diameter, Tap Plastic Drill Size, Tap Plastic Decimal Equiv., Tap Steel Drill Size, Tap Steel Decimal Equiv., Close Fit Drill Size, Close Fit Decimal Equiv., Free Fit Drill Size, Free Fit Decimal Equiv.")])]),e._v(" "),a("dt",[a("a",{attrs:{href:"#SocketCapScrewDimensions"}},[e._v("SocketCapScrewDimensions")])]),e._v(" "),a("dd",[a("p",[e._v("Socket cap screw dimensions.")]),e._v(" "),a("p",[e._v("E - Body Diameter\nH - Head Height\nD - Head Diameter")])]),e._v(" "),a("dt",[a("a",{attrs:{href:"#ImperialBolts"}},[e._v("ImperialBolts")]),e._v(" : "),a("code",[e._v("Object")])]),e._v(" "),a("dd",[a("p",[a("a",{attrs:{href:"http://www.americanfastener.com/cap-screws/"}},[e._v("http://www.americanfastener.com/cap-screws/")]),e._v("\nE - Body Diameter\nF - Width Across Flats\nG - Width Across Corners\nH - Head Height\nD - Head Diameter")]),e._v(" "),a("p",[e._v("tap sizes: "),a("a",{attrs:{href:"https://littlemachineshop.com/reference/TapDrillSizes.pdf"}},[e._v("https://littlemachineshop.com/reference/TapDrillSizes.pdf")])])]),e._v(" "),a("dt",[a("a",{attrs:{href:"#ImperialWashers"}},[e._v("ImperialWashers")]),e._v(" : "),a("code",[e._v("Object")])]),e._v(" "),a("dd",[a("p",[e._v("Imperial washer sizes\nSize Inside Diameter Outside Diameter Thickness")])]),e._v(" "),a("dt",[a("a",{attrs:{href:"#ImperialWoodScrews"}},[e._v("ImperialWoodScrews")])]),e._v(" "),a("dd",[a("p",[e._v("Imperial wood screws.")])]),e._v(" "),a("dt",[a("a",{attrs:{href:"#ImperialNuts"}},[e._v("ImperialNuts")]),e._v(" : "),a("code",[e._v("Object")])]),e._v(" "),a("dd",[a("p",[e._v("Dimensions of nuts for imperial bolts.\nF is the width across teh faces, C is the width\nacross the points, and H is the height. D is the\nbasic diameter.")]),e._v(" "),a("p",[e._v("[F, C, H, D]")])])]),e._v(" "),a("p",[a("a",{attrs:{name:"HexBoltDimensions"}})]),e._v(" "),a("h2",{attrs:{id:"hexboltdimensions-object"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#hexboltdimensions-object","aria-hidden":"true"}},[e._v("#")]),e._v(" HexBoltDimensions : "),a("code",[e._v("Object")])]),e._v(" "),a("p",[e._v("Screw Size, Major Diameter, Threads Per Inch, Minor Diameter, Tap Plastic Drill Size, Tap Plastic Decimal Equiv., Tap Steel Drill Size, Tap Steel Decimal Equiv., Close Fit Drill Size, Close Fit Decimal Equiv., Free Fit Drill Size, Free Fit Decimal Equiv.")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": global constant"),a("br"),e._v(" "),a("strong",[e._v("See")])]),e._v(" "),a("ul",[a("li",[e._v("http://www.americanfastener.com/cap-screws/")]),e._v(" "),a("li",[e._v("https://www.aftfasteners.com/fully-threaded-hex-tap-bolts-dimensions-mechanical-properties/\nE - Body Diameter\nF - Width Across Flats\nG - Width Across Corners\nH - Head Height\nD - Head Diameter")])]),e._v(" "),a("p",[e._v("tap sizes: @see https://littlemachineshop.com/reference/tapdrill.php")]),e._v(" "),a("p",[a("a",{attrs:{name:"SocketCapScrewDimensions"}})]),e._v(" "),a("h2",{attrs:{id:"socketcapscrewdimensions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#socketcapscrewdimensions","aria-hidden":"true"}},[e._v("#")]),e._v(" SocketCapScrewDimensions")]),e._v(" "),a("p",[e._v("Socket cap screw dimensions.")]),e._v(" "),a("p",[e._v("E - Body Diameter\nH - Head Height\nD - Head Diameter")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": global constant"),a("br"),e._v(" "),a("strong",[e._v("See")]),e._v(": https://www.aftfasteners.com/socket-cap-screws-dimensions-and-mechanical-properties/"),a("br"),e._v(" "),a("a",{attrs:{name:"ImperialBolts"}})]),e._v(" "),a("h2",{attrs:{id:"imperialbolts-object"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#imperialbolts-object","aria-hidden":"true"}},[e._v("#")]),e._v(" ImperialBolts : "),a("code",[e._v("Object")])]),e._v(" "),a("p",[e._v("http://www.americanfastener.com/cap-screws/\nE - Body Diameter\nF - Width Across Flats\nG - Width Across Corners\nH - Head Height\nD - Head Diameter")]),e._v(" "),a("p",[e._v("tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": global constant"),a("br"),e._v(" "),a("a",{attrs:{name:"ImperialWashers"}})]),e._v(" "),a("h2",{attrs:{id:"imperialwashers-object"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#imperialwashers-object","aria-hidden":"true"}},[e._v("#")]),e._v(" ImperialWashers : "),a("code",[e._v("Object")])]),e._v(" "),a("p",[e._v("Imperial washer sizes\nSize\tInside Diameter\tOutside Diameter\tThickness")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": global constant"),a("br"),e._v(" "),a("strong",[e._v("See")])]),e._v(" "),a("ul",[a("li",[e._v("https://armstrongmetalcrafts.com/Reference/WasherSizes.aspx")]),e._v(" "),a("li",[e._v("http://almabolt.com/pages/catalog/washers/fender.htm")])]),e._v(" "),a("p",[a("a",{attrs:{name:"ImperialWoodScrews"}})]),e._v(" "),a("h2",{attrs:{id:"imperialwoodscrews"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#imperialwoodscrews","aria-hidden":"true"}},[e._v("#")]),e._v(" ImperialWoodScrews")]),e._v(" "),a("p",[e._v("Imperial wood screws.")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": global constant"),a("br"),e._v(" "),a("strong",[e._v("See")]),e._v(": https://www.aftfasteners.com/wood-screws-dimensions-mechanical-specs/\nheadDiameter, headLength, diameter, tap, countersink"),a("br"),e._v(" "),a("a",{attrs:{name:"ImperialNuts"}})]),e._v(" "),a("h2",{attrs:{id:"imperialnuts-object"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#imperialnuts-object","aria-hidden":"true"}},[e._v("#")]),e._v(" ImperialNuts : "),a("code",[e._v("Object")])]),e._v(" "),a("p",[e._v("Dimensions of nuts for imperial bolts.\nF is the width across teh faces, C is the width\nacross the points, and H is the height. D is the\nbasic diameter.")]),e._v(" "),a("p",[e._v("[F, C, H, D]")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": global constant"),a("br"),e._v(" "),a("strong",[e._v("See")])]),e._v(" "),a("ul",[a("li",[e._v("https://en.wikipedia.org/wiki/Nut_(hardware)")]),e._v(" "),a("li",[e._v("https://www.boltdepot.com/fastener-information/nuts-washers/us-nut-dimensions.aspx")])])])},[],!1,null,null,null);t.default=i.exports}}]);
--------------------------------------------------------------------------------
/docs/.vuepress/dist/code/imperial.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | imperial
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/hardware.js:
--------------------------------------------------------------------------------
1 | import { util, Group, parts as Parts, Debug } from '@jwc/jscad-utils';
2 | const debug = Debug('jscadHardware:hardware');
3 | /* exported Hardware */
4 |
5 | /**
6 | * A gear moduel for openJSCAD.
7 | * 
8 | * @example
9 | *include('jscad-utils-color.jscad');
10 | *
11 | *function mainx(params) {
12 | * util.init(CSG);
13 | *
14 | * // draws a blue hexagon
15 | * return Parts.Hexagon(10, 5).color('blue');
16 | *}
17 | * @type {Object}
18 | * @module jscad-hardware
19 | * @exports Hardware
20 | */
21 | export function Bolt(length, bolt, fit, BOM) {
22 | fit = fit || 'loose';
23 |
24 | if (BOM) {
25 | // Keep track of bolts for bill-of-materials
26 | var bomkey = `${bolt.name} - ${util.cm(length).toFixed(2)}`;
27 | if (!BOM[bomkey]) BOM[bomkey] = 0;
28 | BOM[bomkey]++;
29 | }
30 |
31 | var b = this[bolt.type](bolt.G || bolt.D, bolt.H, bolt.E, length);
32 |
33 | var clearance = bolt[fit] - bolt.E;
34 |
35 | b.add(
36 | this[bolt.type](
37 | (bolt.G || bolt.D) + clearance,
38 | bolt.H + clearance,
39 | bolt[fit],
40 | length,
41 | length
42 | ).map(part => part.color('red')),
43 | 'tap',
44 | false,
45 | 'tap-'
46 | );
47 |
48 | return b;
49 | }
50 |
51 | /**
52 | * Create a washer group from a washer type.
53 | * @param {Object} washer Washer type object.
54 | * @param {String} fit Clearance to add to group (tap|close|loose).
55 | */
56 | export function Washer(washer, fit) {
57 | debug('Washer', washer, fit);
58 | var w = Group();
59 | w.add(
60 | Parts.Tube(washer.od, washer.id, washer.thickness).color('gray'),
61 | 'washer'
62 | );
63 |
64 | if (fit) {
65 | var tap = Clearances[fit];
66 | if (!tap)
67 | console.error(
68 | `Washer unknown fit clearance ${fit}, should be ${Object.keys(
69 | Clearances
70 | ).join('|')}`
71 | );
72 | w.add(
73 | Parts.Cylinder(washer.od + Clearances[fit], washer.thickness).color(
74 | 'red'
75 | ),
76 | 'clearance'
77 | );
78 | }
79 | return w;
80 | }
81 |
82 | export function Nut(nut, fit) {
83 | debug('Nut', nut, fit);
84 | return Parts.Hexagon(nut[1] + Clearances[fit], nut[2]);
85 | }
86 |
87 | export const Screw = {
88 | PanHead: function(type, length, fit, options = {}) {
89 | debug('PanHead', type, length, fit, options);
90 | var [headDiameter, headLength, diameter, tap, countersink] = type;
91 | return PanHeadScrew(
92 | headDiameter,
93 | headLength,
94 | diameter,
95 | length,
96 | options.clearLength,
97 | options
98 | );
99 | },
100 |
101 | FlatHead: function(type, length, fit, options = {}) {
102 | debug('FlatHead', type, length, fit, options);
103 | var [headDiameter, headLength, diameter, tap, countersink] = type;
104 | return FlatHeadScrew(
105 | headDiameter,
106 | headLength,
107 | diameter,
108 | length,
109 | options.clearLength,
110 | options
111 | );
112 | }
113 | // HexHead: ScrewType(PanHeadScrew, ...args)
114 | };
115 |
116 | export const Clearances = {
117 | tap: util.inch(-0.049),
118 | close: util.inch(0.007),
119 | loose: util.inch(0.016)
120 | };
121 |
122 | export const Orientation = {
123 | up: {
124 | head: 'outside-',
125 | clear: 'inside+'
126 | },
127 | down: {
128 | head: 'outside+',
129 | clear: 'inside-'
130 | }
131 | };
132 |
133 | export function CreateScrew(head, thread, headClearSpace, options = {}) {
134 | console.warn('head', head);
135 | options = Object.assign(options, {
136 | orientation: 'up',
137 | clearance: [0, 0, 0]
138 | });
139 | var orientation = Orientation[options.orientation];
140 | var group = Group('head,thread', {
141 | head: head.color('gray'),
142 | thread: thread.snap(head, 'z', orientation.head).color('silver')
143 | });
144 |
145 | if (headClearSpace) {
146 | group.add(
147 | headClearSpace
148 | .enlarge(options.clearance)
149 | .snap(head, 'z', orientation.clear)
150 | .color('red'),
151 | 'headClearSpace',
152 | true
153 | );
154 | }
155 |
156 | return group;
157 | }
158 |
159 | /**
160 | * Creates a `Group` object with a Pan Head Screw.
161 | * @param {number} headDiameter Diameter of the head of the screw
162 | * @param {number} headLength Length of the head
163 | * @param {number} diameter Diameter of the threaded shaft
164 | * @param {number} length Length of the threaded shaft
165 | * @param {number} clearLength Length of the clearance section of the head.
166 | * @param {object} options Screw options include orientation and clerance scale.
167 | */
168 | export function PanHeadScrew(
169 | headDiameter,
170 | headLength,
171 | diameter,
172 | length,
173 | clearLength,
174 | options
175 | ) {
176 | var head = Parts.Cylinder(headDiameter, headLength);
177 | var thread = Parts.Cylinder(diameter, length);
178 |
179 | if (clearLength) {
180 | var headClearSpace = Parts.Cylinder(headDiameter, clearLength);
181 | }
182 |
183 | return CreateScrew(head, thread, headClearSpace, options);
184 | }
185 |
186 | /**
187 | * Creates a `Group` object with a Hex Head Screw.
188 | * @param {number} headDiameter Diameter of the head of the screw
189 | * @param {number} headLength Length of the head
190 | * @param {number} diameter Diameter of the threaded shaft
191 | * @param {number} length Length of the threaded shaft
192 | * @param {number} clearLength Length of the clearance section of the head.
193 | * @param {object} options Screw options include orientation and clerance scale.
194 | */
195 | export function HexHeadScrew(
196 | headDiameter,
197 | headLength,
198 | diameter,
199 | length,
200 | clearLength,
201 | options
202 | ) {
203 | debug(
204 | 'HexHeadScrew',
205 | headDiameter,
206 | headLength,
207 | diameter,
208 | length,
209 | clearLength,
210 | options
211 | );
212 | var head = Parts.Hexagon(headDiameter, headLength);
213 | var thread = Parts.Cylinder(diameter, length);
214 |
215 | if (clearLength) {
216 | var headClearSpace = Parts.Hexagon(headDiameter, clearLength);
217 | }
218 |
219 | return CreateScrew(head, thread, headClearSpace, options);
220 | }
221 |
222 | /**
223 | * Create a Flat Head Screw
224 | * @param {number} headDiameter head diameter
225 | * @param {number} headLength head length
226 | * @param {number} diameter thread diameter
227 | * @param {number} length thread length
228 | * @param {number} clearLength clearance length
229 | * @param {object} options options
230 | */
231 | export function FlatHeadScrew(
232 | headDiameter,
233 | headLength,
234 | diameter,
235 | length,
236 | clearLength,
237 | options
238 | ) {
239 | var a = headDiameter;
240 | var b = diameter;
241 | if (options && options.orientation == 'down') {
242 | a = diameter;
243 | b = headDiameter;
244 | }
245 | var head = Parts.Cone(a, b, headLength);
246 | // var head = Parts.Cylinder(headDiameter, headLength);
247 | var thread = Parts.Cylinder(diameter, length);
248 |
249 | if (clearLength) {
250 | var headClearSpace = Parts.Cylinder(headDiameter, clearLength);
251 | }
252 |
253 | return CreateScrew(head, thread, headClearSpace, options);
254 | }
255 |
--------------------------------------------------------------------------------
/v1/jscad-hardware.jscad:
--------------------------------------------------------------------------------
1 | /* exported Hardware */
2 |
3 | /**
4 | * A gear moduel for openJSCAD.
5 | * 
6 | * @example
7 | *include('jscad-utils-color.jscad');
8 | *
9 | *function mainx(params) {
10 | * util.init(CSG);
11 | *
12 | * // draws a blue hexagon
13 | * return Parts.Hexagon(10, 5).color('blue');
14 | *}
15 | * @type {Object}
16 | * @module jscad-hardware
17 | * @exports Hardware
18 | */
19 | Hardware = {
20 | Bolt: function Bolt(length, bolt, fit, BOM) {
21 | fit = fit || 'loose';
22 |
23 | if (BOM) {
24 | // Keep track of bolts for bill-of-materials
25 | var bomkey = `${bolt.name} - ${util.cm(length).toFixed(2)}`;
26 | if (!BOM[bomkey]) BOM[bomkey] = 0;
27 | BOM[bomkey]++;
28 | }
29 | var b = Parts.Hardware[bolt.type](bolt.G || bolt.D, bolt.H, bolt.E, length);
30 |
31 | var clearance = bolt[fit] - bolt.E;
32 |
33 | b.add(
34 | Parts.Hardware
35 | [bolt.type](
36 | (bolt.G || bolt.D) + clearance,
37 | bolt.H + clearance,
38 | bolt[fit],
39 | length,
40 | length
41 | )
42 | .map(part => part.color('red')),
43 | 'tap',
44 | false,
45 | 'tap-'
46 | );
47 |
48 | return b;
49 | },
50 |
51 | /**
52 | * Create a washer group from a washer type.
53 | * @param {Object} washer Washer type object.
54 | * @param {String} fit Clearance to add to group (tap|close|loose).
55 | */
56 | Washer: function Washer(washer, fit) {
57 | var w = util.group();
58 | w.add(
59 | Parts.Tube(washer.od, washer.id, washer.thickness).color('gray'),
60 | 'washer'
61 | );
62 | if (fit) {
63 | var tap = Hardware.Clearances[fit];
64 | if (!tap)
65 | console.error(
66 | `Hardware.Washer unknown fit clearance ${fit}, should be ${Object.keys(
67 | Hardware.Clarances
68 | ).join('|')}`
69 | );
70 | w.add(
71 | Parts.Cylinder(
72 | washer.od + Hardware.Clearances[fit],
73 | washer.thickness
74 | ).color('red'),
75 | 'clearance'
76 | );
77 | }
78 | return w;
79 | },
80 |
81 | Nut: function Nut(nut, fit) {
82 | return Parts.Hexagon(nut[1] + Hardware.Clearances[fit], nut[2]);
83 | },
84 |
85 | Screw: {
86 | PanHead: function(type, length, fit, options = {}) {
87 | var [headDiameter, headLength, diameter, tap, countersink] = type;
88 | return Hardware.PanHeadScrew(
89 | headDiameter,
90 | headLength,
91 | diameter,
92 | length,
93 | options.clearLength,
94 | options
95 | );
96 | },
97 |
98 | FlatHead: function(type, length, fit, options = {}) {
99 | var [headDiameter, headLength, diameter, tap, countersink] = type;
100 | return Hardware.FlatHeadScrew(
101 | headDiameter,
102 | headLength,
103 | diameter,
104 | length,
105 | options.clearLength,
106 | options
107 | );
108 | }
109 | // HexHead: Hardware.ScrewType(Hardware.PanHeadScrew, ...args)
110 | },
111 |
112 | Clearances: {
113 | tap: util.inch(-0.049),
114 | close: util.inch(0.007),
115 | loose: util.inch(0.016)
116 | },
117 |
118 | Orientation: {
119 | up: {
120 | head: 'outside-',
121 | clear: 'inside+'
122 | },
123 | down: {
124 | head: 'outside+',
125 | clear: 'inside-'
126 | }
127 | },
128 |
129 | CreateScrew: function(head, thread, headClearSpace, options) {
130 | options = util.defaults(options, {
131 | orientation: 'up',
132 | clearance: [0, 0, 0]
133 | });
134 |
135 | var orientation = Parts.Hardware.Orientation[options.orientation];
136 | var group = util.group('head,thread', {
137 | head: head.color('gray'),
138 | thread: thread.snap(head, 'z', orientation.head).color('silver')
139 | });
140 |
141 | if (headClearSpace) {
142 | group.add(
143 | headClearSpace
144 | .enlarge(options.clearance)
145 | .snap(head, 'z', orientation.clear)
146 | .color('red'),
147 | 'headClearSpace',
148 | true
149 | );
150 | }
151 |
152 | return group;
153 | },
154 |
155 | /**
156 | * Creates a `Group` object with a Pan Head Screw.
157 | * @param {number} headDiameter Diameter of the head of the screw
158 | * @param {number} headLength Length of the head
159 | * @param {number} diameter Diameter of the threaded shaft
160 | * @param {number} length Length of the threaded shaft
161 | * @param {number} clearLength Length of the clearance section of the head.
162 | * @param {object} options Screw options include orientation and clerance scale.
163 | */
164 | PanHeadScrew: function(
165 | headDiameter,
166 | headLength,
167 | diameter,
168 | length,
169 | clearLength,
170 | options
171 | ) {
172 | var head = Parts.Cylinder(headDiameter, headLength);
173 | var thread = Parts.Cylinder(diameter, length);
174 |
175 | if (clearLength) {
176 | var headClearSpace = Parts.Cylinder(headDiameter, clearLength);
177 | }
178 |
179 | return Hardware.CreateScrew(head, thread, headClearSpace, options);
180 | },
181 |
182 | /**
183 | * Creates a `Group` object with a Hex Head Screw.
184 | * @param {number} headDiameter Diameter of the head of the screw
185 | * @param {number} headLength Length of the head
186 | * @param {number} diameter Diameter of the threaded shaft
187 | * @param {number} length Length of the threaded shaft
188 | * @param {number} clearLength Length of the clearance section of the head.
189 | * @param {object} options Screw options include orientation and clerance scale.
190 | */
191 | HexHeadScrew: function(
192 | headDiameter,
193 | headLength,
194 | diameter,
195 | length,
196 | clearLength,
197 | options
198 | ) {
199 | var head = Parts.Hexagon(headDiameter, headLength);
200 | var thread = Parts.Cylinder(diameter, length);
201 |
202 | if (clearLength) {
203 | var headClearSpace = Parts.Hexagon(headDiameter, clearLength);
204 | }
205 |
206 | return Hardware.CreateScrew(head, thread, headClearSpace, options);
207 | },
208 |
209 | /**
210 | * Create a Flat Head Screw
211 | * @param {number} headDiameter head diameter
212 | * @param {number} headLength head length
213 | * @param {number} diameter thread diameter
214 | * @param {number} length thread length
215 | * @param {number} clearLength clearance length
216 | * @param {object} options options
217 | */
218 | FlatHeadScrew: function(
219 | headDiameter,
220 | headLength,
221 | diameter,
222 | length,
223 | clearLength,
224 | options
225 | ) {
226 | var a = headDiameter;
227 | var b = diameter;
228 | if (options && options.orientation == 'down') {
229 | a = diameter;
230 | b = headDiameter;
231 | }
232 | var head = Parts.Cone(a, b, headLength);
233 | // var head = Parts.Cylinder(headDiameter, headLength);
234 | var thread = Parts.Cylinder(diameter, length);
235 |
236 | if (clearLength) {
237 | var headClearSpace = Parts.Cylinder(headDiameter, clearLength);
238 | }
239 |
240 | return Hardware.CreateScrew(head, thread, headClearSpace, options);
241 | }
242 | };
243 |
--------------------------------------------------------------------------------
/src/metric.js:
--------------------------------------------------------------------------------
1 | import { util, Debug } from '@jwc/jscad-utils';
2 | const debug = Debug('jscadHardware:metric');
3 | /* exported MetricBolts, MetricScrews, MetricNuts */
4 |
5 | const ScrewTapSizes = `m1.5 0.35 1.15 56 1.25 55 1.60 1/16 1.65 52
6 | m1.6 0.35 1.25 55 1.35 54 1.70 51 1.75 50
7 | m1.8 0.35 1.45 53 1.55 1/16 1.90 49 2.00 5/64
8 | m2 0.45 1.55 1/16 1.70 51 2.10 45 2.20 44
9 | m2.2 0.45 1.75 50 1.90 48 2.30 3/32 2.40 41
10 | m2.5 0.45 2.05 46 2.20 44 2.65 37 2.75 7/64
11 | m3 0.60 2.40 41 2.60 37 3.15 1/8 3.30 30
12 | m3.5 0.60 2.90 32 3.10 31 3.70 27 3.85 24
13 | m4 0.75 3.25 30 3.50 28 4.20 19 4.40 17
14 | m4.5 0.75 3.75 25 4.00 22 4.75 13 5.00 9
15 | m5 0.90 4.10 20 4.40 17 5.25 5 5.50 7/32
16 | m5.5 0.90 4.60 14 4.90 10 5.80 1 6.10 B
17 | m6 1.00 5.00 8 5.40 4 6.30 E 6.60 G
18 | m7 1.00 6.00 B 6.40 E 7.40 L 7.70 N
19 | m8 1.25 6.80 H 7.20 J 8.40 Q 8.80 S
20 | m9 1.25 7.80 N 8.20 P 9.50 3/8 9.90 25/64
21 | m10 1.25 8.80 11/32 9.20 23/64 10.50 Z 11.00 7/16
22 | m11 1.50 9.50 3/8 10.00 X 11.60 29/64 12.10 15/32
23 | m12 1.50 10.50 Z 11.00 7/16 12.60 1/2 13.20 33/64
24 | m14 1.50 12.50 1/2 13.00 33/64 14.75 37/64 15.50 39/64
25 | m15 1.50 13.50 17/32 14.00 35/64 15.75 5/8 16.50 21/32
26 | m16 2.00 14.00 35/64 14.75 37/64 16.75 21/32 17.50 11/16
27 | m17 1.50 15.50 39/64 16.00 5/8 18.00 45/64 18.50 47/64
28 | m18 2.00 16.00 5/8 16.75 21/32 19.00 3/4 20.00 25/32
29 | m19 2.50 16.50 21/32 17.50 11/16 20.00 25/32 21.00 53/64
30 | m20 2.00 18.00 45/64 18.50 47/64 21.00 53/64 22.00 55/64`
31 | .split('\n')
32 | .reduce((bolts, line, index) => {
33 | var params = line.split(' ');
34 | var name = `${params[0]}`;
35 | bolts[name] = {
36 | name,
37 | tap: parseFloat(params[2]),
38 | close: parseFloat(params[6]),
39 | loose: parseFloat(params[8])
40 | };
41 | return bolts;
42 | }, {});
43 |
44 | debug('ScrewTapSizes', ScrewTapSizes);
45 |
46 | /**
47 | * @see http://www.atlrod.com/metric-hex-bolt-dimensions/
48 | *
49 | * E - Body Diameter
50 | * F - Width Across Flats
51 | * G - Width Across Corners
52 | * H - Head Height
53 | * D - Head Diameter
54 | *
55 | * NOMINAL SIZE (D) BODY DIAMETER HEAD THICKNESS ACROSS THE FLATS ACROSS CORNERS
56 | */
57 | const MetricHexBoltDimensions = `m10 10.00 9.78 6.63 6.17 17.00 15.73 18.48 17.77
58 | m12 12.00 11.73 7.76 4.24 19.00 17.73 20.78 20.03
59 | m14 14.00 13.73 9.09 8.51 22.00 20.67 24.25 23.35
60 | m16 16.00 15.73 10.32 9.68 24.00 23.67 27.71 26.75
61 | m20 20.00 19.67 12.88 12.12 30.00 29.16 34.64 32.95
62 | m24 24.00 23.67 15.44 14.56 36.00 35.00 41.57 39.55
63 | m30 30.00 29.67 19.48 17.92 46.00 45.00 53.12 50.85
64 | m36 36.00 35.61 23.38 21.63 55.00 53.80 63.51 60.79
65 | m42 42.00 41.38 26.97 25.03 65.00 62.90 75.06 71.71
66 | m48 48.00 47.38 31.07 28.93 75.00 72.60 86.60 82.76
67 | m56 56.00 55.26 36.2 33.80 85.00 82.20 98.15 93.71
68 | m64 64.00 63.26 41.32 38.68 95.00 91.80 109.70 104.65
69 | m72 72.00 71.26 46.45 43.55 105.00 101.40 121.24 115.60
70 | m80 80.00 79.26 51.58 48.42 115.00 111.00 132.72 126.54
71 | m90 90.00 89.13 57.74 54.26 130.00 125.50 150.11 143.07
72 | m100 90.00 99.13 63.9 60.10 145.00 140.00 167.43 159.60`
73 | .split('\n')
74 | .reduce((bolts, line) => {
75 | var params = line.split('\t');
76 | var name = `${params[0]} hex`;
77 | var tap = ScrewTapSizes[params[0]] || {
78 | tap: parseFloat(params[1]),
79 | close: parseFloat(params[1]),
80 | loose: parseFloat(params[1])
81 | };
82 | bolts[name] = {
83 | ...tap,
84 | name,
85 | E: parseFloat(params[1]),
86 | F: parseFloat(params[5]),
87 | G: parseFloat(params[7]),
88 | H: parseFloat(params[3]),
89 | type: 'HexHeadScrew'
90 | };
91 | return bolts;
92 | }, {});
93 |
94 | debug('MetricHexBoltDimensions', MetricHexBoltDimensions);
95 |
96 | /**
97 | * @see https://www.fastenal.com/content/product_specifications/M.SHCS.4762.8.8.Z.pdf
98 | *
99 | * Nominal Size (d), Body Diameter Max, min, Head Diameter max, min, Head Height max, min, Socket Size max, min, Key Engagement min
100 | *
101 | * E - Body Diameter
102 | * H - Head Height
103 | * D - Head Diameter
104 | */
105 | const SocketCapScrewDimensions = `m1.6 1.60 1.46 3.14 2.86 1.60 1.46 1.58 1.52 0.7
106 | m2 2.00 1.86 3.98 3.62 2.00 1.86 1.58 1.52 1
107 | m2.5 2.50 2.36 4.68 4.32 2.50 2.36 2.08 2.02 1.1
108 | m3 3.00 2.86 5.68 5.32 3.00 2.86 2.58 2.52 1.3
109 | m4 4.00 3.82 7.22 6.78 4.00 3.82 3.08 3.02 2
110 | m5 5.00 4.82 8.72 8.28 5.00 4.82 4.095 4.020 2.5
111 | m6 6.00 5.82 10.22 9.78 6.00 5.70 5.14 5.02 3
112 | m8 8.00 7.78 13.27 12.73 8.00 7.64 6.14 6.02 4
113 | m10 10.00 9.78 16.27 15.73 10.00 9.64 8.175 8.025 5
114 | m12 12.00 11.73 18.27 17.73 12.00 11.57 10.175 10.025 6
115 | m14 14.00 13.73 21.33 20.67 14.00 13.57 12.212 12.032 7
116 | m16 16.00 15.73 24.33 23.67 16.00 15.57 14.212 14.032 8
117 | m20 20.00 19.67 30.33 29.67 20.00 19.48 17.23 17.05 10
118 | m24 24.00 23.67 36.39 35.61 24.00 23.48 19.275 19.065 12
119 | m30 30.00 29.67 45.39 44.61 30.00 29.48 22.275 22.065 15.5
120 | m36 36.00 35.61 54.46 53.54 36.00 35.38 27.275 27.065 19
121 | m42 42.00 41.61 63.46 62.54 42.00 41.38 32.33 32.08 24`
122 | .split('\n')
123 | .reduce((screws, line, index) => {
124 | var params = line.split(' ');
125 | var name = `${params[0]} socket`;
126 | var tap = ScrewTapSizes[params[0]] || {
127 | tap: parseFloat(params[1]),
128 | close: parseFloat(params[1]),
129 | loose: parseFloat(params[1])
130 | };
131 | screws[name] = {
132 | ...tap,
133 | name,
134 | E: parseFloat(params[1]),
135 | H: parseFloat(params[5]),
136 | D: parseFloat(params[3]),
137 | type: 'PanHeadScrew'
138 | };
139 | return screws;
140 | }, {});
141 |
142 | debug('SocketCapScrewDimensions', SocketCapScrewDimensions);
143 |
144 | /**
145 | * http://www.atlrod.com/metric-hex-bolt-dimensions/
146 | * E - Body Diameter (D)
147 | * F - Width Across Flats
148 | * G - Width Across Corners (C)
149 | * H - Head Height
150 | * D - Head Diameter
151 | *
152 | * tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
153 | * @type {Object}
154 | */
155 | export const MetricBolts = {
156 | ...MetricHexBoltDimensions,
157 | ...SocketCapScrewDimensions
158 | // 'm10 hex': {
159 | // E: 10, // 10-9.78
160 | // tap: 8.5,
161 | // close: 10.5,
162 | // loose: 11,
163 | // H: 6.5, // 6.63-6.17
164 | // G: 18, // 18.48-17.77
165 | // F: 17, // 17-15.73
166 | // type: 'HexHeadScrew'
167 | // },
168 | // 'm12 hex': {
169 | // E: 12, // 12-11.73
170 | // tap: 10.3,
171 | // close: 12.6,
172 | // loose: 13.2,
173 | // H: 7.5, // 7.76-4.24
174 | // G: 20, // 20.78-20.03
175 | // F: 19, // 19-17.73
176 | // type: 'HexHeadScrew'
177 | // }
178 | };
179 |
180 | // headDiameter, headLength, diameter, tap, countersink
181 | export const MetricScrews = {
182 | m4: [8, 3.1, 4]
183 | };
184 |
185 | /**
186 | * Dimensions of nuts for imperial bolts.
187 | * F is the width across the faces, C is the width
188 | * across the points, and H is the height. D is the
189 | * basic diameter.
190 | *
191 | * [F, C, H, D]
192 | *
193 | * @see https://en.wikipedia.org/wiki/Nut_(hardware)
194 | * @type {Object}
195 | */
196 | export const MetricNuts = {
197 | m4: [7, 8.1, 3.2, 4]
198 | };
199 |
200 | /**
201 | * Metric washer sizes
202 | * Size Inside Diameter Outside Diameter Thickness
203 | * @see https://armstrongmetalcrafts.com/Reference/WasherSizes.aspx
204 | * @type {Object}
205 | */
206 | export const MetricWashers = `M1 1.1mm 3.2mm 0.3mm
207 | M1.2 1.3mm 3.8mm 0.3mm
208 | M1.4 1.5mm 3.8mm 0.3mm
209 | M1.6 1.7mm 4.0mm 0.3mm
210 | M2 2.2mm 5.0mm 0.3mm
211 | M2.5 2.7mm 6.0mm 0.5mm
212 | M3 3.2mm 7.0mm 0.5mm
213 | M3.5 3.7mm 8.0mm 0.5mm
214 | M4 4.3mm 9.0mm 0.8mm
215 | M5 5.3mm 10mm 1mm
216 | M6 6.4mm 12mm 1.6mm
217 | M7 7.4mm 14mm 1.6mm
218 | M8 8.4mm 16mm 1.6mm
219 | M10 10.5mm 20mm 2.0mm
220 | M11 12mm 24mm 2.5mm
221 | M12 13mm 24mm 2.5mm
222 | M14 15mm 28mm 2.5mm
223 | M16 17mm 30mm 3.0mm
224 | M18 19mm 34mm 3.0mm
225 | M20 21mm 37mm 3.0mm`
226 | .split('\n')
227 | .reduce(function ParseWasher(washers, line) {
228 | const [size, id, od, thickness] = line
229 | .replace(/mm/g, '')
230 | .split('\t')
231 | .map(function parseValues(field, index) {
232 | return index == 0 ? field : parseFloat(field);
233 | });
234 | washers[size] = { size, id, od, thickness };
235 | return washers;
236 | }, {});
237 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/code/hardware.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | hardware
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/githubdocs/themes/architect/images/hr.png:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Page not found · GitHub Pages
7 |
50 |
51 |
52 |
53 |
54 |
55 |
404
56 |
File not found
57 |
58 |
59 | The site configured at this address does not
60 | contain the requested file.
61 |
62 |
63 |
64 | If this is your site, make sure that the filename case matches the URL.
65 | For root URLs (like http://example.com/) you must provide an
66 | index.html file.
67 |
68 |
69 |
70 | Read the full documentation
71 | for more information about using GitHub Pages .
72 |
73 |
74 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/js/6.4b3ce8a0.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[6],{267:function(e,t,a){"use strict";a.r(t);var r=a(38),d=Object(r.a)({},function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"hardware"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#hardware","aria-hidden":"true"}},[e._v("#")]),e._v(" hardware")]),e._v(" "),a("p",[a("a",{attrs:{name:"module_jscad-hardware"}})]),e._v(" "),a("h2",{attrs:{id:"jscad-hardware-object"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jscad-hardware-object","aria-hidden":"true"}},[e._v("#")]),e._v(" jscad-hardware : "),a("code",[e._v("Object")])]),e._v(" "),a("p",[e._v("A gear moduel for openJSCAD.\n"),a("img",{attrs:{src:"jsdoc2md/hexagon.png",alt:"parts example"}})]),e._v(" "),a("p",[a("strong",[e._v("Example")])]),e._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[e._v("include")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v("'jscad-utils-color.jscad'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("function")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[e._v("mainx")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[e._v("params")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n util"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[e._v("init")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token constant"}},[e._v("CSG")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// draws a blue hexagon")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("return")]),e._v(" Parts"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[e._v("Hexagon")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[e._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[e._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[e._v("color")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v("'blue'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),a("ul",[a("li",[a("a",{attrs:{href:"#module_jscad-hardware"}},[e._v("jscad-hardware")]),e._v(" : "),a("code",[e._v("Object")]),e._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"#module_jscad-hardware.Washer"}},[e._v(".Washer(washer, fit)")])]),e._v(" "),a("li",[a("a",{attrs:{href:"#module_jscad-hardware.PanHeadScrew"}},[e._v(".PanHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)")])]),e._v(" "),a("li",[a("a",{attrs:{href:"#module_jscad-hardware.HexHeadScrew"}},[e._v(".HexHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)")])]),e._v(" "),a("li",[a("a",{attrs:{href:"#module_jscad-hardware.FlatHeadScrew"}},[e._v(".FlatHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)")])])])])]),e._v(" "),a("p",[a("a",{attrs:{name:"module_jscad-hardware.Washer"}})]),e._v(" "),a("h3",{attrs:{id:"jscad-hardware-washer-washer-fit"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jscad-hardware-washer-washer-fit","aria-hidden":"true"}},[e._v("#")]),e._v(" jscad-hardware.Washer(washer, fit)")]),e._v(" "),a("p",[e._v("Create a washer group from a washer type.")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": static method of "),a("a",{attrs:{href:"#module_jscad-hardware"}},[a("code",[e._v("jscad-hardware")])])]),e._v(" "),a("table",[a("thead",[a("tr",[a("th",[e._v("Param")]),e._v(" "),a("th",[e._v("Type")]),e._v(" "),a("th",[e._v("Description")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("washer")]),e._v(" "),a("td",[a("code",[e._v("Object")])]),e._v(" "),a("td",[e._v("Washer type object.")])]),e._v(" "),a("tr",[a("td",[e._v("fit")]),e._v(" "),a("td",[a("code",[e._v("String")])]),e._v(" "),a("td",[e._v("Clearance to add to group (tap")])])])]),e._v(" "),a("p",[a("a",{attrs:{name:"module_jscad-hardware.PanHeadScrew"}})]),e._v(" "),a("h3",{attrs:{id:"jscad-hardware-panheadscrew-headdiameter-headlength-diameter-length-clearlength-options"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jscad-hardware-panheadscrew-headdiameter-headlength-diameter-length-clearlength-options","aria-hidden":"true"}},[e._v("#")]),e._v(" jscad-hardware.PanHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)")]),e._v(" "),a("p",[e._v("Creates a "),a("code",[e._v("Group")]),e._v(" object with a Pan Head Screw.")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": static method of "),a("a",{attrs:{href:"#module_jscad-hardware"}},[a("code",[e._v("jscad-hardware")])])]),e._v(" "),a("table",[a("thead",[a("tr",[a("th",[e._v("Param")]),e._v(" "),a("th",[e._v("Type")]),e._v(" "),a("th",[e._v("Description")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("headDiameter")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Diameter of the head of the screw")])]),e._v(" "),a("tr",[a("td",[e._v("headLength")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Length of the head")])]),e._v(" "),a("tr",[a("td",[e._v("diameter")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Diameter of the threaded shaft")])]),e._v(" "),a("tr",[a("td",[e._v("length")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Length of the threaded shaft")])]),e._v(" "),a("tr",[a("td",[e._v("clearLength")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Length of the clearance section of the head.")])]),e._v(" "),a("tr",[a("td",[e._v("options")]),e._v(" "),a("td",[a("code",[e._v("object")])]),e._v(" "),a("td",[e._v("Screw options include orientation and clerance scale.")])])])]),e._v(" "),a("p",[a("a",{attrs:{name:"module_jscad-hardware.HexHeadScrew"}})]),e._v(" "),a("h3",{attrs:{id:"jscad-hardware-hexheadscrew-headdiameter-headlength-diameter-length-clearlength-options"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jscad-hardware-hexheadscrew-headdiameter-headlength-diameter-length-clearlength-options","aria-hidden":"true"}},[e._v("#")]),e._v(" jscad-hardware.HexHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)")]),e._v(" "),a("p",[e._v("Creates a "),a("code",[e._v("Group")]),e._v(" object with a Hex Head Screw.")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": static method of "),a("a",{attrs:{href:"#module_jscad-hardware"}},[a("code",[e._v("jscad-hardware")])])]),e._v(" "),a("table",[a("thead",[a("tr",[a("th",[e._v("Param")]),e._v(" "),a("th",[e._v("Type")]),e._v(" "),a("th",[e._v("Description")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("headDiameter")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Diameter of the head of the screw")])]),e._v(" "),a("tr",[a("td",[e._v("headLength")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Length of the head")])]),e._v(" "),a("tr",[a("td",[e._v("diameter")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Diameter of the threaded shaft")])]),e._v(" "),a("tr",[a("td",[e._v("length")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Length of the threaded shaft")])]),e._v(" "),a("tr",[a("td",[e._v("clearLength")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("Length of the clearance section of the head.")])]),e._v(" "),a("tr",[a("td",[e._v("options")]),e._v(" "),a("td",[a("code",[e._v("object")])]),e._v(" "),a("td",[e._v("Screw options include orientation and clerance scale.")])])])]),e._v(" "),a("p",[a("a",{attrs:{name:"module_jscad-hardware.FlatHeadScrew"}})]),e._v(" "),a("h3",{attrs:{id:"jscad-hardware-flatheadscrew-headdiameter-headlength-diameter-length-clearlength-options"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jscad-hardware-flatheadscrew-headdiameter-headlength-diameter-length-clearlength-options","aria-hidden":"true"}},[e._v("#")]),e._v(" jscad-hardware.FlatHeadScrew(headDiameter, headLength, diameter, length, clearLength, options)")]),e._v(" "),a("p",[e._v("Create a Flat Head Screw")]),e._v(" "),a("p",[a("strong",[e._v("Kind")]),e._v(": static method of "),a("a",{attrs:{href:"#module_jscad-hardware"}},[a("code",[e._v("jscad-hardware")])])]),e._v(" "),a("table",[a("thead",[a("tr",[a("th",[e._v("Param")]),e._v(" "),a("th",[e._v("Type")]),e._v(" "),a("th",[e._v("Description")])])]),e._v(" "),a("tbody",[a("tr",[a("td",[e._v("headDiameter")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("head diameter")])]),e._v(" "),a("tr",[a("td",[e._v("headLength")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("head length")])]),e._v(" "),a("tr",[a("td",[e._v("diameter")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("thread diameter")])]),e._v(" "),a("tr",[a("td",[e._v("length")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("thread length")])]),e._v(" "),a("tr",[a("td",[e._v("clearLength")]),e._v(" "),a("td",[a("code",[e._v("number")])]),e._v(" "),a("td",[e._v("clearance length")])]),e._v(" "),a("tr",[a("td",[e._v("options")]),e._v(" "),a("td",[a("code",[e._v("object")])]),e._v(" "),a("td",[e._v("options")])])])])])},[],!1,null,null,null);t.default=d.exports}}]);
--------------------------------------------------------------------------------
/src/imperial.js:
--------------------------------------------------------------------------------
1 | import { util, Debug } from '@jwc/jscad-utils';
2 | const debug = Debug('jscadHardware:imperial');
3 |
4 | /* exported ImperialBolts, ImperialWashers */
5 |
6 | function parseImperial(field) {
7 | var value = [/(\d+)-(\d+)\/(\d+)/, /(\d+)\/(\d+)/, /(\d+)/].reduce(
8 | function parseImperial(value, re, idx) {
9 | if (!value) {
10 | var match = field.match(re);
11 | if (match && idx == 0)
12 | value = parseInt(match[1]) + parseInt(match[2]) / parseInt(match[3]);
13 |
14 | if (match && idx == 1) value = parseInt(match[1]) / parseInt(match[2]);
15 |
16 | if (match && idx == 2) value = parseInt(match[1]);
17 | }
18 | return value;
19 | },
20 | undefined
21 | );
22 | return util.inch(value);
23 | }
24 |
25 | function parseValues(field, index) {
26 | if (index == 0) return field;
27 | if (field == '-') return;
28 | return parseImperial(field);
29 | }
30 |
31 | const ScrewTapSizes = `0 .0600 80 .0447 3/64 .0469 55 .0520 52 .0635 50 .0700
32 | 1 .0730 64 .0538 53 .0595 1/16 .0625 48 .0760 46 .0810
33 | 2 .0860 56 .0641 50 .0700 49 .0730 43 .0890 41 .0960
34 | 3 .0990 48 .0734 47 .0785 44 .0860 37 .1040 35 .1100
35 | 4 .1120 40 .0813 43 .0890 41 .0960 32 .1160 30 .1285
36 | 5 .125 40 .0943 38 .1015 7/64 .1094 30 .1285 29 .1360
37 | 6 .138 32 .0997 36 .1065 32 .1160 27 .1440 25 .1495
38 | 8 .1640 32 .1257 29 .1360 27 .1440 18 .1695 16 .1770
39 | 10 .1900 24 .1389 25 .1495 20 .1610 9 .1960 7 .2010
40 | 12 .2160 24 .1649 16 .1770 12 .1890 2 .2210 1 .2280
41 | 1/4 .2500 20 .1887 7 .2010 7/32 .2188 F .2570 H .2660
42 | 5/16 .3125 18 .2443 F .2570 J .2770 P .3230 Q .3320
43 | 3/8 .3750 16 .2983 5/16 .3125 Q .3320 W .3860 X .3970
44 | 7/16 .4375 14 .3499 U .3680 25/64 .3906 29/64 .4531 15/32 .4687
45 | 1/2 .5000 13 .4056 27/64 .4219 29/64 .4531 33/64 .5156 17/32 .5312
46 | 9/16 .5625 12 .4603 31/64 .4844 33/64 .5156 37/64 .5781 19/32 .5938
47 | 5/8 .6250 11 .5135 17/32 .5312 9/16 .5625 41/64 .6406 21/32 .6562
48 | 11/16 .6875 24 .6364 41/64 .6406 21/32 .6562 45/64 .7031 23/32 .7188
49 | 3/4 .7500 10 .6273 21/32 .6562 11/16 .6875 49/64 .7656 25/32 .7812
50 | 13/16 .8125 20 .7512 49/64 .7656 25/32 .7812 53/64 .8281 27/32 .8438
51 | 7/8 .8750 9 .7387 49/64 .7656 51/64 .7969 57/64 .8906 29/32 .9062
52 | 15/16 .9375 20 .8762 57/64 .8906 29/32 .9062 61/64 .9531 31/32 .9688
53 | 1 1.000 8 .8466 7/8 .8750 59/64 .9219 1-1/64 1.0156 1-1/32 1.0313`
54 | .split('\n')
55 | .reduce((bolts, line, index) => {
56 | var params = line.split('\t');
57 | var name = `${index < 10 ? '#' : ''}${params[0]}`;
58 | bolts[name] = {
59 | name,
60 | tap: util.inch(parseFloat(params[5])),
61 | close: util.inch(parseFloat(params[9])),
62 | loose: util.inch(parseFloat(params[11]))
63 | };
64 | return bolts;
65 | }, {});
66 |
67 | /**
68 | * Screw Size, Major Diameter, Threads Per Inch, Minor Diameter, Tap Plastic Drill Size, Tap Plastic Decimal Equiv., Tap Steel Drill Size, Tap Steel Decimal Equiv., Close Fit Drill Size, Close Fit Decimal Equiv., Free Fit Drill Size, Free Fit Decimal Equiv.
69 | *
70 | * @see http://www.americanfastener.com/cap-screws/
71 | * @see https://www.aftfasteners.com/fully-threaded-hex-tap-bolts-dimensions-mechanical-properties/
72 | * E - Body Diameter
73 | * F - Width Across Flats
74 | * G - Width Across Corners
75 | * H - Head Height
76 | * D - Head Diameter
77 | *
78 | * tap sizes: @see https://littlemachineshop.com/reference/tapdrill.php
79 | * @type {Object}
80 | */
81 | const HexBoltDimensions = `1/4 7/16 .438 .428 .505 .488 5/32 .163 .150
82 | 5/16 1/2 .500 .489 .577 .557 13/64 .211 .195
83 | 3/8 9/16 .562 .551 .650 .628 15/64 .243 .226
84 | 7/16 5/8 .625 .612 .722 .698 9/32 .291 .272
85 | 1/2 3/4 .750 .736 .866 .840 5/16 .323 .302
86 | 9/16 13/16 .812 .798 .938 .910 23/64 .371 .348
87 | 5/8 15/16 .938 .922 1.083 1.051 25/64 .403 .378
88 | 3/4 1-1/8 1.125 1.100 1.299 1.254 15/32 .483 .455
89 | 7/8 1-5/16 1.312 1.269 1.516 1.447 37/64 .604 .531
90 | 1 1-1/2 1.500 1.450 1.732 1.653 43/64 .700 .591
91 | 1-1/4 1-7/8 1.875 1.812 2.165 2.066 27/32 .876 .749`
92 | .split('\n')
93 | .reduce((bolts, line) => {
94 | var params = line.split('\t');
95 | var name = `${params[0]} hex`;
96 | var tap = ScrewTapSizes[params[0]] || {
97 | tap: parseImperial(params[0]),
98 | close: parseImperial(params[0]),
99 | loose: parseImperial(params[0])
100 | };
101 | bolts[name] = {
102 | ...tap,
103 | name,
104 | E: parseImperial(params[0]),
105 | F: parseImperial(params[1]),
106 | G: util.inch(parseFloat(params[4])),
107 | H: parseImperial(params[6]),
108 | type: 'HexHeadScrew'
109 | };
110 | return bolts;
111 | }, {});
112 |
113 | /**
114 | * Socket cap screw dimensions.
115 | *
116 | * E - Body Diameter
117 | * H - Head Height
118 | * D - Head Diameter
119 | *
120 | * @see https://www.aftfasteners.com/socket-cap-screws-dimensions-and-mechanical-properties/
121 | */
122 | const SocketCapScrewDimensions = `0 0.0600 0.0568 0.096 0.091 0.060 0.057 0.004 0.050 0.074 0.062 0.025 0.020 0.007
123 | 1 0.0730 0.0695 0.118 0.112 0.073 0.070 0.005 1/16 0.087 0.075 0.031 0.025 0.007
124 | 2 0.0860 0.0822 0.140 0.134 0.086 0.083 0.008 5/64 0.102 0.090 0.038 0.029 0.007
125 | 3 0.0990 0.0949 0.161 0.154 0.099 0.095 0.008 5/64 0.115 0.102 0.044 0.034 0.007
126 | 4 0.1120 0.1075 0.183 0.176 0.112 0.108 0.009 3/832 0.130 0.117 0.051 0.038 0.008
127 | 5 0.1250 0.1202 0.205 0.198 0.125 0.121 0.012 3/32 0.145 0.132 0.057 0.043 0.008
128 | 6 0.1380 0.1329 0.226 0.218 0.138 0.134 0.013 7/64 0.158 0.144 0.064 0.047 0.008
129 | 8 0.1640 0.1585 0.270 0.262 0.164 0.159 0.014 9/64 0.188 0.172 0.077 0.056 0.008
130 | 10 0.1900 0.1840 0.312 0.303 0.207 0.185 0.018 5/32 0.218 0.202 0.090 0.065 0.008
131 | 1/4 0.2500 0.2435 0.375 0.365 0.250 0.244 0.025 3/16 0.278 0.261 0.120 0.095 0.010
132 | 5/16 0.3125 0.3053 0.469 0.457 0.312 0.306 0.033 1/4 0.347 0.329 0.151 0.119 0.010
133 | 3/8 0.3750 0.3678 0.562 0.550 0.375 0.368 0.040 5/16 0.415 0.397 0.182 0.143 0.010
134 | 7/16 0.4375 0.4294 0.656 0.642 0.438 0.430 0.047 3/8 0.484 0.465 0.213 0.166 0.015
135 | 1/2 0.5000 0.4919 0.750 0.735 0.500 0.492 0.055 3/8 0.552 0.531 0.245 0.190 0.015
136 | 5/8 0.6250 0.6163 0.938 0.921 0.625 0.616 0.070 1/2 0.689 0.664 0.307 0.238 0.015
137 | 3/4 0.7500 0.7406 1.125 1.107 0.750 0.740 0.085 5/8 0.828 0.800 0.370 0.285 0.015
138 | 7/8 0.8750 0.8647 1.312 1.293 0.875 0.864 0.100 3/4 0.963 0.932 0.432 0.333 0.020
139 | 1 1.0000 0.9886 1.500 1.479 1.000 0.988 0.114 3/4 1.100 1.068 0.495 0.380 0.020
140 | 1-1/4 1.2500 1.2336 1.875 1.852 1.250 1.236 0.144 7/8 1.370 1.333 0.620 0.475 0.020
141 | 1-1/2 1.5000 1.4818 2.250 2.224 1.500 1.485 0.176 1 1.640 1.601 0.745 0.570 0.020`
142 | .split('\n')
143 | .reduce((screws, line, index) => {
144 | var params = line.split('\t');
145 | var name = `${index < 9 ? '#' : ''}${params[0]} socket`;
146 | var tap = ScrewTapSizes[params[0]] || {
147 | tap: util.inch(parseFloat(params[3])),
148 | close: util.inch(parseFloat(params[3])),
149 | loose: util.inch(parseFloat(params[3]))
150 | };
151 | screws[name] = {
152 | ...tap,
153 | name,
154 | E: util.inch(parseFloat(params[1])),
155 | H: util.inch(parseFloat(params[5])),
156 | D: util.inch(parseFloat(params[3])),
157 | type: 'PanHeadScrew'
158 | };
159 | return screws;
160 | }, {});
161 |
162 | /**
163 | * http://www.americanfastener.com/cap-screws/
164 | * E - Body Diameter
165 | * F - Width Across Flats
166 | * G - Width Across Corners
167 | * H - Head Height
168 | * D - Head Diameter
169 | *
170 | * tap sizes: https://littlemachineshop.com/reference/TapDrillSizes.pdf
171 | * @type {Object}
172 | */
173 | export const ImperialBolts = {
174 | ...HexBoltDimensions,
175 | ...SocketCapScrewDimensions
176 | };
177 |
178 | /**
179 | * Imperial washer sizes
180 | * Size Inside Diameter Outside Diameter Thickness
181 | * @see https://armstrongmetalcrafts.com/Reference/WasherSizes.aspx
182 | * @see http://almabolt.com/pages/catalog/washers/fender.htm
183 | * @type {Object}
184 | */
185 | export const ImperialWashers = Object.assign(
186 | `3/16 1/4" 9/16" 3/64"
187 | 1/4 5/16" 3/4" 1/16"
188 | 5/16 3/8" 7/8" 5/64"
189 | 3/8 7/16" 1" 5/64"
190 | 7/16 1/2" 1-1/4" 5/64"
191 | 1/2 9/16" 1-3/8" 7/64"
192 | 9/16 5/8" 1-1/2" 7/64"
193 | 5/8 11/16" 1-3/4" 9/64"
194 | 3/4 13/16" 2" 5/32"
195 | 7/8 15/16" 2-1/4" 1/64"
196 | 1 1-1/16" 2-1/2" 11/64"
197 | 1-1/8 1-1/4" 2-3/4" 11/64"
198 | 1-1/4 1-3/8" 3" 11/64"
199 | 1-3/8 1-1/2" 2-1/4" 3/16"
200 | 1-1/2 1-5/8" 3-1/2" 3/16"
201 | 1-5/8 1-3/4" 3-3/4" 3/16"
202 | 1-3/4 1-7/8" 4" 3/16"
203 | 2 2-1/8" 4-1/2" 3/16"
204 | 2-1/2 2-5/8" 4-1/2" 3/16"
205 | 3 3-1/8" 5-1/2" 9/32"`
206 | .split('\n')
207 | .reduce(function ParseWasher(washers, line) {
208 | const [size, id, od, thickness] = line
209 | .replace(/\"/g, '')
210 | .split('\t')
211 | .map(parseValues);
212 | washers[size] = { size, id, od, thickness };
213 | return washers;
214 | }, {}),
215 | {
216 | '1/4 fender': {
217 | size: '1/4 fender',
218 | od: util.inch(1.25),
219 | id: util.inch(0.28125),
220 | thickness: util.inch(0.08) // .051/.080
221 | }
222 | }
223 | );
224 |
225 | const WoodScrewDiameter = `2 .086 26 .090 .079 .090 .079 .075 .064 .010
226 | 3 .099 24 .103 .092 .103 .092 .086 .075 .014
227 | 4 .112 22 .116 .105 .116 .105 .095 .084 .016
228 | 5 .125 20 .129 .118 .129 .118 .107 .096 .018
229 | 6 .138 18 .142 .131 .142 .131 .118 .107 .020
230 | 7 .151 16 .155 .144 .155 .144 .127 .116 .022
231 | 8 .164 15 .168 .157 .168 .157 .136 .125 .023
232 | 9 .177 14 .181 .170 .181 .170 .147 .136 .026
233 | 10 .190 13 .194 .183 .194 .183 .157 .146 .030
234 | 12 .216 11 .220 .209 .220 .209 .176 .165 .031
235 | 14 .242 10 .246 .235 .246 .235 .201 .190 .035
236 | 16 .268 9 .272 .261 .272 .261 .214 .203 .038`
237 | .split('\n')
238 | .reduce((values, line) => {
239 | var params = line.split('\t');
240 | values[`#${params[0]}`] = util.inch(parseFloat(params[1]));
241 | return values;
242 | }, {});
243 |
244 | /**
245 | * Imperial wood screws.
246 | * @see https://www.aftfasteners.com/wood-screws-dimensions-mechanical-specs/
247 | * headDiameter, headLength, diameter, tap, countersink
248 | */
249 | export const ImperialWoodScrews = `2 1 .172 .147 .051 .031 .023 .023 .015 .102 .089 .063 .047 .017
250 | 3 1 .199 .141 .059 .035 .027 .027 .017 .107 .094 .068 .052 .018
251 | 4 1 .225 .195 .067 .039 .031 .030 .020 .128 .115 .089 .073 .018
252 | 5 2 .252 .220 .075 .043 .035 .034 .022 .154 .141 .086 .063 .027
253 | 6 2 .279 .244 .083 .048 .039 .038 .024 .174 .161 .106 .083 .029
254 | 7 2 .305 .268 .091 .048 .039 .041 .027 .189 .176 .121 .098 .030
255 | 8 2 .332 .292 .100 .054 .045 .045 .029 .204 .191 .136 .113 .032
256 | 9 2 .358 .316 .108 .054 .045 .049 .032 .214 .201 .146 .123 .033
257 | 10 3 .385 .340 .116 .060 .050 .053 .034 .258 .245 .146 .123 .034
258 | 12 3 .438 .389 .132 .067 .056 .060 .039 .283 .270 .171 .148 .036
259 | 14 3 .507 .452 .153 .075 .064 .070 .046 .283 .270 .171 .148 .036
260 | 16 3 .544 .485 .164 .075 .064 .075 .049 .303 .290 .191 .168 .039`
261 | .split('\n')
262 | .reduce((screws, line) => {
263 | var params = line
264 | .split('\t')
265 | .map((value, index) => (index > 1 ? parseFloat(value) : value));
266 | screws[`#${params[0]}`] = [
267 | util.inch(params[2]),
268 | util.inch(params[4]),
269 | WoodScrewDiameter[`#${params[0]}`]
270 | ];
271 | return screws;
272 | }, {});
273 |
274 | /**
275 | * Dimensions of nuts for imperial bolts.
276 | * F is the width across teh faces, C is the width
277 | * across the points, and H is the height. D is the
278 | * basic diameter.
279 | *
280 | * [F, C, H, D]
281 | *
282 | * @see https://en.wikipedia.org/wiki/Nut_(hardware)
283 | * @see https://www.boltdepot.com/fastener-information/nuts-washers/us-nut-dimensions.aspx
284 | * @type {Object}
285 | */
286 | export const ImperialNuts = `#0 - 5/32" - - - 3/64"
287 | #1 - 5/32" - - - 3/64"
288 | #2 - 3/16" - - 9/64" 1/16"
289 | #3 - 3/16" - - 9/64" 1/16"
290 | #4 - 1/4" - - 9/64" 3/32"
291 | #6 - 5/16" - - 11/64" 7/64"
292 | #8 - 11/32" - - 15/64" 1/8"
293 | #10 - 3/8" - - 15/64" 1/8"
294 | #12 - 7/16" - - 5/16" 5/32"
295 | 1/4 7/16" 7/16" 7/32" 5/32" 5/16" 3/16"
296 | 5/16 1/2" 9/16" 17/64" 3/16" 11/32" 7/32"
297 | 3/8 9/16" 5/8" 21/64" 7/32" 29/64" 1/4"
298 | 7/16 11/16" - 3/8" 1/4" 29/64" -
299 | 1/2 3/4" - 7/16" 5/16" 19/32" -
300 | 9/16 7/8" - 31/64" 5/16" 41/64" -
301 | 5/8 15/16" - 35/64" 3/8" 3/4" -
302 | 3/4 1-1/8" - 41/64" 27/64" 7/8" -
303 | 7/8 1-5/16" - 3/4" 31/64" 63/64" -
304 | 1 1-1/2" - 55/64" 35/64" 1-3/64" -`
305 | .split('\n')
306 | .reduce((nuts, line) => {
307 | var params = line.split('\t').map(parseValues);
308 | var flatDiameter = params[1] || params[2];
309 | var cornerDiameter = flatDiameter / (Math.sqrt(3) / 2);
310 | var height = params[3] || params[6];
311 | nuts[`${params[0]} hex`] = [
312 | flatDiameter,
313 | cornerDiameter,
314 | height,
315 | cornerDiameter / 2 // the boltdepot data does not have the hole diameter
316 | ];
317 | return nuts;
318 | }, {});
319 |
--------------------------------------------------------------------------------
/githubdocs/themes/architect/css/style.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 | /** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
3 | html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ }
4 |
5 | /** Remove default margin. */
6 | body { margin: 0; }
7 |
8 | /* HTML5 display definitions ========================================================================== */
9 | /** Correct `block` display not defined for any HTML5 element in IE 8/9. Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox. Correct `block` display not defined for `main` in IE 11. */
10 | article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary { display: block; }
11 |
12 | /** 1. Correct `inline-block` display not defined in IE 8/9. 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. */
13 | audio, canvas, progress, video { display: inline-block; /* 1 */ vertical-align: baseline; /* 2 */ }
14 |
15 | /** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
16 | audio:not([controls]) { display: none; height: 0; }
17 |
18 | /** Address `[hidden]` styling not present in IE 8/9/10. Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. */
19 | [hidden], template { display: none; }
20 |
21 | /* Links ========================================================================== */
22 | /** Remove the gray background color from active links in IE 10. */
23 | a { background-color: transparent; }
24 |
25 | /** Improve readability when focused and also mouse hovered in all browsers. */
26 | a:active, a:hover { outline: 0; }
27 |
28 | /* Text-level semantics ========================================================================== */
29 | /** Address styling not present in IE 8/9/10/11, Safari, and Chrome. */
30 | abbr[title] { border-bottom: 1px dotted; }
31 |
32 | /** Address style set to `bolder` in Firefox 4+, Safari, and Chrome. */
33 | b, strong { font-weight: bold; }
34 |
35 | /** Address styling not present in Safari and Chrome. */
36 | dfn { font-style: italic; }
37 |
38 | /** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari, and Chrome. */
39 | h1 { font-size: 2em; margin: 0.67em 0; }
40 |
41 | /** Address styling not present in IE 8/9. */
42 | mark { background: #ff0; color: #000; }
43 |
44 | /** Address inconsistent and variable font size in all browsers. */
45 | small { font-size: 80%; }
46 |
47 | /** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
48 | sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
49 |
50 | sup { top: -0.5em; }
51 |
52 | sub { bottom: -0.25em; }
53 |
54 | /* Embedded content ========================================================================== */
55 | /** Remove border when inside `a` element in IE 8/9/10. */
56 | img { border: 0; }
57 |
58 | /** Correct overflow not hidden in IE 9/10/11. */
59 | svg:not(:root) { overflow: hidden; }
60 |
61 | /* Grouping content ========================================================================== */
62 | /** Address margin not present in IE 8/9 and Safari. */
63 | figure { margin: 1em 40px; }
64 |
65 | /** Address differences between Firefox and other browsers. */
66 | hr { box-sizing: content-box; height: 0; }
67 |
68 | /** Contain overflow in all browsers. */
69 | pre { overflow: auto; }
70 |
71 | /** Address odd `em`-unit font size rendering in all browsers. */
72 | code, kbd, pre, samp { font-family: monospace, monospace; font-size: 1em; }
73 |
74 | /* Forms ========================================================================== */
75 | /** Known limitation: by default, Chrome and Safari on OS X allow very limited styling of `select`, unless a `border` property is set. */
76 | /** 1. Correct color not being inherited. Known issue: affects color of disabled elements. 2. Correct font properties not being inherited. 3. Address margins set differently in Firefox 4+, Safari, and Chrome. */
77 | button, input, optgroup, select, textarea { color: inherit; /* 1 */ font: inherit; /* 2 */ margin: 0; /* 3 */ }
78 |
79 | /** Address `overflow` set to `hidden` in IE 8/9/10/11. */
80 | button { overflow: visible; }
81 |
82 | /** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. Correct `select` style inheritance in Firefox. */
83 | button, select { text-transform: none; }
84 |
85 | /** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */
86 | button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }
87 |
88 | /** Re-set default cursor for disabled elements. */
89 | button[disabled], html input[disabled] { cursor: default; }
90 |
91 | /** Remove inner padding and border in Firefox 4+. */
92 | button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
93 |
94 | /** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
95 | input { line-height: normal; }
96 |
97 | /** It's recommended that you don't attempt to style these elements. Firefox's implementation doesn't respect box-sizing, padding, or width. 1. Address box sizing set to `content-box` in IE 8/9/10. 2. Remove excess padding in IE 8/9/10. */
98 | input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }
99 |
100 | /** Fix the cursor style for Chrome's increment/decrement buttons. For certain `font-size` values of the `input`, it causes the cursor style of the decrement button to change from `default` to `text`. */
101 | input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { height: auto; }
102 |
103 | /** 1. Address `appearance` set to `searchfield` in Safari and Chrome. 2. Address `box-sizing` set to `border-box` in Safari and Chrome (include `-moz` to future-proof). */
104 | input[type="search"] { -webkit-appearance: textfield; /* 1 */ /* 2 */ box-sizing: content-box; }
105 |
106 | /** Remove inner padding and search cancel button in Safari and Chrome on OS X. Safari (but not Chrome) clips the cancel button when the search input has padding (and `textfield` appearance). */
107 | input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
108 |
109 | /** Define consistent border, margin, and padding. */
110 | fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
111 |
112 | /** 1. Correct `color` not being inherited in IE 8/9/10/11. 2. Remove padding so people aren't caught out if they zero out fieldsets. */
113 | legend { border: 0; /* 1 */ padding: 0; /* 2 */ }
114 |
115 | /** Remove default vertical scrollbar in IE 8/9/10/11. */
116 | textarea { overflow: auto; }
117 |
118 | /** Don't inherit the `font-weight` (applied by a rule above). NOTE: the default cannot safely be changed in Chrome and Safari on OS X. */
119 | optgroup { font-weight: bold; }
120 |
121 | /* Tables ========================================================================== */
122 | /** Remove most spacing between table cells. */
123 | table { border-collapse: collapse; border-spacing: 0; }
124 |
125 | td, th { padding: 0; }
126 |
127 | .highlight table td { padding: 5px; }
128 |
129 | .highlight table pre { margin: 0; }
130 |
131 | .highlight .cm { color: #999988; font-style: italic; }
132 |
133 | .highlight .cp { color: #999999; font-weight: bold; }
134 |
135 | .highlight .c1 { color: #999988; font-style: italic; }
136 |
137 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic; }
138 |
139 | .highlight .c, .highlight .cd { color: #999988; font-style: italic; }
140 |
141 | .highlight .err { color: #a61717; background-color: #e3d2d2; }
142 |
143 | .highlight .gd { color: #000000; background-color: #ffdddd; }
144 |
145 | .highlight .ge { color: #000000; font-style: italic; }
146 |
147 | .highlight .gr { color: #aa0000; }
148 |
149 | .highlight .gh { color: #999999; }
150 |
151 | .highlight .gi { color: #000000; background-color: #ddffdd; }
152 |
153 | .highlight .go { color: #888888; }
154 |
155 | .highlight .gp { color: #555555; }
156 |
157 | .highlight .gs { font-weight: bold; }
158 |
159 | .highlight .gu { color: #aaaaaa; }
160 |
161 | .highlight .gt { color: #aa0000; }
162 |
163 | .highlight .kc { color: #000000; font-weight: bold; }
164 |
165 | .highlight .kd { color: #000000; font-weight: bold; }
166 |
167 | .highlight .kn { color: #000000; font-weight: bold; }
168 |
169 | .highlight .kp { color: #000000; font-weight: bold; }
170 |
171 | .highlight .kr { color: #000000; font-weight: bold; }
172 |
173 | .highlight .kt { color: #445588; font-weight: bold; }
174 |
175 | .highlight .k, .highlight .kv { color: #000000; font-weight: bold; }
176 |
177 | .highlight .mf { color: #009999; }
178 |
179 | .highlight .mh { color: #009999; }
180 |
181 | .highlight .il { color: #009999; }
182 |
183 | .highlight .mi { color: #009999; }
184 |
185 | .highlight .mo { color: #009999; }
186 |
187 | .highlight .m, .highlight .mb, .highlight .mx { color: #009999; }
188 |
189 | .highlight .sb { color: #d14; }
190 |
191 | .highlight .sc { color: #d14; }
192 |
193 | .highlight .sd { color: #d14; }
194 |
195 | .highlight .s2 { color: #d14; }
196 |
197 | .highlight .se { color: #d14; }
198 |
199 | .highlight .sh { color: #d14; }
200 |
201 | .highlight .si { color: #d14; }
202 |
203 | .highlight .sx { color: #d14; }
204 |
205 | .highlight .sr { color: #009926; }
206 |
207 | .highlight .s1 { color: #d14; }
208 |
209 | .highlight .ss { color: #990073; }
210 |
211 | .highlight .s { color: #d14; }
212 |
213 | .highlight .na { color: #008080; }
214 |
215 | .highlight .bp { color: #999999; }
216 |
217 | .highlight .nb { color: #0086B3; }
218 |
219 | .highlight .nc { color: #445588; font-weight: bold; }
220 |
221 | .highlight .no { color: #008080; }
222 |
223 | .highlight .nd { color: #3c5d5d; font-weight: bold; }
224 |
225 | .highlight .ni { color: #800080; }
226 |
227 | .highlight .ne { color: #990000; font-weight: bold; }
228 |
229 | .highlight .nf { color: #990000; font-weight: bold; }
230 |
231 | .highlight .nl { color: #990000; font-weight: bold; }
232 |
233 | .highlight .nn { color: #555555; }
234 |
235 | .highlight .nt { color: #000080; }
236 |
237 | .highlight .vc { color: #008080; }
238 |
239 | .highlight .vg { color: #008080; }
240 |
241 | .highlight .vi { color: #008080; }
242 |
243 | .highlight .nv { color: #008080; }
244 |
245 | .highlight .ow { color: #000000; font-weight: bold; }
246 |
247 | .highlight .o { color: #000000; font-weight: bold; }
248 |
249 | .highlight .w { color: #bbbbbb; }
250 |
251 | .highlight { background-color: #f8f8f8; }
252 |
253 | /* LAYOUT STYLES */
254 | body { font-family: 'Helvetica Neue', Helvetica, Arial, serif; font-size: 15px; font-weight: 400; line-height: 1.5; color: #666; background: #fafafa url(../images/body-bg.jpg) 0 0 repeat; }
255 |
256 | p { margin-top: 0; }
257 |
258 | a { color: #2879d0; }
259 |
260 | a:hover { color: #2268b2; }
261 |
262 | header { padding-top: 40px; padding-bottom: 40px; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; background: #2e7bcf url(../images/header-bg.jpg) 0 0 repeat-x; border-bottom: solid 1px #275da1; }
263 |
264 | header h1 { width: 540px; margin-top: 0; margin-bottom: 0.2em; font-size: 72px; font-weight: normal; line-height: 1; color: #fff; letter-spacing: -1px; }
265 |
266 | header h2 { width: 540px; margin-top: 0; margin-bottom: 0; font-size: 26px; font-weight: normal; line-height: 1.3; color: #9ddcff; letter-spacing: 0; }
267 |
268 | .inner { position: relative; width: 940px; margin: 0 auto; }
269 |
270 | #content-wrapper { padding-top: 30px; border-top: solid 1px #fff; }
271 |
272 | #main-content { float: left; width: 690px; }
273 |
274 | #main-content img { max-width: 100%; }
275 |
276 | aside#sidebar { float: right; width: 200px; min-height: 504px; padding-left: 20px; font-size: 12px; line-height: 1.3; background: transparent url(../images/sidebar-bg.jpg) 0 0 no-repeat; }
277 |
278 | aside#sidebar p.repo-owner, aside#sidebar p.repo-owner a { font-weight: bold; }
279 |
280 | #downloads { margin-bottom: 40px; }
281 |
282 | a.button { width: 134px; height: 58px; padding-top: 22px; padding-left: 68px; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; font-size: 23px; line-height: 1.2; color: #fff; }
283 |
284 | a.button small { display: block; font-size: 11px; }
285 |
286 | header a.button { position: absolute; top: 0; right: 0; background: transparent url(../images/github-button.png) 0 0 no-repeat; }
287 |
288 | aside a.button { display: block; width: 138px; padding-left: 64px; margin-bottom: 20px; font-size: 21px; background: transparent url(../images/download-button.png) 0 0 no-repeat; }
289 |
290 | code, pre { margin-bottom: 30px; font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; font-size: 13px; color: #222; }
291 |
292 | code { padding: 0 3px; background-color: #f2f8fc; border: solid 1px #dbe7f3; }
293 |
294 | pre { padding: 20px; overflow: auto; text-shadow: none; background: #fff; border: solid 1px #f2f2f2; }
295 |
296 | pre code { padding: 0; color: #2879d0; background-color: #fff; border: none; }
297 |
298 | ul, ol, dl { margin-bottom: 20px; }
299 |
300 | /* COMMON STYLES */
301 | hr { height: 0; margin-top: 1em; margin-bottom: 1em; border: 0; border-top: solid 1px #ddd; }
302 |
303 | table { width: 100%; border: 1px solid #ebebeb; }
304 |
305 | th { font-weight: 500; }
306 |
307 | td { font-weight: 300; text-align: center; border: 1px solid #ebebeb; }
308 |
309 | form { padding: 20px; background: #f2f2f2; }
310 |
311 | /* GENERAL ELEMENT TYPE STYLES */
312 | #main-content h1 { margin-top: 0; margin-bottom: 0; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; font-size: 2.8em; font-weight: normal; color: #474747; text-indent: 6px; letter-spacing: -1px; }
313 |
314 | #main-content h1:before { padding-right: 0.3em; margin-left: -0.9em; color: #9ddcff; content: "/"; }
315 |
316 | #main-content h2 { margin-bottom: 8px; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; font-size: 22px; font-weight: bold; color: #474747; text-indent: 4px; }
317 |
318 | #main-content h2:before { padding-right: 0.3em; margin-left: -1.5em; content: "//"; color: #9ddcff; }
319 |
320 | #main-content h3 { margin-top: 24px; margin-bottom: 8px; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; font-size: 18px; font-weight: bold; color: #474747; text-indent: 3px; }
321 |
322 | #main-content h3:before { padding-right: 0.3em; margin-left: -2em; content: "///"; color: #9ddcff; }
323 |
324 | #main-content h4 { margin-bottom: 8px; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; font-size: 15px; font-weight: bold; color: #474747; text-indent: 3px; }
325 |
326 | h4:before { padding-right: 0.3em; margin-left: -2.8em; content: "////"; color: #9ddcff; }
327 |
328 | #main-content h5 { margin-bottom: 8px; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; font-size: 14px; color: #474747; text-indent: 3px; }
329 |
330 | h5:before { padding-right: 0.3em; margin-left: -3.2em; content: "/////"; color: #9ddcff; }
331 |
332 | #main-content h6 { margin-bottom: 8px; font-family: 'Architects Daughter', 'Helvetica Neue', Helvetica, Arial, serif; font-size: .8em; color: #474747; text-indent: 3px; }
333 |
334 | h6:before { padding-right: 0.3em; margin-left: -3.7em; content: "//////"; color: #9ddcff; }
335 |
336 | p { margin-bottom: 20px; }
337 |
338 | a { text-decoration: none; }
339 |
340 | p a { font-weight: 400; }
341 |
342 | blockquote { padding: 0 0 0 30px; margin-bottom: 20px; font-size: 15px; border-left: 10px solid #e9e9e9; }
343 |
344 | ul { list-style-position: inside; list-style: disc; padding-left: 20px; }
345 |
346 | ol { list-style-position: inside; list-style: decimal; padding-left: 3px; }
347 |
348 | dl dd { font-style: italic; font-weight: 100; }
349 |
350 | footer { padding-top: 20px; padding-bottom: 30px; margin-top: 40px; font-size: 13px; color: #aaa; background: transparent url("../images/hr.png") 0 0 no-repeat; }
351 |
352 | footer a { color: #666; }
353 |
354 | footer a:hover { color: #444; }
355 |
356 | /* MISC */
357 | .clearfix:after { display: block; height: 0; clear: both; visibility: hidden; content: '.'; }
358 |
359 | .clearfix { display: inline-block; }
360 |
361 | * html .clearfix { height: 1%; }
362 |
363 | .clearfix { display: block; }
364 |
365 | /* #Media Queries
366 | ================================================== */
367 | /* Smaller than standard 960 (devices and browsers) */
368 | /* Tablet Portrait size to standard 960 (devices and browsers) */
369 | @media only screen and (min-width: 768px) and (max-width: 959px) { .inner { width: 740px; }
370 | header h1, header h2 { width: 340px; }
371 | header h1 { font-size: 60px; }
372 | header h2 { font-size: 30px; }
373 | #main-content { width: 490px; }
374 | #main-content h1:before, #main-content h2:before, #main-content h3:before, #main-content h4:before, #main-content h5:before, #main-content h6:before { padding-right: 0; margin-left: 0; content: none; } }
375 | /* All Mobile Sizes (devices and browser) */
376 | @media only screen and (max-width: 767px) { .inner { width: 93%; }
377 | header { padding: 20px 0; }
378 | header .inner { position: relative; }
379 | header h1, header h2 { width: 100%; }
380 | header h1 { font-size: 48px; }
381 | header h2 { font-size: 24px; }
382 | header a.button { position: relative; display: inline-block; width: auto; height: auto; padding: 5px 10px; margin-top: 15px; font-size: 13px; line-height: 1; color: #2879d0; text-align: center; background-color: #9ddcff; background-image: none; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; }
383 | header a.button small { display: inline; font-size: 13px; }
384 | #main-content, aside#sidebar { float: none; width: 100% !important; }
385 | aside#sidebar { min-height: 0; padding: 20px 0; margin-top: 20px; background-image: none; border-top: solid 1px #ddd; }
386 | aside#sidebar a.button { display: none; }
387 | #main-content h1:before, #main-content h2:before, #main-content h3:before, #main-content h4:before, #main-content h5:before, #main-content h6:before { padding-right: 0; margin-left: 0; content: none; } }
388 | /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
389 | /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
390 |
--------------------------------------------------------------------------------
/githubdocs/formats.js:
--------------------------------------------------------------------------------
1 | /*
2 | ## Formats.js
3 |
4 | Copyright (c) 2014 bebbi (elghatta@gmail.com)
5 | Copyright (c) 2013 Eduard Bespalov (edwbes@gmail.com)
6 | Copyright (c) 2013 Rene K. Mueller (spiritdude@gmail.com)
7 | Copyright (c) 2012 Joost Nieuwenhuijse (joost@newhouse.nl)
8 | Copyright (c) 2011 Evan Wallace (http://evanw.github.com/csg.js/)
9 | Copyright (c) 2012 Alexandre Girard (https://github.com/alx)
10 |
11 | Exporting CSG into various formats:
12 | - AMF
13 | - X3D
14 | - STL (ASCII & Binary)
15 | Exporting CAG into various formats:
16 | - DXF
17 | - SVG
18 |
19 | License: MIT license
20 |
21 | */
22 |
23 | // import the required modules if necessary
24 |
25 | // if(typeof module !== 'undefined') { // used via nodejs
26 | // CSG = require(lib+'csg.js').CSG;
27 | // CAG = require(lib+'csg.js').CAG;
28 | // Blob = require(lib+'Blob.js').Blob;
29 | // }
30 |
31 | ////////////////////////////////////////////
32 | // X3D Export
33 | ////////////////////////////////////////////
34 |
35 | (function(module) {
36 |
37 | CSG.prototype.toX3D = function() {
38 | // materialPolygonLists
39 | // key: a color string (e.g. "0 1 1" for yellow)
40 | // value: an array of strings specifying polygons of this color
41 | // (as space-separated indices into vertexCoords)
42 | var materialPolygonLists = {},
43 | // list of coordinates (as "x y z" strings)
44 | vertexCoords = [],
45 | // map to look up the index in vertexCoords of a given vertex
46 | vertexTagToCoordIndexMap = {};
47 |
48 | this.polygons.map(function(p) {
49 | var red = 0,
50 | green = 0,
51 | blue = 1; // default color is blue
52 | if (p.shared && p.shared.color) {
53 | red = p.shared.color[0];
54 | green = p.shared.color[1];
55 | blue = p.shared.color[2];
56 | }
57 |
58 | var polygonVertexIndices = [],
59 | numvertices = p.vertices.length,
60 | vertex;
61 | for (var i = 0; i < numvertices; i++) {
62 | vertex = p.vertices[i];
63 | if (!(vertex.getTag() in vertexTagToCoordIndexMap)) {
64 | vertexCoords.push(vertex.pos._x.toString() + " " +
65 | vertex.pos._y.toString() + " " +
66 | vertex.pos._z.toString()
67 | );
68 | vertexTagToCoordIndexMap[vertex.getTag()] = vertexCoords.length - 1;
69 | }
70 | polygonVertexIndices.push(vertexTagToCoordIndexMap[vertex.getTag()]);
71 | }
72 |
73 | var polygonString = polygonVertexIndices.join(" ");
74 |
75 | var colorString = red.toString() + " " + green.toString() + " " + blue.toString();
76 | if (!(colorString in materialPolygonLists)) {
77 | materialPolygonLists[colorString] = [];
78 | }
79 | // add this polygonString to the list of colorString-colored polygons
80 | materialPolygonLists[colorString].push(polygonString);
81 | });
82 |
83 |
84 | // create output document
85 | var docType = document.implementation.createDocumentType("X3D",
86 | "ISO//Web3D//DTD X3D 3.1//EN","http://www.web3d.org/specifications/x3d-3.1.dtd");
87 | var exportDoc = document.implementation.createDocument(null, "X3D", docType);
88 | exportDoc.insertBefore(
89 | exportDoc.createProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"'),
90 | exportDoc.doctype);
91 |
92 | var exportRoot = exportDoc.getElementsByTagName("X3D")[0];
93 | exportRoot.setAttribute("profile", "Interchange");
94 | exportRoot.setAttribute("version", "3.1");
95 | exportRoot.setAttribute("xsd:noNamespaceSchemaLocation", "http://www.web3d.org/specifications/x3d-3.1.xsd");
96 | exportRoot.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema-instance");
97 |
98 | var exportScene = exportDoc.createElement("Scene");
99 | exportRoot.appendChild(exportScene);
100 |
101 | /*
102 | For each color, create a shape made of an appropriately colored
103 | material which contains all polygons that are this color.
104 |
105 | The first shape will contain the definition of all vertices,
106 | ( ), which will be referenced by
107 | subsequent shapes.
108 | */
109 | var coordsMeshDefined = false;
110 | for (var colorString in materialPolygonLists) {
111 | var polygonList = materialPolygonLists[colorString];
112 | var shape = exportDoc.createElement("Shape");
113 | exportScene.appendChild(shape);
114 |
115 | var appearance = exportDoc.createElement("Appearance");
116 | shape.appendChild(appearance);
117 |
118 | var material = exportDoc.createElement("Material");
119 | appearance.appendChild(material);
120 | material.setAttribute("diffuseColor", colorString);
121 | material.setAttribute("ambientIntensity", "1.0");
122 |
123 | var ifs = exportDoc.createElement("IndexedFaceSet");
124 | shape.appendChild(ifs);
125 | ifs.setAttribute("solid", "true");
126 | ifs.setAttribute("coordIndex", polygonList.join(" -1 ") + " -1");
127 |
128 | var coordinate = exportDoc.createElement("Coordinate");
129 | ifs.appendChild(coordinate);
130 | if (coordsMeshDefined) {
131 | coordinate.setAttribute("USE", "coords_mesh");
132 | } else {
133 | coordinate.setAttribute("DEF", "coords_mesh");
134 | coordinate.setAttribute("point", vertexCoords.join(" "));
135 | coordsMeshDefined = true;
136 | }
137 | }
138 |
139 | var x3dstring = (new XMLSerializer()).serializeToString(exportDoc);
140 | return new Blob([x3dstring], {
141 | type: "model/x3d+xml"
142 | });
143 | };
144 |
145 | ////////////////////////////////////////////
146 | // STL Binary Export
147 | ////////////////////////////////////////////
148 |
149 | // see http://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL
150 | CSG.prototype.toStlBinary = function() {
151 | // first check if the host is little-endian:
152 | var buffer = new ArrayBuffer(4);
153 | var int32buffer = new Int32Array(buffer, 0, 1);
154 | var int8buffer = new Int8Array(buffer, 0, 4);
155 | int32buffer[0] = 0x11223344;
156 | if (int8buffer[0] != 0x44) {
157 | throw new Error("Binary STL output is currently only supported on little-endian (Intel) processors");
158 | }
159 |
160 | var numtriangles = 0;
161 | this.polygons.map(function(p) {
162 | var numvertices = p.vertices.length;
163 | var thisnumtriangles = (numvertices >= 3) ? numvertices - 2 : 0;
164 | numtriangles += thisnumtriangles;
165 | });
166 | var headerarray = new Uint8Array(80);
167 | for (var i = 0; i < 80; i++) {
168 | headerarray[i] = 65;
169 | }
170 | var ar1 = new Uint32Array(1);
171 | ar1[0] = numtriangles;
172 | // write the triangles to allTrianglesBuffer:
173 | var allTrianglesBuffer = new ArrayBuffer(50 * numtriangles);
174 | var allTrianglesBufferAsInt8 = new Int8Array(allTrianglesBuffer);
175 | // a tricky problem is that a Float32Array must be aligned at 4-byte boundaries (at least in certain browsers)
176 | // while each triangle takes 50 bytes. Therefore we write each triangle to a temporary buffer, and copy that
177 | // into allTrianglesBuffer:
178 | var triangleBuffer = new ArrayBuffer(50);
179 | var triangleBufferAsInt8 = new Int8Array(triangleBuffer);
180 | // each triangle consists of 12 floats:
181 | var triangleFloat32array = new Float32Array(triangleBuffer, 0, 12);
182 | // and one uint16:
183 | var triangleUint16array = new Uint16Array(triangleBuffer, 48, 1);
184 | var byteoffset = 0;
185 | this.polygons.map(function(p) {
186 | var numvertices = p.vertices.length;
187 | for (var i = 0; i < numvertices - 2; i++) {
188 | var normal = p.plane.normal;
189 | triangleFloat32array[0] = normal._x;
190 | triangleFloat32array[1] = normal._y;
191 | triangleFloat32array[2] = normal._z;
192 | var arindex = 3;
193 | for (var v = 0; v < 3; v++) {
194 | var vv = v + ((v > 0) ? i : 0);
195 | var vertexpos = p.vertices[vv].pos;
196 | triangleFloat32array[arindex++] = vertexpos._x;
197 | triangleFloat32array[arindex++] = vertexpos._y;
198 | triangleFloat32array[arindex++] = vertexpos._z;
199 | }
200 | triangleUint16array[0] = 0;
201 | // copy the triangle into allTrianglesBuffer:
202 | allTrianglesBufferAsInt8.set(triangleBufferAsInt8, byteoffset);
203 | byteoffset += 50;
204 | }
205 | });
206 | return new Blob([headerarray.buffer, ar1.buffer, allTrianglesBuffer], {
207 | type: "application/sla"
208 | });
209 | };
210 |
211 | ////////////////////////////////////////////
212 | // STL String Export
213 | ////////////////////////////////////////////
214 |
215 | CSG.prototype.toStlString = function() {
216 | var result = "solid csg.js\n";
217 | this.polygons.map(function(p) {
218 | result += p.toStlString();
219 | });
220 | result += "endsolid csg.js\n";
221 | return new Blob([result], {
222 | type: "application/sla"
223 | });
224 | };
225 |
226 | CSG.Vector3D.prototype.toStlString = function() {
227 | return this._x + " " + this._y + " " + this._z;
228 | };
229 |
230 | CSG.Vertex.prototype.toStlString = function() {
231 | return "vertex " + this.pos.toStlString() + "\n";
232 | };
233 |
234 | CSG.Polygon.prototype.toStlString = function() {
235 | var result = "";
236 | if (this.vertices.length >= 3) // should be!
237 | {
238 | // STL requires triangular polygons. If our polygon has more vertices, create
239 | // multiple triangles:
240 | var firstVertexStl = this.vertices[0].toStlString();
241 | for (var i = 0; i < this.vertices.length - 2; i++) {
242 | result += "facet normal " + this.plane.normal.toStlString() + "\nouter loop\n";
243 | result += firstVertexStl;
244 | result += this.vertices[i + 1].toStlString();
245 | result += this.vertices[i + 2].toStlString();
246 | result += "endloop\nendfacet\n";
247 | }
248 | }
249 | return result;
250 | };
251 |
252 | ////////////////////////////////////////////
253 | // DXF Export
254 | ////////////////////////////////////////////
255 |
256 | CAG.PathsToDxf = function(paths) {
257 | var str = "999\nDXF generated by OpenJsCad\n";
258 | str += " 0\nSECTION\n 2\nHEADER\n";
259 | str += " 0\nENDSEC\n";
260 | str += " 0\nSECTION\n 2\nTABLES\n";
261 | str += " 0\nTABLE\n 2\nLTYPE\n 70\n1\n";
262 | str += " 0\nLTYPE\n 2\nCONTINUOUS\n 3\nSolid Line\n 72\n65\n 73\n0\n 40\n0.0\n";
263 | str += " 0\nENDTAB\n";
264 | str += " 0\nTABLE\n 2\nLAYER\n 70\n1\n";
265 | str += " 0\nLAYER\n 2\nOpenJsCad\n 62\n7\n 6\ncontinuous\n";
266 | str += " 0\nENDTAB\n";
267 | str += " 0\nTABLE\n 2\nSTYLE\n 70\n0\n 0\nENDTAB\n";
268 | str += " 0\nTABLE\n 2\nVIEW\n 70\n0\n 0\nENDTAB\n";
269 | str += " 0\nENDSEC\n";
270 | str += " 0\nSECTION\n 2\nBLOCKS\n";
271 | str += " 0\nENDSEC\n";
272 | str += " 0\nSECTION\n 2\nENTITIES\n";
273 | paths.map(function(path) {
274 | var numpoints_closed = path.points.length + (path.closed ? 1 : 0);
275 | str += " 0\nLWPOLYLINE\n 8\nOpenJsCad\n 90\n" + numpoints_closed + "\n 70\n" + (path.closed ? 1 : 0) + "\n";
276 | for (var pointindex = 0; pointindex < numpoints_closed; pointindex++) {
277 | var pointindexwrapped = pointindex;
278 | if (pointindexwrapped >= path.points.length) pointindexwrapped -= path.points.length;
279 | var point = path.points[pointindexwrapped];
280 | str += " 10\n" + point.x + "\n 20\n" + point.y + "\n 30\n0.0\n";
281 | }
282 | });
283 | str += " 0\nENDSEC\n 0\nEOF\n";
284 | return new Blob([str], {
285 | type: "application/dxf"
286 | });
287 | };
288 |
289 | CAG.prototype.toDxf = function() {
290 | var paths = this.getOutlinePaths();
291 | return CAG.PathsToDxf(paths);
292 | };
293 |
294 | ////////////////////////////////////////////
295 | // AMF Export
296 | ////////////////////////////////////////////
297 |
298 | CSG.prototype.toAMFString = function(m) {
299 | var result = "\n\n";
300 | for(var k in m) {
301 | result += ""+m[k]+" \n";
302 | }
303 | result += "\n\n\n";
304 |
305 | this.polygons.map(function(p) { // first we dump all vertices of all polygons
306 | for(var i=0; i\n";
311 |
312 | var n = 0;
313 | this.polygons.map(function(p) { // then we dump all polygons
314 | result += "\n";
315 | if(p.vertices.length<3)
316 | return;
317 | var color = null;
318 | if(p.shared && p.shared.color) {
319 | color = p.shared.color;
320 | } else if(p.color) {
321 | color = p.color;
322 | }
323 | if (color != null) {
324 | if(color.length < 4) color.push(1.);
325 | result += ""+color[0]+" "+color[1]+" "+color[2]+" "+color[3]+" ";
326 | }
327 |
328 | for(var i=0; i";
330 | result += "" + (n) + " ";
331 | result += "" + (n+i+1) + " ";
332 | result += "" + (n+i+2) + " ";
333 | result += "\n";
334 | }
335 | n += p.vertices.length;
336 | result += " \n";
337 | });
338 | result += " \n \n";
339 | result += " \n";
340 | return new Blob([result], {
341 | type: "application/amf+xml"
342 | });
343 | };
344 |
345 | CSG.Vector3D.prototype.toAMFString = function() {
346 | return "" + this._x + " " + this._y + " " + this._z + " ";
347 | };
348 |
349 | CSG.Vertex.prototype.toAMFString = function() {
350 | return "" + this.pos.toAMFString() + " \n";
351 | };
352 |
353 |
354 | ////////////////////////////////////////////
355 | // JSON Conversions
356 | ////////////////////////////////////////////
357 |
358 | CSG.prototype.toJSON = function() {
359 | var str = '{ "type": "csg","polygons": [';
360 | var comma = '';
361 | this.polygons.map(
362 | function(polygon) {
363 | str += comma;
364 | str += JSON.stringify(polygon);
365 | comma = ',';
366 | }
367 | );
368 | str += '],';
369 | str += '"isCanonicalized": ' + JSON.stringify(this.isCanonicalized)+',';
370 | str += '"isRetesselated": '+JSON.stringify(this.isRetesselated);
371 | str += '}';
372 | return new Blob([str], {
373 | type: "application/json"
374 | });
375 | };
376 |
377 | // convert the given (anonymous JSON) object into CSG
378 | // Note: Any issues during conversion will result in exceptions
379 | CSG.prototype.fromJSON = function(o) {
380 | // verify the object IS convertable
381 | if (o.type == 'csg') {
382 | Object.setPrototypeOf(o, CSG.prototype);
383 | o.polygons.map( function(p) {
384 | Object.setPrototypeOf(p, CSG.Polygon.prototype);
385 | p.vertices.map(function(v) {
386 | Object.setPrototypeOf(v, CSG.Vertex.prototype);
387 | Object.setPrototypeOf(v.pos, CSG.Vector3D.prototype);
388 | });
389 | Object.setPrototypeOf(p.shared, CSG.Polygon.Shared.prototype);
390 | Object.setPrototypeOf(p.plane, CSG.Plane.prototype);
391 | Object.setPrototypeOf(p.plane.normal, CSG.Vector3D.prototype);
392 | });
393 | o.properties = new CSG.Properties();
394 | }
395 | return o;
396 | };
397 |
398 | CAG.prototype.toJSON = function() {
399 | var str = '{ "type": "cag","sides": [';
400 | var comma = '';
401 | this.sides.map(
402 | function(side) {
403 | str += comma;
404 | str += JSON.stringify(side);
405 | comma = ',';
406 | }
407 | );
408 | str += '] }';
409 | return new Blob([str], {
410 | type: "application/json"
411 | });
412 | };
413 |
414 | // convert the given (anonymous JSON) object into CAG
415 | // Note: Any issues during conversion will result in exceptions
416 | CAG.prototype.fromJSON = function(o) {
417 | // verify the object IS convertable
418 | if (o.type == 'cag') {
419 | Object.setPrototypeOf(o, CAG.prototype);
420 | o.sides.map( function(side) {
421 | Object.setPrototypeOf(side, CAG.Side.prototype);
422 | Object.setPrototypeOf(side.vertex0, CAG.Vertex.prototype);
423 | Object.setPrototypeOf(side.vertex1, CAG.Vertex.prototype);
424 | Object.setPrototypeOf(side.vertex0.pos, CSG.Vector2D.prototype);
425 | Object.setPrototypeOf(side.vertex1.pos, CSG.Vector2D.prototype);
426 | }
427 | );
428 | }
429 | return o;
430 | };
431 |
432 | ////////////////////////////////////////////
433 | // SVG Export
434 | ////////////////////////////////////////////
435 |
436 | CAG.PathsToSvg = function(paths,bounds) {
437 | // calculate offsets in order to create paths orientated from the 0,0 axis
438 | var xoffset = 0 - bounds[0].x;
439 | var yoffset = 0 - bounds[0].y;
440 | var str = '\n';
441 | paths.map(function(path) {
442 | str += ' \n';
456 | });
457 | str += ' \n';
458 | return str;
459 | };
460 |
461 | CAG.prototype.toSvg = function() {
462 | var decimals = 1000;
463 |
464 | // mirror the CAG about the X axis in order to generate paths into the POSITIVE direction
465 | var plane = new CSG.Plane(CSG.Vector3D.Create(0, 1, 0), 0);
466 | var cag = this.transform(CSG.Matrix4x4.mirroring(plane));
467 |
468 | var bounds = cag.getBounds();
469 | var paths = cag.getOutlinePaths();
470 | var width = Math.round((bounds[1].x - bounds[0].x)*decimals)/decimals;
471 | var height = Math.round((bounds[1].y - bounds[0].y)*decimals)/decimals;
472 | var svg = '\n';
473 | svg += '\n';
474 | svg += '\n';
475 | svg += '\n';
476 | svg += CAG.PathsToSvg(paths,bounds);
477 | svg += ' ';
478 | return new Blob([svg], {
479 | type: "image/svg+xml"
480 | });
481 | };
482 |
483 | // re-export CSG and CAG with the extended prototypes
484 | module.CSG = CSG;
485 | module.CAG = CAG;
486 | })(this);
487 |
488 |
--------------------------------------------------------------------------------
/docs/.vuepress/dist/assets/css/0.styles.617c345f.css:
--------------------------------------------------------------------------------
1 | #nprogress{pointer-events:none}#nprogress .bar{background:#3eaf7c;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #3eaf7c,0 0 5px #3eaf7c;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#3eaf7c transparent transparent #3eaf7c;border-style:solid;border-width:2px;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.home{padding:3.6rem 2rem 0;max-width:960px;margin:0 auto;display:block}.home .hero{text-align:center}.home .hero img{max-width:100%;max-height:280px;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.8rem auto}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:#6a8bad}.home .hero .action-button{display:inline-block;font-size:1.2rem;color:#fff;background-color:#3eaf7c;padding:.8rem 1.6rem;border-radius:4px;transition:background-color .1s ease;box-sizing:border-box;border-bottom:1px solid #389d70}.home .hero .action-button:hover{background-color:#4abf8a}.home .features{border-top:1px solid #eaecef;padding:1.2rem 0;margin-top:2.5rem;display:flex;flex-wrap:wrap;align-items:flex-start;align-content:stretch;justify-content:space-between}.home .feature{flex-grow:1;flex-basis:30%;max-width:30%}.home .feature h2{font-size:1.4rem;font-weight:500;border-bottom:none;padding-bottom:0;color:#3a5169}.home .feature p{color:#4e6e8e}.home .footer{padding:2.5rem;border-top:1px solid #eaecef;text-align:center;color:#4e6e8e}@media (max-width:719px){.home .features{flex-direction:column}.home .feature{max-width:100%;padding:0 2.5rem}}@media (max-width:419px){.home{padding-left:1.5rem;padding-right:1.5rem}.home .hero img{max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:#4e6e8e;display:inline-block;border:1px solid #cfd4db;border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all .2s ease;background:#fff url(/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#3eaf7c}.search-box .suggestions{background:#fff;width:20rem;position:absolute;top:1.5rem;border:1px solid #cfd4db;border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:#5d82a6}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused{background-color:#f3f4f5}.search-box .suggestion.focused a{color:#3eaf7c}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:1rem}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (max-width:719px){.sidebar-button{display:block}}.dropdown-enter,.dropdown-leave-to{height:0!important}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title{display:block}.dropdown-wrapper .dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .nav-dropdown .dropdown-item{color:inherit;line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid #eee;padding:.45rem 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{color:#3eaf7c}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #3eaf7c;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper .dropdown-title .arrow{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #ccc;border-bottom:0}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:#fff;padding:.6rem 0;border:1px solid;border-color:#ddd #ddd #ccc;text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links a.router-link-active,.nav-links a:hover{color:#3eaf7c}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}}@media (min-width:719px){.nav-links a.router-link-active,.nav-links a:hover{color:#2c3e50}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px;border-bottom:2px solid #46bd87}}.navbar{padding:.7rem 1.5rem;line-height:2.2rem}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:2.2rem;min-width:2.2rem;margin-right:.8rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:#2c3e50;position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;background-color:#fff;white-space:nowrap;font-size:.9rem;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}@media (max-width:719px){.navbar{padding-left:4rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem}}.page-edit,.page-nav{max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.page-edit,.page-nav{padding:2rem}}@media (max-width:419px){.page-edit,.page-nav{padding:1.5rem}}.page{padding-bottom:2rem;display:block}.page-edit{padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block}.page-edit .edit-link a{color:#4e6e8e;margin-right:.25rem}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:#4e6e8e}.page-edit .last-updated .time{font-weight:400;color:#aaa}.page-nav{padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid #eaecef;padding-top:1rem;overflow:auto}.page-nav .next{float:right}@media (max-width:719px){.page-edit .edit-link{margin-bottom:.5rem}.page-edit .last-updated{font-size:.8em;float:none;text-align:left}}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:.95em;line-height:1.4;font-weight:400;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-heading:not(.clickable){opacity:.5}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.95em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:#2c3e50;transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em}.sidebar-heading.clickable.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-heading.clickable:hover{color:#3eaf7c}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:#2c3e50;border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link:hover{color:#3eaf7c}a.sidebar-link.active{font-weight:600;color:#3eaf7c;border-left-color:#3eaf7c}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid #eaecef;padding:.5rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}@media (max-width:719px){.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}}code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.theme-default-content code{color:#476582;padding:.25rem .5rem;margin:0;font-size:.85em;background-color:rgba(27,31,35,.05);border-radius:3px}.theme-default-content code .token.deleted{color:#ec5975}.theme-default-content code .token.inserted{color:#3eaf7c}.theme-default-content pre,.theme-default-content pre[class*=language-]{line-height:1.4;padding:1.25rem 1.5rem;margin:.85rem 0;background-color:#282c34;border-radius:6px;overflow:auto}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#fff;padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:#282c34;border-radius:6px}div[class*=language-] .highlight-lines{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:hsla(0,0%,100%,.4)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:3.5rem;height:100%;background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode pre{padding-left:4.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:3.5rem;text-align:center;color:hsla(0,0%,100%,.3);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number,div[class*=language-].line-numbers-mode .line-numbers-wrapper br{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:3.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid rgba(0,0,0,.66);background-color:#282c34}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:-.4rem}.custom-block.danger,.custom-block.tip,.custom-block.warning{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983}.custom-block.warning{background-color:rgba(255,229,100,.3);border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:#2c3e50}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:#2c3e50}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-default-content:not(.custom){max-width:740px;margin:0 auto;padding:2rem 2.5rem}@media (max-width:959px){.theme-default-content:not(.custom){padding:2rem}}@media (max-width:419px){.theme-default-content:not(.custom){padding:1.5rem}}.table-of-contents .badge{vertical-align:middle}body,html{padding:0;margin:0;background-color:#fff}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;color:#2c3e50}.page{padding-left:20rem}.navbar{z-index:20;right:0;height:3.6rem;background-color:#fff;box-sizing:border-box;border-bottom:1px solid #eaecef}.navbar,.sidebar-mask{position:fixed;top:0;left:0}.sidebar-mask{z-index:9;width:100vw;height:100vh;display:none}.sidebar{font-size:16px;background-color:#fff;width:20rem;position:fixed;z-index:10;margin:0;top:3.6rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid #eaecef;overflow-y:auto}.theme-default-content:not(.custom)>:first-child{margin-top:3.6rem}.theme-default-content:not(.custom) a:hover{text-decoration:underline}.theme-default-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-default-content:not(.custom) img{max-width:100%}.theme-default-content.custom{padding:0;margin:0}.theme-default-content.custom img{max-width:100%}a{font-weight:500;text-decoration:none}a,p a code{color:#3eaf7c}p a code{font-weight:400}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;color:#999;border-left:.2rem solid #dfe2e5;margin:1rem 0;padding:.25rem 0 .25rem 1rem}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-default-content:not(.custom)>h1,.theme-default-content:not(.custom)>h2,.theme-default-content:not(.custom)>h3,.theme-default-content:not(.custom)>h4,.theme-default-content:not(.custom)>h5,.theme-default-content:not(.custom)>h6{margin-top:-3.1rem;padding-top:4.6rem;margin-bottom:0}.theme-default-content:not(.custom)>h1:first-child,.theme-default-content:not(.custom)>h2:first-child,.theme-default-content:not(.custom)>h3:first-child,.theme-default-content:not(.custom)>h4:first-child,.theme-default-content:not(.custom)>h5:first-child,.theme-default-content:not(.custom)>h6:first-child{margin-top:-1.5rem;margin-bottom:1rem}.theme-default-content:not(.custom)>h1:first-child+.custom-block,.theme-default-content:not(.custom)>h1:first-child+p,.theme-default-content:not(.custom)>h1:first-child+pre,.theme-default-content:not(.custom)>h2:first-child+.custom-block,.theme-default-content:not(.custom)>h2:first-child+p,.theme-default-content:not(.custom)>h2:first-child+pre,.theme-default-content:not(.custom)>h3:first-child+.custom-block,.theme-default-content:not(.custom)>h3:first-child+p,.theme-default-content:not(.custom)>h3:first-child+pre,.theme-default-content:not(.custom)>h4:first-child+.custom-block,.theme-default-content:not(.custom)>h4:first-child+p,.theme-default-content:not(.custom)>h4:first-child+pre,.theme-default-content:not(.custom)>h5:first-child+.custom-block,.theme-default-content:not(.custom)>h5:first-child+p,.theme-default-content:not(.custom)>h5:first-child+pre,.theme-default-content:not(.custom)>h6:first-child+.custom-block,.theme-default-content:not(.custom)>h6:first-child+p,.theme-default-content:not(.custom)>h6:first-child+pre{margin-top:2rem}h1:hover .header-anchor,h2:hover .header-anchor,h3:hover .header-anchor,h4:hover .header-anchor,h5:hover .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid #eaecef}h3{font-size:1.35rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0}a.header-anchor:hover{text-decoration:none}.line-number,code,kbd{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid #eaecef}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}.theme-container.sidebar-open .sidebar-mask{display:block}.theme-container.no-navbar .theme-default-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}@media (min-width:720px){.theme-container.no-sidebar .sidebar{display:none}.theme-container.no-sidebar .page{padding-left:0}}@media (max-width:959px){.sidebar{font-size:15px;width:16.4rem}.page{padding-left:16.4rem}}@media (max-width:719px){.sidebar{top:0;padding-top:3.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-default-content div[class*=language-]{margin:.85rem -1.5rem;border-radius:0}}.badge[data-v-c13ee5b0]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-c13ee5b0],.badge.tip[data-v-c13ee5b0],.badge[data-v-c13ee5b0]{background-color:#42b983}.badge.error[data-v-c13ee5b0]{background-color:#da5961}.badge.warn[data-v-c13ee5b0],.badge.warning[data-v-c13ee5b0],.badge.yellow[data-v-c13ee5b0]{background-color:#e7c000}.badge+.badge[data-v-c13ee5b0]{margin-left:5px}
--------------------------------------------------------------------------------