Compare commits
102 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d6297f575 | |||
| a27f2f36e6 | |||
| 339fbc98cf | |||
|
|
19de89dc6e | ||
|
|
2b8a238f8a | ||
|
|
ed0c201894 | ||
|
|
703015dc51 | ||
|
|
f0e339966f | ||
|
|
263bd8ebbf | ||
|
|
1c3960aaff | ||
|
|
4bce68dfbb | ||
|
|
dbe5bca1a9 | ||
|
|
0c9d05e270 | ||
|
|
8ef5bad891 | ||
|
|
1a8dd314e4 | ||
|
|
cc8892364c | ||
|
|
2429384b51 | ||
|
|
1a10d1e5bc | ||
|
|
41381ed376 | ||
|
|
08f17a4e1f | ||
|
|
4766e3eca6 | ||
|
|
19cdb2d9ae | ||
|
|
75cfa2a856 | ||
|
|
feb9ec6a71 | ||
|
|
4ba88df064 | ||
|
|
315bc83039 | ||
|
|
077de5ac87 | ||
|
|
aad8ddc558 | ||
|
|
5ccd4b7f8d | ||
|
|
e35d5d354a | ||
|
|
47f17efcf1 | ||
|
|
d3001e7da0 | ||
|
|
378af54056 | ||
|
|
397a3b84fc | ||
|
|
2c85ea5c07 | ||
|
|
6e5955ed8c | ||
|
|
065787ee99 | ||
|
|
6f1ae47011 | ||
|
|
db30aa2066 | ||
|
|
9b52a91db9 | ||
|
|
4ad1814d02 | ||
|
|
2a71b0618b | ||
|
|
3675509456 | ||
|
|
b36bf13b3e | ||
|
|
0d807f3b14 | ||
|
|
e8ce3f5c5e | ||
|
|
75ec333e1f | ||
|
|
f7b5f382fa | ||
|
|
cc336c0c41 | ||
|
|
8fb65aca70 | ||
|
|
38bfbfa61c | ||
|
|
2d03e5dd4b | ||
|
|
7ee9e61412 | ||
|
|
665698771f | ||
|
|
f63de1caf2 | ||
|
|
c6bae9460c | ||
|
|
3fb34bc663 | ||
|
|
ed2ed9c2c7 | ||
|
|
57da045abb | ||
|
|
3ef9857bc1 | ||
|
|
9c10403421 | ||
|
|
1dbd31d697 | ||
|
|
1f1f6a62d2 | ||
|
|
fdce624cb1 | ||
|
|
762e45ba3d | ||
|
|
d7ea2bf7cc | ||
|
|
3fca4e26ca | ||
|
|
cdf75654a6 | ||
|
|
e7b92cf52b | ||
|
|
29f5cd2468 | ||
|
|
d3c26dfaca | ||
|
|
13520c54e3 | ||
|
|
3047614d95 | ||
|
|
8d69ec6c21 | ||
|
|
024eb8a7d4 | ||
|
|
a3f1d605c6 | ||
|
|
12c228fbdf | ||
|
|
33794d3ea9 | ||
|
|
961e940f26 | ||
|
|
f2f080a51b | ||
|
|
dfbd88e065 | ||
|
|
b73b9346a4 | ||
|
|
2972f7f322 | ||
|
|
d4aa75fc14 | ||
|
|
55d196448c | ||
|
|
92c1856712 | ||
|
|
78a69feff1 | ||
|
|
8a7a302ac8 | ||
|
|
e6dd35fca0 | ||
|
|
24c80cb735 | ||
|
|
e29bb46dfa | ||
|
|
57fbf6044d | ||
|
|
2eed004407 | ||
|
|
8b4b9ae687 | ||
|
|
c7168eae68 | ||
|
|
c1bbaed9a2 | ||
|
|
c81889b298 | ||
|
|
0a246489ec | ||
|
|
654874fb5f | ||
|
|
a523c45f4a | ||
|
|
b29a5f3c5f | ||
|
|
a61411258b |
49 changed files with 3967 additions and 1657 deletions
16
CHANGELOG.md
Normal file
16
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
CHANGELOG:
|
||||
V2.0.0:
|
||||
* added $fa values for minkowski and shape - so you can customize how much rounding there is
|
||||
* rejiggered `key.scad` pipeline for more clarity and less shapes
|
||||
* implemented "3d_surface" dish - still in beta
|
||||
* super cool though, you can even change the distribution of points on the surface! just make sure you use monotonically increasing functions
|
||||
* created "hull" folder to house different ways of creating the overall key shape
|
||||
* promoted "feature" folder to first-class folder with keytext and switch clearance as new residents
|
||||
* wrote this changelog!
|
||||
* implemented `$inner_shape_type`, use "flat" for less geometry or "disable" to make a completely solid key easily. didn't help render rounded keys though
|
||||
* side-printed keycaps are first class! you can use the `sideways()` modifier to set up sideways keycaps that have flat sides to print on.
|
||||
* it's much easier to make quick artisans now that the inside of the keycap is differenced from any additive features placed on top
|
||||
* `$linear_extrude_shape` and `$skin_extrude_shape` retired in favor of `$hull_shape_type`
|
||||
* added regular_polygon shape and octagonal and hexagonal key profiles
|
||||
* added beta kailh choc
|
||||
* Finally got ISO Enter working correctly!
|
||||
30
README.md
30
README.md
|
|
@ -9,6 +9,14 @@ Relevant links:
|
|||
* Shapeways: https://www.shapeways.com/designer/rsheldiii/creations
|
||||
* Buy me a coffee: https://ko-fi.com/rsheldiii, but only if you want to!
|
||||
|
||||
# V2.0.0 Cutover
|
||||
|
||||
As of February 19th, 2022, the v2.0.0 branch has been merged into master.
|
||||
|
||||
This branch completely rewrote key.scad to be much simpler and faster. If you're just starting out, please use master and report any bugs you find.
|
||||
|
||||
If you branched off this repo previously, merging to master will probably break any additions you've made. If you need the prior version of the code for whatever reason, v1.1.0 is master just before the v2.0.0 merge. I will be backporting bugfixes to the v1 branch, so if you see v1.1.1 or higher, use that instead.
|
||||
|
||||
## How to run
|
||||
|
||||
#### OpenSCAD Proper (recommended way)
|
||||
|
|
@ -17,7 +25,19 @@ If you are technically inclined at all, this is definitely the best way to run t
|
|||
|
||||
First, you'll need OpenSCAD: http://www.openscad.org/downloads.html. I highly recommend installing the development snapshot, as they generally support more features and are relatively stable. Development snapshots are listed in their own section on the downloads page.
|
||||
|
||||
After you have openSCAD installed, you need to download the code and run it. running `git clone https://github.com/rsheldiii/KeyV2.git` if you have git, or downloading [this zip](https://github.com/rsheldiii/KeyV2/archive/master.zip) and extracting the directory should do it. Then all you need to do is open `keys.scad` with openSCAD and you are set! It is possible to edit this project with an external editor by checking off Design => 'Automatic Reload and Preview' in OpenSCAD.
|
||||
After you have openSCAD installed, you need to download the code and run it. running `git clone https://github.com/rsheldiii/openSCAD-projects.git` if you have git, or downloading [this zip](https://github.com/rsheldiii/openSCAD-projects/archive/master.zip) and extracting the directory should do it.
|
||||
|
||||
To make your own key, all you need to do is open `keys.scad` with openSCAD and modify this line:
|
||||
|
||||
```
|
||||
dcs_row(5) legend("⇪", size=9) key();
|
||||
```
|
||||
|
||||
To be whatever you want. For example, this is for a ctrl key on an OEM keyboard:
|
||||
|
||||
```u(1.25) oem_row(3) legend("ctrl", size=4.5) key();```
|
||||
|
||||
It is possible to edit this project with an external editor by checking off Design => 'Automatic Reload and Preview' in OpenSCAD.
|
||||
|
||||
All examples below assume you are running the library on your computer with OpenSCAD.
|
||||
|
||||
|
|
@ -70,7 +90,7 @@ These modifier functions may not cover every use case; in that case, you may hav
|
|||
|
||||
new to the library and still in a beta state, layouts allows you to generate an entire layout for a keyboard!
|
||||
|
||||
It is recommended to use tined stem support and set `$extra_long_stem_support = true` if you plan on printing these keycaps.
|
||||
It is recommended to print layouts with a brim that extends to the next key.
|
||||
|
||||
```
|
||||
60_percent_default("dcs") key();
|
||||
|
|
@ -169,7 +189,7 @@ Prints from this library are still challenging, despite all efforts to the contr
|
|||
|
||||
1. If your stem isn't fitting in the switch, try upping the slop factor, accessed by giving your keystem function a numeric value (eg `cherry(0.5) key()`). This will lengthen the cross and decrease the overall size of the keystem. The default value is 0.3, and represents millimeters. Note that even if you have a resin printer, you should probably keep the default value; keys printed with 0 slop will barely fit on the stem.
|
||||
|
||||
2. If your keystem breaks off the bed mid-print, you can enable a brim by adding the `brimmed()` modifier. This will give a solid base for the keystem to anchor into.
|
||||
2. If your keystem breaks off the bed mid-print, you can enable a brim by adding the `brimmed_stem_support()` modifier. This will give a solid base for the keystem to anchor into.
|
||||
|
||||
3. If you are unsatisfied with the quality of the top surface, you can try printing the keycap on a different surface than the bottom, though it may impact the quality of the stem.
|
||||
|
||||
|
|
@ -178,9 +198,7 @@ Prints from this library are still challenging, despite all efforts to the contr
|
|||
That's it, if you have any questions feel free to open an issue or leave a comment on thingiverse!
|
||||
|
||||
## TODO:
|
||||
* replace linear_extrude_shape_hull with skin_extrude_shape_hull or something, to enable concave extrusions
|
||||
* replace current ISO enter shape with one that works for `skin()`
|
||||
* generate dishes via math?
|
||||
moved to [TODO doc](./TODO.md)
|
||||
|
||||
## Contributions welcome
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ At the end of the day though, all the columnular sculpting is doing is adding ex
|
|||
|
||||
## skin mode
|
||||
|
||||
SA, HiPro and DSA keycaps take _forever_ to render. This is a multifaceted issue that I don't want to get into here, but suffice to say _one_ of the reasons it takes so long is how the keycap is constructed from multiple, smaller slices. OpenSCAD takes more time to render the more objects you have, regardless of how they interact. Enter `$skin_extrude_shape = true`.
|
||||
SA, HiPro and DSA keycaps take _forever_ to render. This is a multifaceted issue that I don't want to get into here, but suffice to say _one_ of the reasons it takes so long is how the keycap is constructed from multiple, smaller slices. OpenSCAD takes more time to render the more objects you have, regardless of how they interact. Enter `$hull_shape_type = "skin"`.
|
||||
|
||||
`skin()` is a list comprehension function available [here](https://github.com/openscad/list-comprehension-demos/blob/master/skin.scad). The gist of it is that instead of having x number of keycap slices unioned together, we give `skin()` a set of profiles and it makes a single object out of it for us. This reduces the number of objects per keycap, which makes it easier to render them.
|
||||
|
||||
|
|
|
|||
7
TODO.md
Normal file
7
TODO.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
TODO:
|
||||
* Make flat stem support default
|
||||
* implement regular polygon for skin extrusions
|
||||
* switch to skin-shaped extrusions by default
|
||||
* kailh choc has a non-square key unit; should I get that working for layouts etc?
|
||||
* move everything over to layouts requiring a child key
|
||||
* add an "errors" or "warnings" or "suggestions" echo section in key.scad, right when the key is being made, so the errors don't get lost / repeated
|
||||
3763
customizer.scad
3763
customizer.scad
File diff suppressed because it is too large
Load diff
|
|
@ -17,4 +17,4 @@ dcs_row(5) legend("⇪", size=9) key();
|
|||
} */
|
||||
|
||||
// example layout
|
||||
/* preonic_default("dcs"); */
|
||||
/* preonic_default("dcs") key(); */
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// a safe theoretical distance between two vertices such that they don't collapse. hard to use
|
||||
SMALLEST_POSSIBLE = 1/128;
|
||||
$fs = .1;
|
||||
$unit = 19.05;
|
||||
$fs=0.1;
|
||||
$unit=19.05;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ include <dishes/cylindrical.scad>
|
|||
include <dishes/old_spherical.scad>
|
||||
include <dishes/sideways_cylindrical.scad>
|
||||
include <dishes/spherical.scad>
|
||||
include <dishes/squared_spherical.scad>
|
||||
include <dishes/squared_scoop.scad>
|
||||
include <dishes/flat.scad>
|
||||
include <dishes/3d_surface.scad>
|
||||
|
||||
|
|
@ -14,20 +16,22 @@ geodesic=false;
|
|||
module dish(width, height, depth, inverted) {
|
||||
if($dish_type == "cylindrical"){
|
||||
cylindrical_dish(width, height, depth, inverted);
|
||||
}
|
||||
else if ($dish_type == "spherical") {
|
||||
} else if ($dish_type == "spherical") {
|
||||
spherical_dish(width, height, depth, inverted);
|
||||
}
|
||||
else if ($dish_type == "sideways cylindrical"){
|
||||
} else if ($dish_type == "sideways cylindrical"){
|
||||
sideways_cylindrical_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "old spherical") {
|
||||
old_spherical_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "3d_surface") {
|
||||
} else if ($dish_type == "3d surface") {
|
||||
3d_surface_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "flat") {
|
||||
flat_dish(width, height, depth, inverted);
|
||||
} else if ($dish_type == "disable") {
|
||||
// else no dish
|
||||
} else if ($dish_type == "squared spherical") {
|
||||
squared_spherical_dish(width, height, depth, inverted=inverted);
|
||||
} else if ($dish_type == "squared scoop") {
|
||||
squared_scoop_dish(width, height, depth, inverted=inverted);
|
||||
} else {
|
||||
echo("WARN: $dish_type unsupported");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ module 3d_surface_dish(width, height, depth, inverted) {
|
|||
// it doesn't have to be dead reckoning for anything but sculpted sides
|
||||
// we know the angle of the sides from the width difference, height difference,
|
||||
// skew and tilt of the top. it's a pain to calculate though
|
||||
scale_factor = 1.1;
|
||||
scale_factor = 1.11;
|
||||
// the edges on this behave differently than with the previous dish implementations
|
||||
scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth]) rotate([inverted ? 0:180,0,90]) polar_3d_surface(bottom=-10);
|
||||
scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth])
|
||||
rotate([inverted ? 0:180,0,180])
|
||||
polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-10);
|
||||
/* %scale([width*scale_factor/$3d_surface_size/2,height*scale_factor/$3d_surface_size/2,depth]) rotate([180,0,0]) polar_3d_surface(bottom=-10); */
|
||||
|
||||
}
|
||||
|
|
|
|||
34
src/dishes/squared_scoop.scad
Normal file
34
src/dishes/squared_scoop.scad
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
module squared_scoop_dish(height, width, depth, r=0.5, inverted=false, num=4, den=5){
|
||||
// changable numerator/denoninator on where to place the square's corners
|
||||
// for example, num=2, den=3 means the dish will happen at 1/3 and 2/3 the
|
||||
// width and the height. Defaults to 4/5. Customizable when calling
|
||||
// this module
|
||||
//
|
||||
// This was initially intended for the scoop on the HiPro, since that's what
|
||||
// it uses. Use "hipro_row()" if that's what you'd like. However, I do NOT
|
||||
// know how close the inner square is for the HiPro keycaps. In fact, it could
|
||||
// just be a sphere, in which the "squared spherical" scoop is more appropriate.
|
||||
// If, however, it the "squared scoop" makes sense, you can adjust where the square
|
||||
// lands with the num (numerator) and den (denominator) variables. For instance,
|
||||
// "3" and "4" mean 3/4 of the width/height is where the flat part starts.
|
||||
|
||||
chord = pow(pow(height/2, 2) + pow(width/2, 2),0.5);
|
||||
direction = inverted ? -1 : 1;
|
||||
|
||||
//This is the set of points to hull around for the scoop
|
||||
points=[
|
||||
[height/den - height/2, width/den - width/2, -chord],
|
||||
[num*height/den - height/2, width/den - width/2, -chord],
|
||||
[height/den - height/2, num*width/den - width/2, -chord],
|
||||
[num*height/den - height/2, num*width/den - width/2, -chord]
|
||||
];
|
||||
|
||||
resize([height,width,depth])
|
||||
hull() {
|
||||
shape_slice(1,0,0);
|
||||
for(i=[0:len(points)-1]) {
|
||||
translate(points[i])
|
||||
sphere(r=r,$fn=64);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
src/dishes/squared_spherical.scad
Normal file
22
src/dishes/squared_spherical.scad
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
module squared_spherical_dish(width, height, depth, inverted=false) {
|
||||
chord = pow(pow(height / 2, 2) + pow(width / 2, 2),0.5);
|
||||
direction = inverted ? -1 : 1;
|
||||
r=max(height,width,chord) / 5;
|
||||
// ^^^^^ Nothing special about this code to figure out r.
|
||||
// I just modeled up 1u, 1.25u, 1.5u, 2u, 2.25u, and 2.75u
|
||||
// keys and messed around until I came up with something that
|
||||
// looked reasonable for all key sizes. This just seems to work
|
||||
// well for all sizes
|
||||
|
||||
translate([-width / 2, -height / 2, 0 * direction]) {
|
||||
resize([width, height, depth])
|
||||
hull() {
|
||||
cube([chord,chord,0.001]);
|
||||
// Use something larger in this translate than -depth
|
||||
// (like -chord) if you want more of a defined circle
|
||||
// in the keywell
|
||||
translate([chord/2, chord/2, -depth])
|
||||
sphere(r=r, $fn=128);
|
||||
}
|
||||
}
|
||||
}
|
||||
6
src/features.scad
Normal file
6
src/features.scad
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// features are any premade self-contained objects that go on top or inside
|
||||
|
||||
include <features/key_bump.scad>
|
||||
include <features/clearance_check.scad>
|
||||
include <features/legends.scad>
|
||||
include <features/resin_holes.scad>
|
||||
24
src/features/clearance_check.scad
Normal file
24
src/features/clearance_check.scad
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// a fake cherry keyswitch, abstracted out to maybe replace with a better one later
|
||||
module cherry_keyswitch() {
|
||||
union() {
|
||||
hull() {
|
||||
cube([15.6, 15.6, 0.01], center=true);
|
||||
translate([0,1,5 - 0.01]) cube([10.5,9.5, 0.01], center=true);
|
||||
}
|
||||
hull() {
|
||||
cube([15.6, 15.6, 0.01], center=true);
|
||||
translate([0,0,-5.5]) cube([13.5,13.5,0.01], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//approximate (fully depressed) cherry key to check clearances
|
||||
module clearance_check() {
|
||||
if($stem_type == "cherry" || $stem_type == "cherry_rounded"){
|
||||
color($warning_color){
|
||||
translate([0,0,3.6 + $stem_inset - 5]) {
|
||||
cherry_keyswitch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/features/legends.scad
Normal file
26
src/features/legends.scad
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
module keytext(text, position, font_size, depth) {
|
||||
woffset = (top_total_key_width()/3.5) * position[0];
|
||||
hoffset = (top_total_key_height()/3.5) * -position[1];
|
||||
translate([woffset, hoffset, -depth]){
|
||||
color($tertiary_color) linear_extrude(height=$dish_depth + depth){
|
||||
text(text=text, font=$font, size=font_size, halign="center", valign="center");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module legends(depth=0) {
|
||||
if (len($front_legends) > 0) {
|
||||
front_of_key() {
|
||||
for (i=[0:len($front_legends)-1]) {
|
||||
rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (len($legends) > 0) {
|
||||
top_of_key() {
|
||||
for (i=[0:len($legends)-1]) {
|
||||
keytext($legends[i][0], $legends[i][1], $legends[i][2], depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/features/resin_holes.scad
Normal file
46
src/features/resin_holes.scad
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
module resin_suction_holes() {
|
||||
if ($key_shape_type != "sculpted_square"
|
||||
&& $key_shape_type != "rounded_square"
|
||||
&& $key_shape_type != "flat_sided_square"
|
||||
&& $key_shape_type != "square") {
|
||||
echo("Warning: unsupported $key_shape_type for resin_suction_holes. disable resin_suction_holes or pick a new shape");
|
||||
}
|
||||
|
||||
dx = $key_length*$unit/2;
|
||||
dy = $key_height*$unit/2;
|
||||
|
||||
for(theta=[0, 180])
|
||||
rotate(theta)
|
||||
{
|
||||
translate([dx,dy])
|
||||
rotate(-45)
|
||||
rotate([90,0,0])
|
||||
cylinder(center=true, d=2, h=8);
|
||||
|
||||
translate([-dx,dy])
|
||||
rotate(45)
|
||||
rotate([90,0,0])
|
||||
cylinder(center=true, d=2, h=8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module resin_drain_holes() {
|
||||
if ($key_shape_type != "sculpted_square"
|
||||
&& $key_shape_type != "rounded_square"
|
||||
&& $key_shape_type != "flat_sided_square"
|
||||
&& $key_shape_type != "square") {
|
||||
echo("Warning: unsupported $key_shape_type for resin_drain_holes. disable resin_drain_holes or pick a new shape");
|
||||
}
|
||||
|
||||
// XXX these calculations are specific to the flared support type
|
||||
loft = $stem_throw;
|
||||
height = $total_depth-$stem_throw;
|
||||
dx = $key_length*$unit/2;
|
||||
for(r=[90, 270])
|
||||
rotate(r)
|
||||
translate([0,dx,loft+height/4-1])
|
||||
rotate([87,0,0])
|
||||
cylinder(center=true, d=3, h=11);
|
||||
}
|
||||
|
||||
|
|
@ -4,6 +4,8 @@ include <constants.scad>
|
|||
// functions need to be explicitly included, unlike special variables, which
|
||||
// just need to have been set before they are used. hence this file
|
||||
|
||||
function stem_height() = $total_depth - $dish_depth - $stem_inset;
|
||||
|
||||
// cherry stem dimensions
|
||||
function outer_cherry_stem(slop) = [7.2 - slop * 2, 5.5 - slop * 2];
|
||||
|
||||
|
|
@ -31,7 +33,7 @@ function top_total_key_height() = $bottom_key_height + ($unit * ($key_height - 1
|
|||
|
||||
function side_tilt(column) = asin($unit * column / $double_sculpt_radius);
|
||||
// tan of 0 is 0, division by 0 is nan, so we have to guard
|
||||
function extra_side_tilt_height(column) = side_tilt(column) ? ($double_sculpt_radius - (unit * abs(column)) / tan(abs(side_tilt(column)))) : 0;
|
||||
function extra_side_tilt_height(column) = side_tilt(column) ? ($double_sculpt_radius - ($unit * abs(column)) / tan(abs(side_tilt(column)))) : 0;
|
||||
|
||||
// (I think) extra length of the side of the keycap due to the keytop being tilted.
|
||||
// necessary for calculating flat sided keycaps
|
||||
|
|
@ -41,25 +43,7 @@ function vertical_inclination_due_to_top_tilt() = sin($top_tilt) * (top_total_ke
|
|||
// I derived this through a bunch of trig reductions I don't really understand.
|
||||
function extra_keytop_length_for_flat_sides() = ($width_difference * vertical_inclination_due_to_top_tilt()) / ($total_depth);
|
||||
|
||||
// 3d surface functions (still in beta)
|
||||
|
||||
// monotonically increasing function that distributes the points of the surface mesh
|
||||
// only for polar_3d_surface right now
|
||||
// if it's linear it's a grid. sin(dim) * size concentrates detail around the edges
|
||||
function surface_distribution_function(dim, size) = sin(dim) * size;
|
||||
|
||||
// the function that actually determines what the surface is.
|
||||
// feel free to override, the last one wins
|
||||
|
||||
// debug
|
||||
function surface_function(x,y) = 1;
|
||||
// cylindrical
|
||||
function surface_function(x,y) = (sin(acos(x/$3d_surface_size)));
|
||||
// spherical
|
||||
function surface_function(x,y) = (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
|
||||
// (statically) random!
|
||||
/* function surface_function(x,y) = sin(rands(0,90,1,x+y)[0]); */
|
||||
// adds uniform rounding radius for round-anything polyRound
|
||||
function add_rounding(p, radius)=[for(i=[0:len(p)-1])[p[i].x,p[i].y, radius]];
|
||||
// computes millimeter length from unit length
|
||||
function unit_length(length) = unit * (length - 1) + 18.16;
|
||||
function unit_length(length) = $unit * (length - 1) + 18.16;
|
||||
|
|
|
|||
19
src/hulls.scad
Normal file
19
src/hulls.scad
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
include <hulls/skin.scad>
|
||||
include <hulls/linear_extrude.scad>
|
||||
include <hulls/hull.scad>
|
||||
|
||||
// basic key shape, no dish, no inside
|
||||
// which is only used for dishing to cut the dish off correctly
|
||||
// $height_difference used for keytop thickness
|
||||
// extra_slices is a hack to make inverted dishes still work
|
||||
module shape_hull(thickness_difference, depth_difference, extra_slices = 0){
|
||||
render() {
|
||||
if ($hull_shape_type == "skin") {
|
||||
skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices);
|
||||
} else if ($hull_shape_type == "linear extrude") {
|
||||
linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices);
|
||||
} else {
|
||||
hull_shape_hull(thickness_difference, depth_difference, extra_slices);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/hulls/hull.scad
Normal file
37
src/hulls/hull.scad
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
module hull_shape_hull(thickness_difference, depth_difference, extra_slices = 0) {
|
||||
for (index = [0:$height_slices - 1 + extra_slices]) {
|
||||
hull() {
|
||||
placed_shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
placed_shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module placed_shape_slice(progress, thickness_difference, depth_difference) {
|
||||
skew_this_slice = $top_skew * progress;
|
||||
x_skew_this_slice = $top_skew_x * progress;
|
||||
|
||||
depth_this_slice = ($total_depth - depth_difference) * progress;
|
||||
|
||||
tilt_this_slice = -$top_tilt / $key_height * progress;
|
||||
y_tilt_this_slice = $double_sculpted ? (-$top_tilt_y / $key_length * progress) : 0;
|
||||
|
||||
translate([x_skew_this_slice, skew_this_slice, depth_this_slice]) {
|
||||
rotate([tilt_this_slice,y_tilt_this_slice,0]){
|
||||
shape_slice(progress, thickness_difference, depth_difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module shape_slice(progress, thickness_difference, depth_difference) {
|
||||
linear_extrude(height = SMALLEST_POSSIBLE, scale = 1){
|
||||
key_shape(
|
||||
[
|
||||
total_key_width(thickness_difference),
|
||||
total_key_height(thickness_difference)
|
||||
],
|
||||
[$width_difference, $height_difference],
|
||||
progress
|
||||
);
|
||||
}
|
||||
}
|
||||
18
src/hulls/linear_extrude.scad
Normal file
18
src/hulls/linear_extrude.scad
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// corollary is hull_shape_hull
|
||||
// extra_slices unused, only to match argument signatures
|
||||
module linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices = 0){
|
||||
height = $total_depth - depth_difference;
|
||||
width_scale = top_total_key_width() / total_key_width();
|
||||
height_scale = top_total_key_height() / total_key_height();
|
||||
|
||||
translate([0,$linear_extrude_height_adjustment,0]){
|
||||
linear_extrude(height = height, scale = [width_scale, height_scale]) {
|
||||
translate([0,-$linear_extrude_height_adjustment,0]){
|
||||
key_shape(
|
||||
[total_key_width(), total_key_height()],
|
||||
[thickness_difference, thickness_difference]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
src/hulls/skin.scad
Normal file
34
src/hulls/skin.scad
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// use skin() instead of successive hulls. much more correct, and looks faster
|
||||
// too, in most cases. successive hull relies on overlapping faces which are
|
||||
// not good. But, skin works on vertex sets instead of shapes, which makes it
|
||||
// a lot more difficult to use
|
||||
module skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices = 0 ) {
|
||||
skin([
|
||||
for (index = [0:$height_slices + extra_slices])
|
||||
let(
|
||||
progress = (index / $height_slices),
|
||||
skew_this_slice = $top_skew * progress,
|
||||
x_skew_this_slice = $top_skew_x * progress,
|
||||
depth_this_slice = ($total_depth - depth_difference) * progress,
|
||||
tilt_this_slice = -$top_tilt / $key_height * progress,
|
||||
y_tilt_this_slice = $double_sculpted ? (-$top_tilt_y / $key_length * progress) : 0
|
||||
)
|
||||
skin_shape_slice(progress, thickness_difference, skew_this_slice, x_skew_this_slice, depth_this_slice, tilt_this_slice, y_tilt_this_slice)
|
||||
]);
|
||||
}
|
||||
|
||||
function skin_shape_slice(progress, thickness_difference, skew_this_slice, x_skew_this_slice, depth_this_slice, tilt_this_slice, y_tilt_this_slice) =
|
||||
transform(
|
||||
translation([x_skew_this_slice,skew_this_slice,depth_this_slice]),
|
||||
transform(
|
||||
rotation([tilt_this_slice,y_tilt_this_slice,0]),
|
||||
skin_key_shape([
|
||||
total_key_width(0) - thickness_difference,
|
||||
total_key_height(0) - thickness_difference,
|
||||
],
|
||||
[$width_difference, $height_difference],
|
||||
progress,
|
||||
thickness_difference
|
||||
)
|
||||
)
|
||||
);
|
||||
468
src/key.scad
468
src/key.scad
|
|
@ -6,7 +6,8 @@ include <stems.scad>
|
|||
include <stem_supports.scad>
|
||||
include <dishes.scad>
|
||||
include <supports.scad>
|
||||
include <key_features.scad>
|
||||
include <features.scad>
|
||||
include <hulls.scad>
|
||||
|
||||
include <libraries/geodesic_sphere.scad>
|
||||
|
||||
|
|
@ -19,201 +20,30 @@ use <libraries/skin.scad>
|
|||
// key shape including dish. used as the ouside and inside shape in hollow_key(). allows for itself to be shrunk in depth and width / height
|
||||
module shape(thickness_difference, depth_difference=0){
|
||||
dished(depth_difference, $inverted_dish) {
|
||||
/* %shape_hull(thickness_difference, depth_difference, $inverted_dish ? 2 : 0); */
|
||||
color($primary_color) shape_hull(thickness_difference, depth_difference, $inverted_dish ? 2 : 0);
|
||||
color($primary_color) shape_hull(thickness_difference, depth_difference, $inverted_dish ? 200 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// shape of the key but with soft, rounded edges. no longer includes dish
|
||||
// randomly doesnt work sometimes
|
||||
// the dish doesn't _quite_ reach as far as it should
|
||||
module rounded_shape() {
|
||||
dished(-$minkowski_radius, $inverted_dish) {
|
||||
color($primary_color) minkowski(){
|
||||
// half minkowski in the z direction
|
||||
color($primary_color) shape_hull($minkowski_radius * 2, $minkowski_radius/2, $inverted_dish ? 2 : 0);
|
||||
/* cube($minkowski_radius); */
|
||||
sphere(r=$minkowski_radius, $fn=$minkowski_facets);
|
||||
}
|
||||
}
|
||||
/* %envelope(); */
|
||||
}
|
||||
|
||||
// this function is more correct, but takes _forever_
|
||||
// the main difference is minkowski happens after dishing, meaning the dish is
|
||||
// also minkowski'd
|
||||
/* module rounded_shape() {
|
||||
color($primary_color) minkowski(){
|
||||
// half minkowski in the z direction
|
||||
shape($minkowski_radius * 2, $minkowski_radius/2);
|
||||
difference(){
|
||||
sphere(r=$minkowski_radius, $fn=20);
|
||||
translate([0,0,-$minkowski_radius]){
|
||||
cube($minkowski_radius * 2, center=true);
|
||||
}
|
||||
minkowski_object();
|
||||
}
|
||||
}
|
||||
|
||||
// minkowski places this object at every vertex of the other object then mashes
|
||||
// it all together
|
||||
module minkowski_object() {
|
||||
// alternative minkowski shape that needs the bottom of the keycap to be trimmed
|
||||
/* sphere(1); */
|
||||
|
||||
difference(){
|
||||
sphere(r=$minkowski_radius, $fa=360/$minkowski_facets);
|
||||
translate([0,0,-$minkowski_radius]){
|
||||
cube($minkowski_radius * 2, center=true);
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
|
||||
// basic key shape, no dish, no inside
|
||||
// which is only used for dishing to cut the dish off correctly
|
||||
// $height_difference used for keytop thickness
|
||||
// extra_slices is a hack to make inverted dishes still work
|
||||
module shape_hull(thickness_difference, depth_difference, extra_slices = 0){
|
||||
render() {
|
||||
if ($skin_extrude_shape) {
|
||||
skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices);
|
||||
} else if ($linear_extrude_shape) {
|
||||
linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices);
|
||||
} else {
|
||||
hull_shape_hull(thickness_difference, depth_difference, extra_slices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use skin() instead of successive hulls. much more correct, and looks faster
|
||||
// too, in most cases. successive hull relies on overlapping faces which are
|
||||
// not good. But, skin works on vertex sets instead of shapes, which makes it
|
||||
// a lot more difficult to use
|
||||
module skin_extrude_shape_hull(thickness_difference, depth_difference, extra_slices = 0 ) {
|
||||
skin([
|
||||
for (index = [0:$height_slices + extra_slices])
|
||||
let(
|
||||
progress = (index / $height_slices),
|
||||
skew_this_slice = $top_skew * progress,
|
||||
x_skew_this_slice = $top_skew_x * progress,
|
||||
depth_this_slice = ($total_depth - depth_difference) * progress,
|
||||
tilt_this_slice = -$top_tilt / $key_height * progress,
|
||||
y_tilt_this_slice = $double_sculpted ? (-$top_tilt_y / $key_length * progress) : 0
|
||||
)
|
||||
skin_shape_slice(progress, thickness_difference, skew_this_slice, x_skew_this_slice, depth_this_slice, tilt_this_slice, y_tilt_this_slice)
|
||||
]);
|
||||
}
|
||||
|
||||
function skin_shape_slice(progress, thickness_difference, skew_this_slice, x_skew_this_slice, depth_this_slice, tilt_this_slice, y_tilt_this_slice) =
|
||||
transform(
|
||||
translation([x_skew_this_slice,skew_this_slice,depth_this_slice]),
|
||||
transform(
|
||||
rotation([tilt_this_slice,y_tilt_this_slice,0]),
|
||||
skin_key_shape([
|
||||
total_key_width(0),
|
||||
total_key_height(0),
|
||||
],
|
||||
[$width_difference, $height_difference],
|
||||
progress,
|
||||
thickness_difference
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// corollary is hull_shape_hull
|
||||
// extra_slices unused, only to match argument signatures
|
||||
module linear_extrude_shape_hull(thickness_difference, depth_difference, extra_slices = 0){
|
||||
height = $total_depth - depth_difference;
|
||||
width_scale = top_total_key_width() / total_key_width();
|
||||
height_scale = top_total_key_height() / total_key_height();
|
||||
|
||||
translate([0,$linear_extrude_height_adjustment,0]){
|
||||
linear_extrude(height = height, scale = [width_scale, height_scale]) {
|
||||
translate([0,-$linear_extrude_height_adjustment,0]){
|
||||
key_shape(
|
||||
[total_key_width(thickness_difference), total_key_height(thickness_difference)],
|
||||
[$width_difference, $height_difference]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module hull_shape_hull(thickness_difference, depth_difference, extra_slices = 0) {
|
||||
for (index = [0:$height_slices - 1 + extra_slices]) {
|
||||
hull() {
|
||||
shape_slice(index / $height_slices, thickness_difference, depth_difference);
|
||||
shape_slice((index + 1) / $height_slices, thickness_difference, depth_difference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module shape_slice(progress, thickness_difference, depth_difference) {
|
||||
skew_this_slice = $top_skew * progress;
|
||||
x_skew_this_slice = $top_skew_x * progress;
|
||||
|
||||
depth_this_slice = ($total_depth - depth_difference) * progress;
|
||||
|
||||
tilt_this_slice = -$top_tilt / $key_height * progress;
|
||||
y_tilt_this_slice = $double_sculpted ? (-$top_tilt_y / $key_length * progress) : 0;
|
||||
|
||||
translate([x_skew_this_slice, skew_this_slice, depth_this_slice]) {
|
||||
rotate([tilt_this_slice,y_tilt_this_slice,0]){
|
||||
linear_extrude(height = SMALLEST_POSSIBLE){
|
||||
key_shape(
|
||||
[
|
||||
total_key_width(thickness_difference),
|
||||
total_key_height(thickness_difference)
|
||||
],
|
||||
[$width_difference, $height_difference],
|
||||
progress
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for when you want something to only exist inside the keycap.
|
||||
// used for the support structure
|
||||
module inside() {
|
||||
intersection() {
|
||||
shape($wall_thickness, $keytop_thickness);
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
// for when you want something to only exist outside the keycap
|
||||
module outside() {
|
||||
difference() {
|
||||
children();
|
||||
shape($wall_thickness, $keytop_thickness);
|
||||
}
|
||||
}
|
||||
|
||||
// put something at the top of the key, with no adjustments for dishing
|
||||
module top_placement(depth_difference=0) {
|
||||
top_tilt_by_height = -$top_tilt / $key_height;
|
||||
top_tilt_y_by_length = $double_sculpted ? (-$top_tilt_y / $key_length) : 0;
|
||||
|
||||
minkowski_height = $rounded_key ? $minkowski_radius : 0;
|
||||
|
||||
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference + minkowski_height/2]){
|
||||
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
|
||||
children();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module front_placement() {
|
||||
// all this math is to take top skew and tilt into account
|
||||
// we need to find the new effective height and depth of the top, front lip
|
||||
// of the keycap to find the angle so we can rotate things correctly into place
|
||||
total_depth_difference = sin(-$top_tilt) * (top_total_key_height()/2);
|
||||
total_height_difference = $top_skew + (1 - cos(-$top_tilt)) * (top_total_key_height()/2);
|
||||
|
||||
angle = atan2(($total_depth - total_depth_difference), ($height_difference/2 + total_height_difference));
|
||||
hypotenuse = ($total_depth -total_depth_difference) / sin(angle);
|
||||
|
||||
translate([0,-total_key_height()/2,0]) {
|
||||
rotate([-(90-angle), 0, 0]) {
|
||||
translate([0,0,hypotenuse/2]){
|
||||
children();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// just to DRY up the code
|
||||
module _dish() {
|
||||
translate([$dish_offset_x,0,0]) dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, $inverted_dish);
|
||||
}
|
||||
|
||||
module envelope(depth_difference=0) {
|
||||
|
|
@ -226,18 +56,6 @@ module envelope(depth_difference=0) {
|
|||
}
|
||||
}
|
||||
|
||||
// I think this is unused
|
||||
module dished_for_show() {
|
||||
difference(){
|
||||
union() {
|
||||
envelope();
|
||||
if ($inverted_dish) top_placement(0) color($secondary_color) _dish();
|
||||
}
|
||||
if (!$inverted_dish) top_placement(0) color($secondary_color) _dish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// for when you want to take the dish out of things
|
||||
// used for adding the dish to the key shape and making sure stems don't stick out the top
|
||||
// creates a bounding box 1.5 times larger in width and height than the keycap.
|
||||
|
|
@ -246,38 +64,24 @@ module dished(depth_difference = 0, inverted = false) {
|
|||
children();
|
||||
difference(){
|
||||
union() {
|
||||
// envelope is needed to "fill in" the rest of the keycap
|
||||
envelope(depth_difference);
|
||||
if (inverted) top_placement(depth_difference) color($secondary_color) _dish();
|
||||
if (inverted) top_placement(depth_difference) color($secondary_color) _dish(inverted);
|
||||
}
|
||||
if (!inverted) top_placement(depth_difference) color($secondary_color) _dish();
|
||||
if (!inverted) top_placement(depth_difference) color($secondary_color) _dish(inverted);
|
||||
/* %top_placement(depth_difference) _dish(); */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// puts it's children at the center of the dishing on the key, including dish height
|
||||
// more user-friendly than top_placement
|
||||
module top_of_key(){
|
||||
// if there is a dish, we need to account for how much it digs into the top
|
||||
dish_depth = ($dish_type == "disable") ? 0 : $dish_depth;
|
||||
// if the dish is inverted, we need to account for that too. in this case we do half, otherwise the children would be floating on top of the dish
|
||||
corrected_dish_depth = ($inverted_dish) ? -dish_depth / 2 : dish_depth;
|
||||
|
||||
top_placement(corrected_dish_depth) {
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
module keytext(text, position, font_size, depth) {
|
||||
woffset = (top_total_key_width()/3.5) * position[0];
|
||||
hoffset = (top_total_key_height()/3.5) * -position[1];
|
||||
translate([woffset, hoffset, -depth]){
|
||||
color($tertiary_color) linear_extrude(height=$dish_depth){
|
||||
text(text=text, font=$font, size=font_size, halign="center", valign="center");
|
||||
}
|
||||
}
|
||||
// just to DRY up the code
|
||||
// TODO is putting special vars in function signatures legal
|
||||
module _dish(inverted=$inverted_dish) {
|
||||
translate([$dish_offset_x,0,0]) color($secondary_color)
|
||||
dish(top_total_key_width() + $dish_overdraw_width, top_total_key_height() + $dish_overdraw_height, $dish_depth, inverted);
|
||||
}
|
||||
|
||||
// puts its children at each keystem position provided
|
||||
module keystem_positions(positions) {
|
||||
for (connector_pos = positions) {
|
||||
translate(connector_pos) {
|
||||
|
|
@ -296,131 +100,167 @@ module support_for(positions, stem_type) {
|
|||
|
||||
module stems_for(positions, stem_type) {
|
||||
keystem_positions(positions) {
|
||||
color($tertiary_color) stem(stem_type, $total_depth, $stem_slop, $stem_throw);
|
||||
color($tertiary_color) stem(stem_type, stem_height(), $stem_slop, $stem_throw);
|
||||
if ($stem_support_type != "disable") {
|
||||
color($quaternary_color) stem_support($stem_support_type, stem_type, $stem_support_height, $stem_slop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a fake cherry keyswitch, abstracted out to maybe replace with a better one later
|
||||
module cherry_keyswitch() {
|
||||
union() {
|
||||
hull() {
|
||||
cube([15.6, 15.6, 0.01], center=true);
|
||||
translate([0,1,5 - 0.01]) cube([10.5,9.5, 0.01], center=true);
|
||||
}
|
||||
hull() {
|
||||
cube([15.6, 15.6, 0.01], center=true);
|
||||
translate([0,0,-5.5]) cube([13.5,13.5,0.01], center=true);
|
||||
// put something at the top of the key, with no adjustments for dishing
|
||||
module top_placement(depth_difference=0) {
|
||||
top_tilt_by_height = -$top_tilt / $key_height;
|
||||
top_tilt_y_by_length = $double_sculpted ? (-$top_tilt_y / $key_length) : 0;
|
||||
|
||||
// minkowski_height = $rounded_key ? $minkowski_radius : 0;
|
||||
|
||||
translate([$top_skew_x + $dish_skew_x, $top_skew + $dish_skew_y, $total_depth - depth_difference]){
|
||||
rotate([top_tilt_by_height, top_tilt_y_by_length,0]){
|
||||
children();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//approximate (fully depressed) cherry key to check clearances
|
||||
module clearance_check() {
|
||||
if($stem_type == "cherry" || $stem_type == "cherry_rounded"){
|
||||
color($warning_color){
|
||||
translate([0,0,3.6 + $stem_inset - 5]) {
|
||||
cherry_keyswitch();
|
||||
// puts its children at the center of the dishing on the key, including dish height
|
||||
// more user-friendly than top_placement
|
||||
module top_of_key(){
|
||||
// if there is a dish, we need to account for how much it digs into the top
|
||||
dish_depth = ($dish_type == "disable") ? 0 : $dish_depth;
|
||||
// if the dish is inverted, we need to account for that too. in this case we do half, otherwise the children would be floating on top of the dish
|
||||
corrected_dish_depth = ($inverted_dish) ? -dish_depth / 2 : dish_depth;
|
||||
|
||||
top_placement(corrected_dish_depth) {
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
module front_of_key() {
|
||||
// all this math is to take top skew and tilt into account
|
||||
// we need to find the new effective height and depth of the top, front lip
|
||||
// of the keycap to find the angle so we can rotate things correctly into place
|
||||
total_depth_difference = sin(-$top_tilt) * (top_total_key_height()/2);
|
||||
total_height_difference = $top_skew + (1 - cos(-$top_tilt)) * (top_total_key_height()/2);
|
||||
|
||||
angle = atan2(($total_depth - total_depth_difference), ($height_difference/2 + total_height_difference));
|
||||
hypotenuse = ($total_depth -total_depth_difference) / sin(angle);
|
||||
|
||||
translate([0,-total_key_height()/2,0]) {
|
||||
rotate([-(90-angle), 0, 0]) {
|
||||
translate([0,0,hypotenuse/2]){
|
||||
children();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module legends(depth=0) {
|
||||
if (len($front_legends) > 0) {
|
||||
front_placement() {
|
||||
if (len($front_legends) > 0) {
|
||||
for (i=[0:len($front_legends)-1]) {
|
||||
rotate([90,0,0]) keytext($front_legends[i][0], $front_legends[i][1], $front_legends[i][2], depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (len($legends) > 0) {
|
||||
top_of_key() {
|
||||
// outset legend
|
||||
if (len($legends) > 0) {
|
||||
for (i=[0:len($legends)-1]) {
|
||||
keytext($legends[i][0], $legends[i][1], $legends[i][2], depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
module outer_shape() {
|
||||
if ($rounded_key == true) {
|
||||
rounded_shape();
|
||||
} else {
|
||||
shape(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// legends / artisan support
|
||||
module artisan(depth) {
|
||||
module inner_shape(extra_wall_thickness = 0, extra_keytop_thickness = 0) {
|
||||
if ($inner_shape_type == "flat") {
|
||||
/* $key_shape_type="square"; */
|
||||
$height_slices = 1;
|
||||
// if inner_shape is flat, keytop_thickness will be dish_depth less than it should be, since the dish digs in that far.
|
||||
// so, we add dish_depth here
|
||||
color($primary_color) shape_hull($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness + $dish_depth, 0);
|
||||
} else {
|
||||
shape($wall_thickness + extra_wall_thickness, $keytop_thickness + extra_keytop_thickness);
|
||||
}
|
||||
}
|
||||
|
||||
// additive objects at the top of the key
|
||||
module additive_features(inset) {
|
||||
top_of_key() {
|
||||
// artisan objects / outset shape legends
|
||||
color($secondary_color) children();
|
||||
if($key_bump) keybump($key_bump_depth, $key_bump_edge);
|
||||
if(!inset && $children > 0) color($secondary_color) children();
|
||||
}
|
||||
if($outset_legends) legends(0);
|
||||
// render the clearance check if it's enabled, but don't have it intersect with anything
|
||||
if ($clearance_check) %clearance_check();
|
||||
}
|
||||
|
||||
// subtractive objects at the top of the key
|
||||
module subtractive_features(inset) {
|
||||
top_of_key() {
|
||||
if (inset && $children > 0) color($secondary_color) children();
|
||||
}
|
||||
if(!$outset_legends) legends($inset_legend_depth);
|
||||
// subtract the clearance check if it's enabled, letting the user see the
|
||||
// parts of the keycap that will hit the cherry switch
|
||||
// this is a little confusing as it eats the stem too
|
||||
/* if ($clearance_check) clearance_check(); */
|
||||
|
||||
// resin-specific subtractive features
|
||||
if($resin_suction_holes) {
|
||||
resin_suction_holes();
|
||||
}
|
||||
|
||||
if($resin_drain_holes) {
|
||||
resin_drain_holes();
|
||||
}
|
||||
}
|
||||
|
||||
// key with hollowed inside but no stem
|
||||
module hollow_key() {
|
||||
difference(){
|
||||
if ($rounded_key) {
|
||||
rounded_shape();
|
||||
} else {
|
||||
shape(0, 0);
|
||||
}
|
||||
// translation purely for aesthetic purposes, to get rid of that awful lattice
|
||||
translate([0,0,-SMALLEST_POSSIBLE]) {
|
||||
shape($wall_thickness, $keytop_thickness);
|
||||
}
|
||||
// features inside the key itself (stem, supports, etc)
|
||||
module inside_features() {
|
||||
// Stems and stabilizers are not "inside features" unless they are fully
|
||||
// contained inside the cap. otherwise they'd be cut off when they are
|
||||
// differenced with the outside shape. this only matters if $stem_inset
|
||||
// is negative
|
||||
if ($stem_inset >= 0) stems_and_stabilizers();
|
||||
if ($support_type != "disable") translate([0, 0, $stem_inset]) support_for($stem_positions, $stem_type);
|
||||
if ($stabilizer_type != "disable") translate([0, 0, $stem_inset]) support_for($stabilizers, $stabilizer_type);
|
||||
}
|
||||
|
||||
// all stems and stabilizers
|
||||
module stems_and_stabilizers() {
|
||||
translate([0, 0, $stem_inset]) {
|
||||
if ($stabilizer_type != "disable") stems_for($stabilizers, $stabilizer_type);
|
||||
if ($stem_type != "disable") stems_for($stem_positions, $stem_type);
|
||||
}
|
||||
}
|
||||
|
||||
// helpers for doubleshot keycaps for now
|
||||
module inner_total_shape() {
|
||||
difference() {
|
||||
inner_shape();
|
||||
inside_features();
|
||||
}
|
||||
}
|
||||
|
||||
module outer_total_shape(inset=false) {
|
||||
outer_shape();
|
||||
additive_features(inset) {
|
||||
children();
|
||||
};
|
||||
}
|
||||
|
||||
// The final, penultimate key generation function.
|
||||
// takes all the bits and glues them together. requires configuration with special variables.
|
||||
module key(inset = false) {
|
||||
difference() {
|
||||
union(){
|
||||
// the shape of the key, inside and out
|
||||
hollow_key();
|
||||
if($key_bump) top_of_key() keybump($key_bump_depth, $key_bump_edge);
|
||||
// additive objects at the top of the key
|
||||
// outside() makes them stay out of the inside. it's a bad name
|
||||
if(!inset && $children > 0) outside() artisan(0) children();
|
||||
if($outset_legends) legends(0);
|
||||
// render the clearance check if it's enabled, but don't have it intersect with anything
|
||||
if ($clearance_check) %clearance_check();
|
||||
}
|
||||
module key(inset=false) {
|
||||
difference(){
|
||||
outer_total_shape(inset) {
|
||||
children();
|
||||
};
|
||||
|
||||
// subtractive objects at the top of the key
|
||||
// no outside() - I can't think of a use for it. will save render time
|
||||
if (inset && $children > 0) artisan($inset_legend_depth) children();
|
||||
if(!$outset_legends) legends($inset_legend_depth);
|
||||
// subtract the clearance check if it's enabled, letting the user see the
|
||||
// parts of the keycap that will hit the cherry switch
|
||||
if ($clearance_check) %clearance_check();
|
||||
}
|
||||
|
||||
// both stem and support are optional
|
||||
if ($stem_type != "disable" || ($stabilizers != [] && $stabilizer_type != "disable")) {
|
||||
dished($keytop_thickness, $inverted_dish) {
|
||||
translate([0, 0, $stem_inset]) {
|
||||
if ($stabilizer_type != "disable") stems_for($stabilizers, $stabilizer_type);
|
||||
|
||||
if ($stem_type != "disable") stems_for($stem_positions, $stem_type);
|
||||
if ($inner_shape_type != "disable") {
|
||||
translate([0,0,-SMALLEST_POSSIBLE]) {
|
||||
inner_total_shape();
|
||||
}
|
||||
}
|
||||
|
||||
subtractive_features(inset) {
|
||||
children();
|
||||
};
|
||||
}
|
||||
|
||||
if ($support_type != "disable"){
|
||||
inside() {
|
||||
translate([0, 0, $stem_inset]) {
|
||||
if ($stabilizer_type != "disable") support_for($stabilizers, $stabilizer_type);
|
||||
|
||||
// always render stem support even if there isn't a stem.
|
||||
// rendering flat support w/no stem is much more common than a hollow keycap
|
||||
// so if you want a hollow keycap you'll have to turn support off entirely
|
||||
support_for($stem_positions, $stem_type);
|
||||
}
|
||||
}
|
||||
// if $stem_inset is less than zero, we add the
|
||||
if ($stem_inset < 0) {
|
||||
stems_and_stabilizers();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,13 @@ include <key_profiles/dsa.scad>
|
|||
include <key_profiles/sa.scad>
|
||||
include <key_profiles/g20.scad>
|
||||
include <key_profiles/hipro.scad>
|
||||
include <key_profiles/mt3.scad>
|
||||
include <key_profiles/grid.scad>
|
||||
include <key_profiles/regular_polygon.scad>
|
||||
include <key_profiles/cherry.scad>
|
||||
include <key_profiles/dss.scad>
|
||||
include <key_profiles/asa.scad>
|
||||
include <key_profiles/typewriter.scad>
|
||||
|
||||
// man, wouldn't it be so cool if functions were first order
|
||||
module key_profile(key_profile_type, row, column=0) {
|
||||
|
|
@ -24,14 +28,24 @@ module key_profile(key_profile_type, row, column=0) {
|
|||
dss_row(row, column) children();
|
||||
} else if (key_profile_type == "sa") {
|
||||
sa_row(row, column) children();
|
||||
} else if (key_profile_type == "asa") {
|
||||
asa_row(row, column) children();
|
||||
} else if (key_profile_type == "g20") {
|
||||
g20_row(row, column) children();
|
||||
} else if (key_profile_type == "hipro") {
|
||||
hipro_row(row, column) children();
|
||||
} else if (key_profile_type == "grid") {
|
||||
grid_row(row, column) children();
|
||||
} else if (key_profile_type == "typewriter") {
|
||||
typewriter_row(row, column) children();
|
||||
} else if (key_profile_type == "hexagon") {
|
||||
hexagonal_row(row, column) children();
|
||||
} else if (key_profile_type == "octagon") {
|
||||
octagonal_row(row, column) children();
|
||||
} else if (key_profile_type == "cherry") {
|
||||
cherry_row(row, column) children();
|
||||
} else if (key_profile_type == "mt3") {
|
||||
mt3_row(row, column) children();
|
||||
} else if (key_profile_type == "disable") {
|
||||
children();
|
||||
} else {
|
||||
|
|
|
|||
42
src/key_profiles/asa.scad
Normal file
42
src/key_profiles/asa.scad
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
module asa_row(row=3, column = 0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
$bottom_key_height = 18.06;
|
||||
$bottom_key_width = 18.05; // Default (R3)
|
||||
$total_depth = 10.35; // Default (R3)
|
||||
$top_tilt = 1.5; // Default (R3)
|
||||
$width_difference = 5.05;
|
||||
$height_difference = 5.56;
|
||||
$dish_type = "spherical";
|
||||
$dish_depth = 1.2;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 1.75;
|
||||
$stem_inset = 1.2;
|
||||
$height_slices = 10;
|
||||
$corner_radius = 1;
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
//$rounded_key = true;
|
||||
|
||||
if (row == 1){
|
||||
$bottom_key_width = 17.95;
|
||||
$width_difference = 4.95;
|
||||
$total_depth = 10.65;
|
||||
$top_tilt = 7;
|
||||
children();
|
||||
} else if (row == 2) {
|
||||
$bottom_key_width = 18.17;
|
||||
$width_difference = 5.17;
|
||||
$total_depth = 9.65;
|
||||
$top_tilt = 3.25;
|
||||
children();
|
||||
} else if (row == 4){
|
||||
$bottom_key_width = 18.02;
|
||||
$width_difference = 5.02;
|
||||
$total_depth = 11.9;
|
||||
$top_tilt = 0.43;
|
||||
children();
|
||||
} else {
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ module grid_row(row=3, column = 0) {
|
|||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
|
||||
$linear_extrude_shape = true;
|
||||
$hull_shape_type = "linear extrude";
|
||||
|
||||
|
||||
$dish_overdraw_width = -6.5;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// my own measurements
|
||||
module hipro_row(row=3, column=0) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
|
||||
|
|
@ -7,7 +6,7 @@ module hipro_row(row=3, column=0) {
|
|||
|
||||
$width_difference = ($bottom_key_width - 12.3);
|
||||
$height_difference = ($bottom_key_height - 12.65);
|
||||
$dish_type = "spherical";
|
||||
$dish_type = "squared scoop";
|
||||
$dish_depth = 0.75;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
|
|
|
|||
53
src/key_profiles/mt3.scad
Normal file
53
src/key_profiles/mt3.scad
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// This is an imperfect attempt to clone the MT3 profile
|
||||
module mt3_row(row=3, column=0, deep_dish=false) {
|
||||
$key_shape_type = "sculpted_square";
|
||||
|
||||
$bottom_key_width = 18.35;
|
||||
$bottom_key_height = 18.6;
|
||||
|
||||
$width_difference = ($bottom_key_width - 13.0);
|
||||
$height_difference = ($bottom_key_height - 13.0);
|
||||
$dish_type = "squared spherical";
|
||||
$dish_depth = deep_dish ? 1.6 : 1.2;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 0;
|
||||
$height_slices = 10;
|
||||
|
||||
$corner_sculpting_factor = 2;
|
||||
$corner_radius = 0.0125;
|
||||
|
||||
$more_side_sculpting_factor = 0.75;
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
if (row == 0){
|
||||
// TODO I didn't change these yet
|
||||
$total_depth = 14.7 + extra_height;
|
||||
$top_tilt = -12.5;
|
||||
children();
|
||||
} else if (row == 1) {
|
||||
$total_depth = 13.1 + extra_height;
|
||||
$top_tilt = -6;
|
||||
children();
|
||||
} else if (row == 2) {
|
||||
$total_depth = 10.7 + extra_height;
|
||||
$top_tilt = -6;
|
||||
children();
|
||||
} else if (row == 3) {
|
||||
$total_depth = 10.7 + extra_height;
|
||||
$top_tilt = 6;
|
||||
children();
|
||||
} else if (row == 4){
|
||||
$total_depth = 11.6 + extra_height;
|
||||
$top_tilt = 12;
|
||||
children();
|
||||
} else if (row >= 5) {
|
||||
$total_depth = 11.6 + extra_height;
|
||||
$top_tilt = 0;
|
||||
children();
|
||||
} else {
|
||||
children();
|
||||
}
|
||||
}
|
||||
66
src/key_profiles/regular_polygon.scad
Normal file
66
src/key_profiles/regular_polygon.scad
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
include <../constants.scad>
|
||||
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
|
||||
// This is to make tiling them easier, like in the case of hexagonal keycaps etc
|
||||
|
||||
// this function doesn't set the key shape, so you can't use it directly without some fiddling
|
||||
module regular_polygon_row(n=3, column=0) {
|
||||
$bottom_key_width = $unit - 0.5;
|
||||
$bottom_key_height = $unit - 0.5;
|
||||
$width_difference = 0;
|
||||
$height_difference = 0;
|
||||
$dish_type = "spherical";
|
||||
$dish_depth = 0.85;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 0;
|
||||
$height_slices = 1;
|
||||
$corner_radius = 1;
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
/* $rounded_key = true; */
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
base_depth = 7.5;
|
||||
if (n <= 1){
|
||||
$total_depth = base_depth + 2.5 + extra_height;
|
||||
$top_tilt = -13;
|
||||
|
||||
children();
|
||||
} else if (n == 2) {
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = -7;
|
||||
|
||||
children();
|
||||
} else if (n == 3) {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
} else if (n == 4){
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = 7;
|
||||
|
||||
children();
|
||||
} else {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
module hexagonal_row(n=3, column=0) {
|
||||
$key_shape_type = "hexagon";
|
||||
regular_polygon_row(n,column) {
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
||||
module octagonal_row(n=3, column=0) {
|
||||
$key_shape_type = "octagon";
|
||||
regular_polygon_row(n, column) {
|
||||
children();
|
||||
}
|
||||
}
|
||||
57
src/key_profiles/typewriter.scad
Normal file
57
src/key_profiles/typewriter.scad
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
include <../constants.scad>
|
||||
// Regular polygon shapes CIRCUMSCRIBE the sphere of diameter $bottom_key_width
|
||||
// This is to make tiling them easier, like in the case of hexagonal keycaps etc
|
||||
|
||||
// this function doesn't set the key shape, so you can't use it directly without some fiddling
|
||||
module typewriter_row(n=3, column=0) {
|
||||
$bottom_key_width = $unit - 0.5;
|
||||
$bottom_key_height = $unit - 0.5;
|
||||
$width_difference = 0;
|
||||
$height_difference = 0;
|
||||
$dish_type = "spherical";
|
||||
$key_shape_type = "circular";
|
||||
$inverted_dish = true;
|
||||
$stem_inset = -4.5;
|
||||
$stem_throw = 5;
|
||||
$dish_depth = 1;
|
||||
$dish_skew_x = 0;
|
||||
$dish_skew_y = 0;
|
||||
$top_skew = 0;
|
||||
$height_slices = 1;
|
||||
$stem_support_type = "disable";
|
||||
// $corner_radius = 1;
|
||||
|
||||
// this is _incredibly_ intensive
|
||||
/* $rounded_key = true; */
|
||||
|
||||
$top_tilt_y = side_tilt(column);
|
||||
extra_height = $double_sculpted ? extra_side_tilt_height(column) : 0;
|
||||
|
||||
base_depth = 3.5;
|
||||
if (n <= 1){
|
||||
$total_depth = base_depth + 2.5 + extra_height;
|
||||
$top_tilt = -13;
|
||||
|
||||
children();
|
||||
} else if (n == 2) {
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = -7;
|
||||
|
||||
children();
|
||||
} else if (n == 3) {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
} else if (n == 4){
|
||||
$total_depth = base_depth + 0.5 + extra_height;
|
||||
$top_tilt = 7;
|
||||
|
||||
children();
|
||||
} else {
|
||||
$total_depth = base_depth + extra_height;
|
||||
$top_tilt = 0;
|
||||
|
||||
children();
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,10 @@ module 1_5u() {
|
|||
u(1.5) children();
|
||||
}
|
||||
|
||||
module 1_75u(){
|
||||
u(1.75) children();
|
||||
}
|
||||
|
||||
module 2u() {
|
||||
u(2) children();
|
||||
}
|
||||
|
|
@ -25,6 +29,10 @@ module 2_25u() {
|
|||
u(2.25) children();
|
||||
}
|
||||
|
||||
module 2_50u() {
|
||||
u(2.5) children();
|
||||
}
|
||||
|
||||
module 2_75u() {
|
||||
u(2.75) children();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
// kind of a catch-all at this point for any directive that doesn't fit in the other files
|
||||
|
||||
//TODO duplicate def to not make this a special var. maybe not worth it
|
||||
unit = 19.05;
|
||||
include <constants.scad>
|
||||
|
||||
module translate_u(x=0, y=0, z=0){
|
||||
translate([x * unit, y*unit, z*unit]) children();
|
||||
translate([x * $unit, y*$unit, z*$unit]) children();
|
||||
}
|
||||
|
||||
module no_stem_support() {
|
||||
|
|
@ -92,30 +91,58 @@ module blank() {
|
|||
children();
|
||||
}
|
||||
|
||||
module cherry(slop) {
|
||||
$stem_slop = slop ? slop : $stem_slop;
|
||||
module cherry(slop = undef) {
|
||||
$stem_slop = slop != undef ? slop : $stem_slop;
|
||||
$stem_type = "cherry";
|
||||
children();
|
||||
}
|
||||
|
||||
module alps(slop) {
|
||||
$stem_slop = slop ? slop : $stem_slop;
|
||||
module alps(slop = undef) {
|
||||
$stem_slop = slop != undef ? slop : $stem_slop;
|
||||
$stem_type = "alps";
|
||||
children();
|
||||
}
|
||||
|
||||
module rounded_cherry(slop) {
|
||||
$stem_slop = slop ? slop : $stem_slop;
|
||||
module rounded_cherry(slop = undef) {
|
||||
$stem_slop = slop != undef ? slop : $stem_slop;
|
||||
$stem_type = "rounded_cherry";
|
||||
children();
|
||||
}
|
||||
|
||||
module box_cherry(slop) {
|
||||
$stem_slop = slop ? slop : $stem_slop;
|
||||
module box_cherry(slop = undef) {
|
||||
$stem_slop = slop != undef ? slop : $stem_slop;
|
||||
$stem_type = "box_cherry";
|
||||
children();
|
||||
}
|
||||
|
||||
module choc(slop = 0.05) {
|
||||
echo("WARN:\n\n * choc support is experimental.\n * $stem_slop is overridden.\n * it is also recommended to print them upside down if you can\n\n");
|
||||
$stem_throw = 3;
|
||||
$stem_slop = slop;
|
||||
|
||||
$bottom_key_width = 18;
|
||||
$bottom_key_height = 17;
|
||||
|
||||
$stem_type = "choc";
|
||||
children();
|
||||
}
|
||||
|
||||
// a hacky way to make "low profile" keycaps
|
||||
module low_profile() {
|
||||
$width_difference = $width_difference / 1.5;
|
||||
$height_difference = $height_difference / 1.5;
|
||||
// helps tilted keycaps not have holes if worst comes to worst
|
||||
$inner_shape_type = "dished";
|
||||
|
||||
$top_tilt = $top_tilt / 1.25;
|
||||
|
||||
$total_depth = ($total_depth / 2) < 7 ? 7 : $total_depth / 2;
|
||||
|
||||
// just to make sure
|
||||
$stem_throw = 3;
|
||||
children();
|
||||
}
|
||||
|
||||
module flared_support() {
|
||||
$support_type = "flared";
|
||||
children();
|
||||
|
|
@ -166,13 +193,68 @@ module upside_down() {
|
|||
}
|
||||
|
||||
module sideways() {
|
||||
$stem_support_type = "disable";
|
||||
$key_shape_type = "flat_sided_square";
|
||||
$dish_overdraw_width = abs(extra_keytop_length_for_flat_sides());
|
||||
extra_y_rotation = atan2($width_difference/2,$total_depth);
|
||||
extra_y_rotation = atan2($width_difference/2,$total_depth); // TODO assumes centered top
|
||||
translate([0,0,cos(extra_y_rotation) * total_key_width()/2])
|
||||
rotate([0,90 + extra_y_rotation ,0]) children();
|
||||
}
|
||||
|
||||
/* this is hard to explain. we want the angle of the back of the keycap.
|
||||
* first we draw a line at the back of the keycap perpendicular to the ground.
|
||||
* then we extend the line created by the slope of the keytop to that line
|
||||
* the angle of the latter line off the ground is $top_tilt, and
|
||||
* you can create a right triangle with the adjacent edge being $bottom_key_height/2
|
||||
* raised up $total_depth. this gets you x, the component of the extended
|
||||
* keytop slope line, and y, a component of the first perpendicular line.
|
||||
* by a very similar triangle you get r and s, where x is the hypotenuse of that
|
||||
* right triangle and the right angle is again against the first perpendicular line
|
||||
* s is the opposite line in the right triangle required to find q, the angle
|
||||
* of the back. if you subtract r from $total_depth plus y you can now use these
|
||||
* two values in atan to find the angle of interest.
|
||||
*/
|
||||
module backside() {
|
||||
$stem_support_type = "disable";
|
||||
|
||||
// $key_shape_type = "flat_sided_square";
|
||||
|
||||
a = $bottom_key_height;
|
||||
b = $total_depth;
|
||||
c = top_total_key_height();
|
||||
|
||||
x = (a / 2 - $top_skew) / cos(-$top_tilt) - c / 2;
|
||||
y = sin(-$top_tilt) * (x + c/2);
|
||||
r = sin(-$top_tilt) * x;
|
||||
s = cos(-$top_tilt) * x;
|
||||
|
||||
q = atan2(s, (y + b - r));
|
||||
|
||||
translate([0,0,cos(q) * total_key_height()/2])
|
||||
rotate([-90 - q, 0,0]) children();
|
||||
}
|
||||
|
||||
// this is just backside with a few signs switched
|
||||
module frontside() {
|
||||
$stem_support_type = "disable";
|
||||
|
||||
// $key_shape_type = "flat_sided_square";
|
||||
|
||||
a = $bottom_key_height;
|
||||
b = $total_depth;
|
||||
c = top_total_key_height();
|
||||
|
||||
x = (a / 2 + $top_skew) / cos($top_tilt) - c / 2;
|
||||
y = sin($top_tilt) * (x + c/2);
|
||||
r = sin($top_tilt) * x;
|
||||
s = cos($top_tilt) * x;
|
||||
|
||||
q = atan2(s, (y + b - r));
|
||||
|
||||
translate([0,0,cos(q) * total_key_height()/2])
|
||||
rotate([90 + q, 0,0]) children();
|
||||
}
|
||||
|
||||
// emulating the % modifier.
|
||||
// since we use custom colors, just using the % modifier doesn't work
|
||||
module debug() {
|
||||
|
|
@ -183,3 +265,26 @@ module debug() {
|
|||
|
||||
%children();
|
||||
}
|
||||
|
||||
// auto-place children in a grid.
|
||||
// For this to work all children have to be single keys, no for loops etc
|
||||
module auto_place() {
|
||||
num_children = $children;
|
||||
row_size = round(pow(num_children, 0.5));
|
||||
|
||||
for (child_index = [0:num_children-1]) {
|
||||
x = child_index % row_size;
|
||||
y = floor(child_index / row_size);
|
||||
translate_u(x,-y) children(child_index);
|
||||
}
|
||||
}
|
||||
|
||||
// suggested settings for resin prints
|
||||
module resin() {
|
||||
$stem_slop = 0;
|
||||
$stem_inner_slop = 0;
|
||||
$stem_support_type = "disable";
|
||||
$resin_suction_holes = true;
|
||||
$resin_drain_holes = true;
|
||||
children();
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
include <functions.scad>
|
||||
|
||||
module spacebar() {
|
||||
$inverted_dish = true;
|
||||
$dish_type = "sideways cylindrical";
|
||||
$inverted_dish = $dish_type != "disable";
|
||||
$dish_type = $dish_type != "disable" ? "sideways cylindrical" : "disable";
|
||||
6_25u() stabilized(mm=50) children();
|
||||
}
|
||||
|
||||
|
|
@ -50,13 +50,14 @@ module iso_enter() {
|
|||
/* $top_tilt = 0; */
|
||||
$stem_support_type = "disable";
|
||||
$key_shape_type = "iso_enter";
|
||||
/* $linear_extrude_shape = true; */
|
||||
$hull_shape_type = "skin";
|
||||
$linear_extrude_height_adjustment = 19.05 * 0.5;
|
||||
// this equals (unit_length(1.5) - unit_length(1.25)) / 2
|
||||
/* $dish_overdraw_width = 2.38125; */
|
||||
|
||||
|
||||
stabilized(vertical=true) {
|
||||
children();
|
||||
render() {
|
||||
stabilized(vertical=true) {
|
||||
children();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,5 @@ include <../layout.scad>
|
|||
];
|
||||
|
||||
module 60_percent_default(profile) {
|
||||
layout(60_percent_default_layout, profile, 60_percent_legends) children();
|
||||
layout(60_percent_default_layout, profile, 60_percent_legends, row_sculpting_offset=1) children();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
include <../layout.scad>
|
||||
|
||||
// negative numbers are used for spacing
|
||||
lets_split_mapping = [
|
||||
lets_split_layout = [
|
||||
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1],
|
||||
|
|
@ -9,5 +9,5 @@ lets_split_mapping = [
|
|||
];
|
||||
|
||||
module lets_split_default(profile) {
|
||||
layout(lets_split_mapping, profile, row_sculpting_offset=1) children();
|
||||
layout(lets_split_layout, profile, row_sculpting_offset=1) children();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
include <../functions.scad>
|
||||
|
||||
module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
|
||||
function p(x, y) = [ x, y, max(0,surface_function(x, y)) ];
|
||||
function p(x, y) = [ x, y, max(0,$surface_function(x, y)) ];
|
||||
function p0(x, y) = [ x, y, bottom ];
|
||||
function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
|
||||
function face(x, y) = [ p(x, y + step), p(x + step, y + step), p(x + step, y), p(x + step, y), p(x, y), p(x, y + step) ];
|
||||
|
|
@ -35,13 +35,13 @@ module 3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST
|
|||
polyhedron(points, faces, convexity = 8);
|
||||
}
|
||||
|
||||
module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SMALLEST_POSSIBLE){
|
||||
module polar_3d_surface(size, step, bottom=-SMALLEST_POSSIBLE){
|
||||
function to_polar(q, size) = q * (90 / size);
|
||||
|
||||
function p(x, y) = [
|
||||
surface_distribution_function(to_polar(x, size), size),
|
||||
surface_distribution_function(to_polar(y, size), size),
|
||||
max(0,surface_function(surface_distribution_function(to_polar(x, size), size), surface_distribution_function(to_polar(y, size), size)))
|
||||
$surface_distribution_function(to_polar(x, size), size),
|
||||
$surface_distribution_function(to_polar(y, size), size),
|
||||
max(0,$surface_function($surface_distribution_function(to_polar(x, size), size), $surface_distribution_function(to_polar(y, size), size)))
|
||||
];
|
||||
function p0(x, y) = [ x, y, bottom ];
|
||||
function rev(b, v) = b ? v : [ v[3], v[2], v[1], v[0] ];
|
||||
|
|
@ -75,5 +75,5 @@ module polar_3d_surface(size=$3d_surface_size, step=$3d_surface_step, bottom=-SM
|
|||
}
|
||||
|
||||
// defaults, overridden in functions.scad
|
||||
function surface_distribution_function(dim, size) = sin(dim) * size;
|
||||
function surface_function(x,y) = (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
|
||||
// $surface_distribution_function = function(dim, size) sin(dim) * size;
|
||||
// $surface_function = function(x,y) (sin(acos(x/$3d_surface_size))) * sin(acos(y/$3d_surface_size));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ $double_sculpt_radius = 200;
|
|||
$support_type = "flared"; // [flared, bars, flat, disable]
|
||||
|
||||
// Supports for the stem, as it often comes off during printing. Reccommended for most machines
|
||||
$stem_support_type = "tines"; // [tines, brim, disabled]
|
||||
$stem_support_type = "tines"; // [tines, brim, disable]
|
||||
|
||||
// make legends outset instead of inset.
|
||||
// broken off from artisan support since who wants outset legends?
|
||||
|
|
@ -74,14 +74,11 @@ $rounded_cherry_stem_d = 5.5;
|
|||
|
||||
// How much higher the stem is than the bottom of the keycap.
|
||||
// Inset stem requires support but is more accurate in some profiles
|
||||
// can be negative to make outset stems!
|
||||
$stem_inset = 0;
|
||||
// How many degrees to rotate the stems. useful for sideways keycaps, maybe
|
||||
$stem_rotation = 0;
|
||||
|
||||
// enable to have stem support extend past the keycap bottom, to (hopefully) the next
|
||||
// keycap. only works on tines right now
|
||||
$extra_long_stem_support = false;
|
||||
|
||||
/* [Shape] */
|
||||
|
||||
// Key shape type, determines the shape of the key. default is 'rounded square'
|
||||
|
|
@ -122,12 +119,10 @@ $font="DejaVu Sans Mono:style=Book";
|
|||
// Whether or not to render fake keyswitches to check clearances
|
||||
$clearance_check = false;
|
||||
// Should be faster, also required for concave shapes
|
||||
// Use linear_extrude instead of hull slices to make the shape of the key
|
||||
$linear_extrude_shape = false;
|
||||
|
||||
// warns in trajectory.scad but it looks benign
|
||||
// brand new, more correct, hopefully faster, lots more work
|
||||
$skin_extrude_shape = false;
|
||||
// what kind of extrusion we use to create the keycap. "hull" is standard, "linear extrude" is legacy, "skin" is new and not well supported.
|
||||
$hull_shape_type = "hull"; // ["hull", "linear extrude", "skin"]
|
||||
|
||||
// This doesn't work very well, but you can try
|
||||
$rounded_key = false;
|
||||
//minkowski radius. radius of sphere used in minkowski sum for minkowski_key function. 1.75 for G20
|
||||
|
|
@ -168,6 +163,9 @@ $inset_legend_depth = 0.2;
|
|||
// Dimensions of alps stem
|
||||
$alps_stem = [4.45, 2.25];
|
||||
|
||||
// Dimensions of choc stem
|
||||
$choc_stem = [1.2, 3];
|
||||
|
||||
// Enable stabilizer stems, to hold onto your cherry or costar stabilizers
|
||||
$stabilizer_type = "costar_stabilizer"; // [costar_stabilizer, cherry_stabilizer, disable]
|
||||
|
||||
|
|
@ -192,8 +190,60 @@ $warning_color = [1,0,0, 0.15];
|
|||
$minkowski_facets = 30;
|
||||
$shape_facets =30;
|
||||
|
||||
|
||||
|
||||
// "flat" / "dished" / "disable"
|
||||
$inner_shape_type = "flat";
|
||||
|
||||
// When sculpting sides using sculpted_square, how much in should the tops come
|
||||
$side_sculpting_factor = 4.5;
|
||||
// When sculpting corners, how much extra radius should be added
|
||||
$corner_sculpting_factor = 1;
|
||||
// When doing more side sculpting corners, how much extra radius should be added
|
||||
$more_side_sculpting_factor = 0.4;
|
||||
|
||||
// 3d surface functions (still in beta)
|
||||
|
||||
// 3d surface settings
|
||||
// unused for now
|
||||
$3d_surface_size = 100;
|
||||
// resolution in each axis. 10 = 10 divisions per x/y = 100 points total
|
||||
$3d_surface_step = 10;
|
||||
$3d_surface_size = 20;
|
||||
// resolution in each axis. 10 = 10 divisions per x/y = 100 points total.
|
||||
// 5 = 20 divisions per x/y
|
||||
$3d_surface_step = 1;
|
||||
|
||||
// monotonically increasing function that distributes the points of the surface mesh
|
||||
// only for polar_3d_surface right now
|
||||
// if it's linear it's a grid. sin(dim) * size concentrates detail around the edges
|
||||
sinusoidal_surface_distribution = function(dim,size) sin(dim) * size;
|
||||
linear_surface_distribution = function(dim,size) sin(dim) * size;
|
||||
|
||||
$surface_distribution_function = linear_surface_distribution;
|
||||
|
||||
// the function that actually determines what the surface is.
|
||||
// feel free to override, the last one wins
|
||||
|
||||
// debug
|
||||
// $surface_function = function(x,y) 1;
|
||||
cylindrical_surface = function(x,y) (sin(acos(x/$3d_surface_size)));
|
||||
spherical_surface = function(x,y) (1 - (x/$3d_surface_size)^2)^0.5 * (1 - (y/$3d_surface_size)^2)^0.5;
|
||||
// looks a lot like mt3
|
||||
quartic_surface = function(x,y) (1 - (x/$3d_surface_size)^4)^0.5 * (1 - (y/$3d_surface_size)^4)^0.5;
|
||||
ripple_surface = function(x,y) cos((x^2+y^2)^0.5 * 50)/4 + 0.75;
|
||||
rosenbrocks_banana_surface = function(x,y) (pow(1-(x/$3d_surface_size))^2 + 100 * pow((y/$3d_surface_size)-(x/$3d_surface_size)^2)^2)/200 + 0.1;
|
||||
spike_surface = function(x,y) 1/(((x/$3d_surface_size)^2+(y/$3d_surface_size)^2)^0.5) + .01;
|
||||
random_surface = function(x,y) sin(rands(0,90,1,x+y)[0]);
|
||||
bumps_surface = function(x,y) sin(20*x)*cos(20*y)/3+1;
|
||||
|
||||
$surface_function = bumps_surface; // bumps_surface;
|
||||
|
||||
// Resin subtractive features
|
||||
$resin_suction_holes = false;
|
||||
$resin_drain_holes = false;
|
||||
|
||||
// ripples
|
||||
/*
|
||||
// Rosenbrock's banana
|
||||
/* $
|
||||
// y=x revolved around the y axis
|
||||
/* $surface_function = */
|
||||
/* $surface_function = */
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
$fs=.1;
|
||||
unit = 19.05;
|
||||
|
||||
include <constants.scad>
|
||||
include <shapes/ISO_enter.scad>
|
||||
include <shapes/sculpted_square.scad>
|
||||
include <shapes/rounded_square.scad>
|
||||
include <shapes/square.scad>
|
||||
include <shapes/oblong.scad>
|
||||
include <shapes/regular_polygon.scad>
|
||||
|
||||
// size: at progress 0, the shape is supposed to be this size
|
||||
// delta: at progress 1, the keycap is supposed to be size - delta
|
||||
|
|
@ -25,6 +24,12 @@ module key_shape(size, delta, progress = 0) {
|
|||
square_shape(size, delta, progress);
|
||||
} else if ($key_shape_type == "oblong") {
|
||||
oblong_shape(size, delta, progress);
|
||||
} else if ($key_shape_type == "hexagon") {
|
||||
regular_polygon_shape(size, delta, progress);
|
||||
} else if ($key_shape_type == "octagon") {
|
||||
regular_polygon_shape(size, delta, progress, sides=8);
|
||||
} else if ($key_shape_type == "circular") {
|
||||
regular_polygon_shape(size, delta, progress, sides=36);
|
||||
} else {
|
||||
echo("Warning: unsupported $key_shape_type");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ width_ratio = unit_length(1.25) / unit_length(1.5);
|
|||
height_ratio = unit_length(1) / unit_length(2);
|
||||
|
||||
|
||||
|
||||
module ISO_enter_shape(size, delta, progress){
|
||||
width = size[0];
|
||||
height = size[1];
|
||||
|
|
@ -37,12 +38,12 @@ module ISO_enter_shape(size, delta, progress){
|
|||
}
|
||||
|
||||
function iso_enter_vertices(size, delta, progress, thickness_difference) = [
|
||||
[ 0-delta.x/2 * progress - thickness_difference/2, 0 - delta.y / 2 * progress - thickness_difference/2], // top right
|
||||
[ 0-delta.x/2 * progress - thickness_difference/2, -size[1] + delta.y / 2 * progress + thickness_difference/2], // bottom right
|
||||
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/2, -size[1] + delta.y / 2 * progress + thickness_difference/2], // bottom left
|
||||
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/2,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // inner middle point
|
||||
[ -size[0] + delta.x/2 * progress + thickness_difference/2,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // outer middle point
|
||||
[ -size[0] + delta.x/2 * progress + thickness_difference/2, 0 - delta.y / 2 * progress - thickness_difference/2] // top left
|
||||
[ 0-delta.x/2 * progress - thickness_difference/8, 0 - delta.y / 2 * progress - thickness_difference/8], // top right
|
||||
[ 0-delta.x/2 * progress - thickness_difference/8, -size[1] + delta.y / 2 * progress + thickness_difference/8], // bottom right
|
||||
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/8, -size[1] + delta.y / 2 * progress + thickness_difference/8], // bottom left
|
||||
[-size[0] * width_ratio + delta.x/2 * progress + thickness_difference/8,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // inner middle point
|
||||
[ -size[0] + delta.x/2 * progress + thickness_difference/8,-size[1] * height_ratio + delta.y / 2 * progress + thickness_difference/2], // outer middle point
|
||||
[ -size[0] + delta.x/2 * progress + thickness_difference/8, 0 - delta.y / 2 * progress - thickness_difference/8] // top left
|
||||
] + [
|
||||
[(size[0] * width_ratio)/2, size[1]/2 ],
|
||||
[(size[0] * width_ratio)/2, size[1]/2 ],
|
||||
|
|
|
|||
14
src/shapes/regular_polygon.scad
Normal file
14
src/shapes/regular_polygon.scad
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// we do this weird key_shape_type check here because rounded_square uses
|
||||
// square_shape, and we want flat sides to work for that too.
|
||||
// could be refactored, idk
|
||||
module regular_polygon_shape(size, delta, progress, sides=6){
|
||||
// https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/undersized_circular_objects
|
||||
fudge = 1/cos(180/sides);
|
||||
diameter = (size.x - delta.x * progress - $corner_radius*2) * fudge;
|
||||
offset(r=$corner_radius) rotate([0,0,360/sides/2]) circle(d = diameter, $fn=sides);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO not implemented
|
||||
function skin_regular_polygon_shape(size, delta, progress, thickness_difference, sides=6) = echo("skin regular polygon not implemented");
|
||||
|
|
@ -1,13 +1,5 @@
|
|||
// rounded square shape with additional sculpting functions to better approximate
|
||||
|
||||
// When sculpting sides, how much in should the tops come
|
||||
$side_sculpting_factor = 4.5;
|
||||
// When sculpting corners, how much extra radius should be added
|
||||
$corner_sculpting_factor = 1;
|
||||
// When doing more side sculpting corners, how much extra radius should be added
|
||||
$more_side_sculpting_factor = 0.4;
|
||||
|
||||
|
||||
// side sculpting functions
|
||||
// bows the sides out on stuff like SA and DSA keycaps
|
||||
function side_sculpting(progress) = (1 - progress) * $side_sculpting_factor;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ module brim_support(stem_type, stem_support_height, slop) {
|
|||
}
|
||||
}
|
||||
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
} else if (stem_type == "rounded_cherry") {
|
||||
difference() {
|
||||
cylinder(d=$rounded_cherry_stem_d * 2, h=stem_support_height);
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
} else if (stem_type == "box_cherry") {
|
||||
difference() {
|
||||
|
|
@ -31,7 +31,7 @@ module brim_support(stem_type, stem_support_height, slop) {
|
|||
}
|
||||
}
|
||||
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
} else if (stem_type == "cherry_stabilizer") {
|
||||
difference() {
|
||||
|
|
@ -41,7 +41,19 @@ module brim_support(stem_type, stem_support_height, slop) {
|
|||
}
|
||||
}
|
||||
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
} else if(stem_type == "choc") {
|
||||
translate([-5.7/2,0,0]) linear_extrude(height=stem_support_height) {
|
||||
offset(r=1){
|
||||
square($choc_stem + [3,3], center=true);
|
||||
}
|
||||
}
|
||||
|
||||
translate([5.7/2,0,0]) linear_extrude(height=stem_support_height) {
|
||||
offset(r=1){
|
||||
square($choc_stem + [3,3], center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,20 @@
|
|||
include <../functions.scad>
|
||||
include <../stems/cherry.scad>
|
||||
|
||||
/* NOTE: every reference to total_key_width and total_key_height
|
||||
* is multiplied by two in order to account for offset stems
|
||||
*/
|
||||
module centered_tines(stem_support_height) {
|
||||
if ($key_length < 2) {
|
||||
translate([0,0,$stem_support_height / 2]) {
|
||||
cube([total_key_width(), 0.5, $stem_support_height], center = true);
|
||||
cube([total_key_width()*2, 0.5, $stem_support_height], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
translate([0,0,$stem_support_height / 2]) {
|
||||
cube([
|
||||
1,
|
||||
total_key_height(),
|
||||
total_key_height()*2,
|
||||
$stem_support_height
|
||||
],
|
||||
center = true);
|
||||
|
|
@ -19,16 +22,13 @@ module centered_tines(stem_support_height) {
|
|||
}
|
||||
|
||||
module tines_support(stem_type, stem_support_height, slop) {
|
||||
extra_height = $extra_long_stem_support ? ($unit - total_key_height()) + 0.1 : -$wall_thickness/4; // fudge
|
||||
extra_width = $extra_long_stem_support ? ($unit - total_key_width()) + 0.1 : -$wall_thickness/4;
|
||||
|
||||
if (stem_type == "cherry" || stem_type == "costar_stabilizer") {
|
||||
difference () {
|
||||
union() {
|
||||
if ($key_length < 2) {
|
||||
translate([0,0,$stem_support_height / 2]) {
|
||||
cube([
|
||||
total_key_width() + extra_width*2,
|
||||
total_key_width()*2,
|
||||
0.5,
|
||||
$stem_support_height
|
||||
], center = true);
|
||||
|
|
@ -36,18 +36,18 @@ module tines_support(stem_type, stem_support_height, slop) {
|
|||
}
|
||||
|
||||
// 2 vertical tines holding either side of the cruciform
|
||||
for (x = [1.15, -1.15]) {
|
||||
for (x = [2, -2]) {
|
||||
translate([x,0,$stem_support_height / 2]) {
|
||||
cube([
|
||||
0.5,
|
||||
total_key_height() + extra_height*2, // this is to extend past
|
||||
total_key_height()*2, // this is to extend past
|
||||
$stem_support_height
|
||||
], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
} else if (stem_type == "cherry_stabilizer") {
|
||||
difference () {
|
||||
|
|
@ -55,7 +55,7 @@ module tines_support(stem_type, stem_support_height, slop) {
|
|||
translate([x,0,$stem_support_height / 2]) {
|
||||
cube([
|
||||
1,
|
||||
total_key_height($wall_thickness),
|
||||
total_key_height()*2,
|
||||
$stem_support_height
|
||||
], center = true);
|
||||
}
|
||||
|
|
@ -67,15 +67,19 @@ module tines_support(stem_type, stem_support_height, slop) {
|
|||
difference () {
|
||||
centered_tines(stem_support_height);
|
||||
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
} else if (stem_type == "rounded_cherry") {
|
||||
difference () {
|
||||
centered_tines(stem_support_height);
|
||||
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
} else if (stem_type == "alps"){
|
||||
centered_tines(stem_support_height);
|
||||
} else if (stem_type == "choc"){
|
||||
if ($key_length < 2) translate([0,0,$stem_support_height / 2]) cube([total_key_width(), 0.42, $stem_support_height], center = true);
|
||||
/* translate([-5.7/2,0,$stem_support_height / 2]) cube([0.5, total_key_height(), $stem_support_height], center = true); */
|
||||
/* translate([5.7/2,0,$stem_support_height / 2]) cube([0.5, total_key_height(), $stem_support_height], center = true); */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ include <stems/box_cherry.scad>
|
|||
include <stems/alps.scad>
|
||||
include <stems/filled.scad>
|
||||
include <stems/cherry_stabilizer.scad>
|
||||
include <stems/custom.scad>
|
||||
include <stems/choc.scad>
|
||||
|
||||
|
||||
//whole stem, alps or cherry, trimmed to fit
|
||||
|
|
@ -21,6 +21,8 @@ module stem(stem_type, depth, slop, throw){
|
|||
filled_stem();
|
||||
} else if (stem_type == "cherry_stabilizer") {
|
||||
cherry_stabilizer_stem(depth, slop, throw);
|
||||
} else if (stem_type == "choc") {
|
||||
choc_stem(depth, slop, throw);
|
||||
} else if (stem_type == "disable") {
|
||||
children();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ module box_cherry_stem(depth, slop, throw) {
|
|||
}
|
||||
|
||||
// inside cross
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ include <../functions.scad>
|
|||
|
||||
// extra length to the vertical tine of the inside cherry cross
|
||||
// splits the stem into halves - allows easier fitment
|
||||
extra_vertical = 0.6;
|
||||
extra_vertical = 100;
|
||||
|
||||
module inside_cherry_cross(slop) {
|
||||
// inside cross
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ include <../functions.scad>
|
|||
// splits the stem into halves - allows easier fitment
|
||||
extra_vertical = 0.6;
|
||||
|
||||
module inside_cherry_stabilizer_cross(slop) {
|
||||
module inside_cherry_stabilizer_cross(slop, throw) {
|
||||
// inside cross
|
||||
// translation purely for aesthetic purposes, to get rid of that awful lattice
|
||||
translate([0,0,-SMALLEST_POSSIBLE]) {
|
||||
linear_extrude(height = $stem_throw) {
|
||||
linear_extrude(height = throw) {
|
||||
square(cherry_cross(slop, extra_vertical)[0], center=true);
|
||||
square(cherry_cross(slop, extra_vertical)[1], center=true);
|
||||
}
|
||||
|
|
@ -24,6 +24,6 @@ module cherry_stabilizer_stem(depth, slop, throw) {
|
|||
}
|
||||
}
|
||||
|
||||
inside_cherry_stabilizer_cross(slop);
|
||||
inside_cherry_stabilizer_cross(slop, throw);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
src/stems/choc.scad
Normal file
17
src/stems/choc.scad
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
separation = 5.7;
|
||||
|
||||
positions = [
|
||||
[separation/2, 0],
|
||||
[-separation/2, 0],
|
||||
];
|
||||
|
||||
// TODO throw not used
|
||||
module choc_stem(depth, slop, throw){
|
||||
for (position=positions) {
|
||||
translate([position.x,position.y, depth/2]) single_choc_stem(depth, slop);
|
||||
}
|
||||
}
|
||||
|
||||
module single_choc_stem(depth, slop) {
|
||||
cube([$choc_stem.x - slop, $choc_stem.y - slop, depth], center=true);
|
||||
}
|
||||
|
|
@ -7,6 +7,6 @@ module rounded_cherry_stem(depth, slop, throw) {
|
|||
|
||||
// inside cross
|
||||
// translation purely for aesthetic purposes, to get rid of that awful lattice
|
||||
inside_cherry_cross(slop);
|
||||
inside_cherry_cross($stem_inner_slop);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,14 @@ module flared(stem_type, loft, height) {
|
|||
square(outer_cherry_stabilizer_stem($stem_slop) - [2,2], center=true);
|
||||
}
|
||||
}
|
||||
} else if (stem_type == "choc") {
|
||||
// single support, just the stem
|
||||
new_choc_scale = [scale_for_45(height, $choc_stem[0] + 5.7 - $stem_slop), scale_for_45(height, $choc_stem[1])];
|
||||
translate([0,0,0]) linear_extrude(height=height, scale = new_choc_scale){
|
||||
// TODO make a choc_stem() function so it can build in the slop
|
||||
square([$choc_stem[0] + 5.7 - $stem_slop, $choc_stem[1] - $stem_slop], center=true);
|
||||
}
|
||||
|
||||
} else {
|
||||
// always render cherry if no stem type. this includes stem_type = false!
|
||||
// this avoids a bug where the keycap is rendered filled when not desired
|
||||
|
|
|
|||
403
yarn.lock
403
yarn.lock
|
|
@ -45,11 +45,6 @@ ansi-regex@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
||||
|
||||
ansi-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
||||
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
|
||||
|
||||
ansi-styles@^4.1.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
|
||||
|
|
@ -78,24 +73,11 @@ append-buffer@^1.0.2:
|
|||
dependencies:
|
||||
buffer-equal "^1.0.0"
|
||||
|
||||
aproba@^1.0.3:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
|
||||
|
||||
archy@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
|
||||
integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
|
||||
|
||||
are-we-there-yet@~1.1.2:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
|
||||
integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
|
||||
dependencies:
|
||||
delegates "^1.0.0"
|
||||
readable-stream "^2.0.6"
|
||||
|
||||
arr-diff@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a"
|
||||
|
|
@ -308,6 +290,14 @@ cache-base@^1.0.1:
|
|||
union-value "^1.0.0"
|
||||
unset-value "^1.0.0"
|
||||
|
||||
call-bind@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
||||
integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.0.2"
|
||||
|
||||
camelcase@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
|
||||
|
|
@ -340,11 +330,6 @@ chokidar@^2.0.0:
|
|||
optionalDependencies:
|
||||
fsevents "^1.2.7"
|
||||
|
||||
chownr@^1.1.1:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
||||
|
||||
class-utils@^0.3.5:
|
||||
version "0.3.6"
|
||||
resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
|
||||
|
|
@ -447,11 +432,6 @@ concat-stream@^1.6.0:
|
|||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
||||
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
|
||||
|
||||
convert-source-map@^1.5.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
||||
|
|
@ -465,12 +445,12 @@ copy-descriptor@^0.1.0:
|
|||
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
|
||||
|
||||
copy-props@^2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.4.tgz#93bb1cadfafd31da5bb8a9d4b41f471ec3a72dfe"
|
||||
integrity sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2"
|
||||
integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==
|
||||
dependencies:
|
||||
each-props "^1.3.0"
|
||||
is-plain-object "^2.0.1"
|
||||
each-props "^1.3.2"
|
||||
is-plain-object "^5.0.0"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
|
|
@ -492,13 +472,6 @@ debug@^2.2.0, debug@^2.3.3:
|
|||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.2.6:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
decamelize@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
|
|
@ -509,11 +482,6 @@ decode-uri-component@^0.2.0:
|
|||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
||||
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
|
||||
|
||||
deep-extend@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||
|
||||
default-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f"
|
||||
|
|
@ -526,7 +494,7 @@ default-resolution@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684"
|
||||
integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=
|
||||
|
||||
define-properties@^1.1.2:
|
||||
define-properties@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
|
||||
|
|
@ -555,21 +523,11 @@ define-property@^2.0.2:
|
|||
is-descriptor "^1.0.2"
|
||||
isobject "^3.0.1"
|
||||
|
||||
delegates@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
|
||||
|
||||
detect-file@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
|
||||
integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
|
||||
|
||||
detect-libc@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
|
||||
|
||||
duplexify@^3.6.0:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
|
||||
|
|
@ -580,7 +538,7 @@ duplexify@^3.6.0:
|
|||
readable-stream "^2.0.0"
|
||||
stream-shift "^1.0.0"
|
||||
|
||||
each-props@^1.3.0:
|
||||
each-props@^1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333"
|
||||
integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==
|
||||
|
|
@ -802,13 +760,6 @@ fragment-cache@^0.2.1:
|
|||
dependencies:
|
||||
map-cache "^0.2.2"
|
||||
|
||||
fs-minipass@^1.2.5:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
|
||||
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
|
||||
dependencies:
|
||||
minipass "^2.6.0"
|
||||
|
||||
fs-mkdirp-stream@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb"
|
||||
|
|
@ -835,25 +786,20 @@ function-bind@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
||||
integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
|
||||
dependencies:
|
||||
aproba "^1.0.3"
|
||||
console-control-strings "^1.0.0"
|
||||
has-unicode "^2.0.0"
|
||||
object-assign "^4.1.0"
|
||||
signal-exit "^3.0.0"
|
||||
string-width "^1.0.1"
|
||||
strip-ansi "^3.0.1"
|
||||
wide-align "^1.1.0"
|
||||
|
||||
get-caller-file@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
|
||||
integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
|
||||
|
||||
get-intrinsic@^1.0.2:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
|
||||
integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
get-value@^2.0.3, get-value@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
||||
|
|
@ -895,7 +841,7 @@ glob-watcher@^5.0.3:
|
|||
just-debounce "^1.0.0"
|
||||
object.defaults "^1.1.0"
|
||||
|
||||
glob@^7.1.1, glob@^7.1.3:
|
||||
glob@^7.1.1:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
|
|
@ -1016,15 +962,10 @@ has-flag@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
has-symbols@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
|
||||
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
|
||||
|
||||
has-unicode@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
||||
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
|
||||
has-symbols@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
|
||||
integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
|
||||
|
||||
has-value@^0.3.1:
|
||||
version "0.3.1"
|
||||
|
|
@ -1057,6 +998,13 @@ has-values@^1.0.0:
|
|||
is-number "^3.0.0"
|
||||
kind-of "^4.0.0"
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
homedir-polyfill@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
|
||||
|
|
@ -1065,23 +1013,9 @@ homedir-polyfill@^1.0.1:
|
|||
parse-passwd "^1.0.0"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.8"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
|
||||
iconv-lite@^0.4.4:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
ignore-walk@^3.0.1:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
|
||||
integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
|
||||
dependencies:
|
||||
minimatch "^3.0.4"
|
||||
version "2.8.9"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
|
|
@ -1096,10 +1030,10 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
ini@^1.3.4, ini@~1.3.0:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
||||
ini@^1.3.4:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||
|
||||
interpret@^1.1.0:
|
||||
version "1.2.0"
|
||||
|
|
@ -1206,11 +1140,6 @@ is-fullwidth-code-point@^1.0.0:
|
|||
dependencies:
|
||||
number-is-nan "^1.0.0"
|
||||
|
||||
is-fullwidth-code-point@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||
|
||||
is-glob@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
|
||||
|
|
@ -1249,6 +1178,11 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
|||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
is-plain-object@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
|
||||
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
|
||||
|
||||
is-relative@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
|
||||
|
|
@ -1475,26 +1409,6 @@ minimatch@^3.0.4:
|
|||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.2.0, minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
|
||||
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
|
||||
dependencies:
|
||||
safe-buffer "^5.1.2"
|
||||
yallist "^3.0.0"
|
||||
|
||||
minizlib@^1.2.1:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
|
||||
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
|
||||
dependencies:
|
||||
minipass "^2.9.0"
|
||||
|
||||
mixin-deep@^1.2.0:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
|
||||
|
|
@ -1503,23 +1417,11 @@ mixin-deep@^1.2.0:
|
|||
for-in "^1.0.2"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
mkdirp@^0.5.0, mkdirp@^0.5.1:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
mute-stdout@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331"
|
||||
|
|
@ -1547,44 +1449,11 @@ nanomatch@^1.2.9:
|
|||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
needle@^2.2.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a"
|
||||
integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==
|
||||
dependencies:
|
||||
debug "^3.2.6"
|
||||
iconv-lite "^0.4.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
next-tick@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
||||
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
||||
|
||||
node-pre-gyp@*:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83"
|
||||
integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==
|
||||
dependencies:
|
||||
detect-libc "^1.0.2"
|
||||
mkdirp "^0.5.1"
|
||||
needle "^2.2.1"
|
||||
nopt "^4.0.1"
|
||||
npm-packlist "^1.1.6"
|
||||
npmlog "^4.0.2"
|
||||
rc "^1.2.7"
|
||||
rimraf "^2.6.1"
|
||||
semver "^5.3.0"
|
||||
tar "^4.4.2"
|
||||
|
||||
nopt@^4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
||||
integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
osenv "^0.1.4"
|
||||
|
||||
nopt@~1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
|
||||
|
|
@ -1621,47 +1490,11 @@ now-and-later@^2.0.0:
|
|||
dependencies:
|
||||
once "^1.3.2"
|
||||
|
||||
npm-bundled@^1.0.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
|
||||
integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
|
||||
dependencies:
|
||||
npm-normalize-package-bin "^1.0.1"
|
||||
|
||||
npm-normalize-package-bin@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
|
||||
integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
|
||||
|
||||
npm-packlist@^1.1.6:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
|
||||
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
|
||||
dependencies:
|
||||
ignore-walk "^3.0.1"
|
||||
npm-bundled "^1.0.1"
|
||||
npm-normalize-package-bin "^1.0.1"
|
||||
|
||||
npmlog@^4.0.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
||||
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
|
||||
dependencies:
|
||||
are-we-there-yet "~1.1.2"
|
||||
console-control-strings "~1.1.0"
|
||||
gauge "~2.7.3"
|
||||
set-blocking "~2.0.0"
|
||||
|
||||
number-is-nan@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
||||
|
||||
object-assign@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
object-copy@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
|
||||
|
|
@ -1671,7 +1504,7 @@ object-copy@^0.1.0:
|
|||
define-property "^0.2.5"
|
||||
kind-of "^3.0.3"
|
||||
|
||||
object-keys@^1.0.11, object-keys@^1.0.12:
|
||||
object-keys@^1.0.12, object-keys@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
|
||||
|
|
@ -1683,15 +1516,15 @@ object-visit@^1.0.0:
|
|||
dependencies:
|
||||
isobject "^3.0.0"
|
||||
|
||||
object.assign@^4.0.4:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
|
||||
integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
|
||||
object.assign@^4.0.4, object.assign@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
|
||||
integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
function-bind "^1.1.1"
|
||||
has-symbols "^1.0.0"
|
||||
object-keys "^1.0.11"
|
||||
call-bind "^1.0.0"
|
||||
define-properties "^1.1.3"
|
||||
has-symbols "^1.0.1"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
object.defaults@^1.0.0, object.defaults@^1.1.0:
|
||||
version "1.1.0"
|
||||
|
|
@ -1740,11 +1573,6 @@ ordered-read-streams@^1.0.0:
|
|||
dependencies:
|
||||
readable-stream "^2.0.1"
|
||||
|
||||
os-homedir@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
|
||||
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
|
||||
|
||||
os-locale@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
|
||||
|
|
@ -1752,19 +1580,6 @@ os-locale@^1.4.0:
|
|||
dependencies:
|
||||
lcid "^1.0.0"
|
||||
|
||||
os-tmpdir@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
||||
|
||||
osenv@^0.1.4:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
|
||||
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
|
||||
dependencies:
|
||||
os-homedir "^1.0.0"
|
||||
os-tmpdir "^1.0.0"
|
||||
|
||||
parse-filepath@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
|
||||
|
|
@ -1814,9 +1629,9 @@ path-is-absolute@^1.0.0:
|
|||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
path-root-regex@^0.1.0:
|
||||
version "0.1.2"
|
||||
|
|
@ -1914,16 +1729,6 @@ pumpify@^1.3.5:
|
|||
inherits "^2.0.3"
|
||||
pump "^2.0.0"
|
||||
|
||||
rc@^1.2.7:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
||||
dependencies:
|
||||
deep-extend "^0.6.0"
|
||||
ini "~1.3.0"
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
read-pkg-up@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
|
||||
|
|
@ -1950,7 +1755,7 @@ read-pkg@^1.0.0:
|
|||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||
readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||
|
|
@ -2075,14 +1880,7 @@ ret@~0.1.10:
|
|||
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
|
||||
|
||||
rimraf@^2.6.1:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
|
||||
safe-buffer@^5.1.0, safe-buffer@~5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
|
||||
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
|
||||
|
|
@ -2099,16 +1897,6 @@ safe-regex@^1.1.0:
|
|||
dependencies:
|
||||
ret "~0.1.10"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sax@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||
|
||||
semver-greatest-satisfied-range@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b"
|
||||
|
|
@ -2116,12 +1904,12 @@ semver-greatest-satisfied-range@^1.1.0:
|
|||
dependencies:
|
||||
sver-compat "^1.5.0"
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.3.0:
|
||||
"semver@2 || 3 || 4 || 5":
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
set-blocking@^2.0.0, set-blocking@~2.0.0:
|
||||
set-blocking@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||
|
|
@ -2136,11 +1924,6 @@ set-value@^2.0.0, set-value@^2.0.1:
|
|||
is-plain-object "^2.0.3"
|
||||
split-string "^3.0.1"
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||
|
||||
snapdragon-node@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||
|
|
@ -2262,14 +2045,6 @@ string-width@^1.0.1, string-width@^1.0.2:
|
|||
is-fullwidth-code-point "^1.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
"string-width@^1.0.2 || 2":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
|
||||
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
|
||||
dependencies:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
|
|
@ -2291,13 +2066,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
|||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
strip-ansi@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||
integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
strip-bom@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
|
||||
|
|
@ -2305,11 +2073,6 @@ strip-bom@^2.0.0:
|
|||
dependencies:
|
||||
is-utf8 "^0.2.0"
|
||||
|
||||
strip-json-comments@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
|
||||
|
|
@ -2325,19 +2088,6 @@ sver-compat@^1.5.0:
|
|||
es6-iterator "^2.0.1"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
tar@^4.4.2:
|
||||
version "4.4.13"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
||||
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
|
||||
dependencies:
|
||||
chownr "^1.1.1"
|
||||
fs-minipass "^1.2.5"
|
||||
minipass "^2.8.6"
|
||||
minizlib "^1.2.1"
|
||||
mkdirp "^0.5.0"
|
||||
safe-buffer "^5.1.2"
|
||||
yallist "^3.0.3"
|
||||
|
||||
through2-filter@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254"
|
||||
|
|
@ -2584,13 +2334,6 @@ which@^1.2.14:
|
|||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wide-align@^1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
|
||||
integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
|
||||
dependencies:
|
||||
string-width "^1.0.2 || 2"
|
||||
|
||||
wrap-ansi@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
|
||||
|
|
@ -2610,21 +2353,17 @@ xtend@~4.0.0, xtend@~4.0.1:
|
|||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
|
||||
|
||||
yallist@^3.0.0, yallist@^3.0.3:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
|
||||
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
|
||||
integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==
|
||||
|
||||
yargs-parser@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
|
||||
integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394"
|
||||
integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==
|
||||
dependencies:
|
||||
camelcase "^3.0.0"
|
||||
object.assign "^4.1.0"
|
||||
|
||||
yargs@^7.1.0:
|
||||
version "7.1.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue