├── CNAME ├── LICENSE ├── README.md ├── deploy ├── Gemfile.lock ├── LICENSE ├── css │ └── main.css ├── img │ ├── ErgoDox-original-min.png │ ├── bg.jpg │ ├── ceramic-min.jpg │ ├── diode-min.jpg │ ├── ergodox-logo.png │ ├── ergodox_ez.svg │ ├── ergodox_logo.png │ ├── gamepad0-min.jpg │ ├── gamepad1-min.jpg │ ├── gamepad2-min.jpg │ ├── gamepad3-min.jpg │ ├── gamepad4-min.jpg │ ├── gamepad5-min.jpg │ ├── teensy-min.jpg │ ├── th-diode-min.jpg │ ├── trrs-min.jpg │ ├── usb-min.jpg │ └── wiring-min.jpg ├── index.html ├── js │ ├── jquery-2.1.1.min.js │ ├── jquery.nav.js │ ├── jquery.scrollTo.js │ └── scripts.js ├── robots.txt └── sitemap.xml └── src ├── .gitignore ├── Gemfile.lock ├── LICENSE ├── _config.yml ├── _entries ├── assembly-2.md ├── assembly.md ├── case.md ├── credits.md ├── dactyl.md ├── electronics.md ├── ergodox-firmware.md ├── ez-config.md ├── ez.md ├── firmware.md ├── flash.md ├── gamepad.md ├── guide.md ├── infinity.md ├── intro.md ├── massdrop-config.md ├── parts.md ├── pcbs.md ├── qmk.md ├── tmk.md └── variants.md ├── _includes ├── fixed-banner.html ├── head.html ├── header.html └── nav.html ├── _layouts └── index.html ├── _sass ├── modules │ ├── _all.scss │ ├── _colors.scss │ ├── _functions.scss │ ├── _mixins.scss │ └── _typography.scss └── partials │ ├── _base.scss │ ├── _fixed-banner.scss │ ├── _general.scss │ ├── _header.scss │ ├── _nav.scss │ ├── _reset.scss │ └── _syntax.scss ├── css └── main.scss ├── img ├── ErgoDox-original-min.png ├── bg.jpg ├── ceramic-min.jpg ├── diode-min.jpg ├── ergodox-logo.png ├── ergodox_ez.svg ├── ergodox_logo.png ├── gamepad0-min.jpg ├── gamepad1-min.jpg ├── gamepad2-min.jpg ├── gamepad3-min.jpg ├── gamepad4-min.jpg ├── gamepad5-min.jpg ├── teensy-min.jpg ├── th-diode-min.jpg ├── trrs-min.jpg ├── usb-min.jpg └── wiring-min.jpg ├── index.html └── js ├── jquery-2.1.1.min.js ├── jquery.nav.js ├── jquery.scrollTo.js └── scripts.js /CNAME: -------------------------------------------------------------------------------- 1 | www.ergodox.io 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Attribution 4.0 International Public License 2 | 3 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 4 | 5 | Section 1 – Definitions. 6 | 7 | Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 8 | Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. 9 | Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 10 | Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 11 | Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 12 | Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 13 | Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 14 | Licensor means the individual(s) or entity(ies) granting rights under this Public License. 15 | Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 16 | Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 17 | You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. 18 | 19 | Section 2 – Scope. 20 | 21 | License grant. 22 | Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 23 | reproduce and Share the Licensed Material, in whole or in part; and 24 | produce, reproduce, and Share Adapted Material. 25 | Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 26 | Term. The term of this Public License is specified in Section 6(a). 27 | Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 28 | Downstream recipients. 29 | Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 30 | No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 31 | No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). 32 | 33 | Other rights. 34 | Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 35 | Patent and trademark rights are not licensed under this Public License. 36 | To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. 37 | 38 | Section 3 – License Conditions. 39 | 40 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 41 | 42 | Attribution. 43 | 44 | If You Share the Licensed Material (including in modified form), You must: 45 | retain the following if it is supplied by the Licensor with the Licensed Material: 46 | identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 47 | a copyright notice; 48 | a notice that refers to this Public License; 49 | a notice that refers to the disclaimer of warranties; 50 | a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 51 | indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 52 | indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 53 | You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 54 | If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 55 | If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. 56 | 57 | Section 4 – Sui Generis Database Rights. 58 | 59 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 60 | 61 | for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; 62 | if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and 63 | You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. 64 | 65 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 66 | 67 | Section 5 – Disclaimer of Warranties and Limitation of Liability. 68 | 69 | Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You. 70 | To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You. 71 | 72 | The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 73 | 74 | Section 6 – Term and Termination. 75 | 76 | This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 77 | 78 | Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 79 | automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 80 | upon express reinstatement by the Licensor. 81 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 82 | For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 83 | Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 84 | 85 | Section 7 – Other Terms and Conditions. 86 | 87 | The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 88 | Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 89 | 90 | Section 8 – Interpretation. 91 | 92 | For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 93 | To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 94 | No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 95 | Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 96 | ======= 97 | The MIT License (MIT) 98 | 99 | Copyright (c) 2015 DigitalMindCH 100 | 101 | Permission is hereby granted, free of charge, to any person obtaining a copy 102 | of this software and associated documentation files (the "Software"), to deal 103 | in the Software without restriction, including without limitation the rights 104 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 105 | copies of the Software, and to permit persons to whom the Software is 106 | furnished to do so, subject to the following conditions: 107 | 108 | The above copyright notice and this permission notice shall be included in all 109 | copies or substantial portions of the Software. 110 | 111 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 112 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 113 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 114 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 115 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 116 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 117 | SOFTWARE. 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [ergodox.io](http://www.ergodox.io) 2 | The new home of the ErgoDox project; an entirely open source, split hand, keyboard designed with ergonomics in mind. 3 | 4 | Site is built with [Jekyll](http://jekyllrb.com/) and themed with [Docster](http://digitalmindch.github.io/docster-jekyll-theme/) 5 | 6 | ##Repo Structure: 7 | Github page is served to http://www.ergodox.io from the /deploy directory and the source code to render is all inside of the /src directory. 8 | 9 | ## Prerequsities 10 | - jekyll 11 | - jekyll-seo-tag 12 | - jekyll-sitemap 13 | 14 | ## Building the site locally 15 | Once you have Jekyll installed, navigate to the /src directory and ```jekyll serve``` or ```jekyll build``` to either build and serve the site locally or just build the site. The rendered files will be put in the /deploy directory. 16 | 17 | ## Ready to push to the live site? 18 | `git subtree push --prefix deploy origin gh-pages` 19 | -------------------------------------------------------------------------------- /deploy/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.5.0) 5 | public_suffix (~> 2.0, >= 2.0.2) 6 | colorator (1.1.0) 7 | ffi (1.9.14) 8 | forwardable-extended (2.6.0) 9 | jekyll (3.3.0) 10 | addressable (~> 2.4) 11 | colorator (~> 1.0) 12 | jekyll-sass-converter (~> 1.0) 13 | jekyll-watch (~> 1.1) 14 | kramdown (~> 1.3) 15 | liquid (~> 3.0) 16 | mercenary (~> 0.3.3) 17 | pathutil (~> 0.9) 18 | rouge (~> 1.7) 19 | safe_yaml (~> 1.0) 20 | jekyll-sass-converter (1.4.0) 21 | sass (~> 3.4) 22 | jekyll-seo-tag (2.1.0) 23 | jekyll (~> 3.3) 24 | jekyll-sitemap (0.12.0) 25 | jekyll (~> 3.3) 26 | jekyll-watch (1.5.0) 27 | listen (~> 3.0, < 3.1) 28 | kramdown (1.12.0) 29 | liquid (3.0.6) 30 | listen (3.0.8) 31 | rb-fsevent (~> 0.9, >= 0.9.4) 32 | rb-inotify (~> 0.9, >= 0.9.7) 33 | mercenary (0.3.6) 34 | pathutil (0.14.0) 35 | forwardable-extended (~> 2.6) 36 | public_suffix (2.0.4) 37 | rb-fsevent (0.9.8) 38 | rb-inotify (0.9.7) 39 | ffi (>= 0.5.0) 40 | rouge (1.11.1) 41 | safe_yaml (1.0.4) 42 | sass (3.4.22) 43 | 44 | PLATFORMS 45 | ruby 46 | 47 | DEPENDENCIES 48 | jekyll-seo-tag 49 | jekyll-sitemap 50 | 51 | BUNDLED WITH 52 | 1.13.6 53 | -------------------------------------------------------------------------------- /deploy/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 DigitalMindCH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /deploy/css/main.css: -------------------------------------------------------------------------------- 1 | @import url("https://overpass-30e2.kxcdn.com/overpass.css");html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,.highlight pre,.highlight .hll,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}b,strong{font-weight:bold}i,em{font-style:italic}.fixed-banner{transition:0.3s ease-in-out transform;position:fixed;left:323px;right:0;bottom:0;width:calc(100% - 343px);background:#385958;padding:0 10px 10px !important;transform:translateY(150%);box-shadow:0px -6px 13px rgba(0,0,0,0.25)}.fixed-banner.show{transform:translateY(0)}.fixed-banner .detail{font-family:"Overpass",sans-serif;font-weight:900;font-size:14px;color:#FDFDFD;display:block;padding:7px 0 6px}.fixed-banner .close{font-family:"Overpass",sans-serif;font-size:18px;color:#FDFDFD;position:absolute;top:0;right:5px;cursor:pointer;transition:0.3s ease-in-out opacity}.fixed-banner .close:hover{opacity:0.8}.fixed-banner .wrapper{padding:10px;background:#FDFDFD;box-shadow:0 4px 4px rgba(0,0,0,0.25);border-radius:8px;display:flex;align-items:stretch}.fixed-banner .column{flex:0 1 608px}.fixed-banner .title{margin-bottom:6px;display:block;font-family:"Overpass",sans-serif;font-size:26px;color:#494949}.fixed-banner .link{transition:0.3s ease-in-out background;display:inline-flex;align-items:center;justify-content:center;width:304px;height:48px;max-width:100%;background:#E59620;box-shadow:0 2px 5px rgba(0,0,0,0.374);border-radius:7px;font-family:"Overpass",sans-serif;font-weight:700;font-size:26px;line-height:normal;color:#FDFDFD}.fixed-banner .link:hover{background:#bf7c1b}.fixed-banner .decoration{display:inline-block;margin:0 66px;flex:0 0 2px;width:2px;height:117px;background:#D7D7D7}.fixed-banner .display{flex:0 1 429px;display:inline-flex;align-items:center;justify-content:center}.fixed-banner img{display:block;max-width:100%;height:auto}@media (max-width: 1000px){.fixed-banner{left:0;width:calc(100% - 20px)}.fixed-banner .decoration{margin:0 20px}}@media (max-width: 667px){.fixed-banner .wrapper{flex-direction:column}.fixed-banner .detail{font-size:12px;padding:3px 0}.fixed-banner .decoration{display:none}.fixed-banner .display,.fixed-banner .column{flex:0 1 auto;text-align:center}.fixed-banner .title{font-size:14px}.fixed-banner img{width:150px;margin:0 auto 10px}.fixed-banner .link{width:304px;height:24px;font-size:14px;padding-top:1px}}.video_container iframe{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%}body{font-family:"Overpass",sans-serif;font-weight:300;font-size:22px;line-height:1.4;background:#FDFDFD;color:#121212}.container{max-width:100%;position:relative;margin:0 auto}.overview{width:320px;font-size:18px}.content{counter-reset:h1-counter;width:calc(100% - 320px);position:absolute;right:0}@media screen and (max-width: 1000px){.content{width:100%}}.content .toggle{position:absolute;top:5px;left:5px}section:last-of-type{padding-bottom:300px}section>p,section>ul,section>ol,section>div{text-align:justify;padding-left:5%;padding-right:5%;box-sizing:border-box}section pre,section .highlight pre,.highlight section pre,section .highlight .hll,.highlight section .hll{margin-left:5%;margin-right:5%}section>ol{padding-left:calc(5% + 40px)}h1,h2,h3,h4,h5,h6{text-transform:uppercase;font-weight:700;line-height:1;color:#385958}h1{font-size:3.1em;padding:30px 0 0;text-align:right;border-bottom:#385958 9px solid;width:100%;line-height:0.61;margin:0 0 20px}h1:before{content:counter(h1-counter) " "}.h1{counter-increment:h1-counter;counter-reset:h2-counter;padding-top:80px}h2{font-size:2em;padding:30px 0 0;width:90%;text-align:center;border-bottom:5px solid #385958;margin:0 auto 20px;line-height:0.63}h2:before{content:counter(h1-counter) "." counter(h2-counter) " "}.h2{counter-increment:h2-counter;counter-reset:h3-counter;padding-top:60px}h3{font-size:1.7em;padding:20px 0 0;width:90%;text-align:left;border-bottom:4px solid #385958;margin:0 auto 20px;line-height:0.65}h3:before{content:counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) " "}.h3{counter-increment:h3-counter;counter-reset:h4-counter;padding-top:40px}h4{font-size:1.5em;padding:18px 0 0;width:90%;text-align:left;border-bottom:3px solid #385958;margin:0 auto 18px;line-height:0.67}h4:before{content:counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) " "}.h4{counter-increment:h4-counter;counter-reset:h5-counter 1;padding-top:30px}h5{font-size:1.3em;padding:40px 0 0;width:90%;text-align:left;border-bottom:2px solid #385958;margin:0 auto 15px;line-height:0.68}h5:before{content:counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) "." counter(h5-counter) " "}a{transition:.3s all;color:#385958;text-decoration:none}.content a{border-bottom:#111a1a 1px solid;padding:0px 2px}.content a:hover{border-bottom:transparent 1px solid}a:hover{color:#111a1a}img{display:block;max-width:100%;margin:20px 0}code{font-family:'Overpass', 'Overpass-mono', monospace}.video_container{margin:30px auto;position:relative;width:90%;height:0;padding:51.3422818792% 0 0 0}#intro{padding-top:20px}code,pre,.highlight pre,.highlight .hll{white-space:pre-wrap;border-radius:0px;border:0}iframe{padding-left:5%;padding-right:5%;box-sizing:border-box;width:100%}p+p{margin-top:20px}header{background-size:auto;background-repeat:repeat;background-image:url(../img/bg.jpg);height:150px;text-align:center;position:relative;max-width:100%}header span{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%, -50%);-ms-transform:translate(-50%, -50%);transform:translate(-50%, -50%);color:#FDFDFD;text-transform:uppercase;font-weight:bold}.toggle:hover{cursor:pointer;opacity:.8}@media screen and (min-width: 1001px){.toggle{display:none}}.overview{position:fixed;top:0px;left:0px;height:100%;overflow-y:auto;transition:.3s all;background:#FDFDFD;border-right:3px solid #385958}@media screen and (max-width: 1000px){.overview{left:-320px;transition:.3s all ease;transform:translate(0, 0);z-index:100}.overview.open{transform:translate(320px, 0)}}.overview .toggle{position:absolute;top:5px;right:5px;z-index:100}.overview ul{list-style:none;counter-reset:nested-counter;padding-left:0}.overview ul li{counter-increment:nested-counter;font-size:98%}.overview #nav{width:100%;box-sizing:border-box}.overview #nav>li{border-bottom:1px solid rgba(56,89,88,0.3)}.overview #nav>li a{display:block;padding:10px 20px;line-height:1;border-bottom:1px solid rgba(56,89,88,0.2)}.overview #nav>li a:before{content:counters(nested-counter,".") " ";font-size:0}.overview #nav>li a:hover{background:rgba(56,89,88,0.1)}.overview #nav>li li a{padding:8px 30px}.overview #nav>li li li a{padding:6px 40px}.overview #nav>li li li li a{padding:4px 50px}.overview #nav .current>a:before{font-size:1em}.current>a{font-weight:700}#ezbanner{display:block;width:180px;margin-right:auto;margin-left:auto}pre,.highlight pre,.highlight .hll{background-color:#f8f8f8;padding:6px 10px;border-radius:2px;overflow-x:auto;font-size:.9em;margin:15px 0}.highlight .c,.highlight .cm,.highlight .c1{color:#998}.highlight .err,.highlight .gr,.highlight .gt{color:#a61717}.highlight .k,.highlight .o,.highlight .cp,.highlight .cs,.highlight .gs,.highlight .kc,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .gu,.highlight .ne,.highlight .nf,.highlight .ow{font-weight:bold}.highlight .cp,.highlight .cs,.highlight .gh{color:#999}.highlight .gd,.highlight .gd .x,.highlight .gi,.highlight .gi .x{color:black}.highlight .gd{background-color:#e3d2d2}.highlight .gd .x{background-color:#ffaaaa}.highlight .gi{background-color:#ddffdd}.highlight .gi .x{background-color:#aaffaa}.highlight .go{color:#888}.highlight .gp{color:#555}.highlight .gu{color:#800080}.highlight .kt{color:#445588;font-weight:bold}.highlight .m{color:#009999}.highlight .s{color:#385958}.highlight .n{color:#333}.highlight .na{color:teal}.highlight .nb{color:#0086b3}.highlight .nc{color:#445588;font-weight:bold}.highlight .no{color:teal}.highlight .ni{color:purple}.highlight .ne{color:#990000}.highlight .nf{color:#990000}.highlight .nn{color:#555555}.highlight .nt{color:navy}.highlight .nv{color:teal}.highlight .w{color:#bbbbbb}.highlight .mf{color:#009999}.highlight .mh{color:#009999}.highlight .mi{color:#009999}.highlight .mo{color:#009999}.highlight .sb{color:#dd1144}.highlight .sc{color:#dd1144}.highlight .sd{color:#dd1144}.highlight .s2{color:#385958}.highlight .se{color:#dd1144}.highlight .sh{color:#dd1144}.highlight .si{color:#dd1144}.highlight .sx{color:#dd1144}.highlight .sr{color:#009926}.highlight .s1{color:#dd1144}.highlight .ss{color:#990073}.highlight .bp{color:#999}.highlight .vc{color:teal}.highlight .vg{color:teal}.highlight .vi{color:teal}.highlight .il{color:#009999}.highlight .gc{color:#999;background-color:#EAF2F5} 2 | -------------------------------------------------------------------------------- /deploy/img/ErgoDox-original-min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/ErgoDox-original-min.png -------------------------------------------------------------------------------- /deploy/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/bg.jpg -------------------------------------------------------------------------------- /deploy/img/ceramic-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/ceramic-min.jpg -------------------------------------------------------------------------------- /deploy/img/diode-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/diode-min.jpg -------------------------------------------------------------------------------- /deploy/img/ergodox-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/ergodox-logo.png -------------------------------------------------------------------------------- /deploy/img/ergodox_ez.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deploy/img/ergodox_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/ergodox_logo.png -------------------------------------------------------------------------------- /deploy/img/gamepad0-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/gamepad0-min.jpg -------------------------------------------------------------------------------- /deploy/img/gamepad1-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/gamepad1-min.jpg -------------------------------------------------------------------------------- /deploy/img/gamepad2-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/gamepad2-min.jpg -------------------------------------------------------------------------------- /deploy/img/gamepad3-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/gamepad3-min.jpg -------------------------------------------------------------------------------- /deploy/img/gamepad4-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/gamepad4-min.jpg -------------------------------------------------------------------------------- /deploy/img/gamepad5-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/gamepad5-min.jpg -------------------------------------------------------------------------------- /deploy/img/teensy-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/teensy-min.jpg -------------------------------------------------------------------------------- /deploy/img/th-diode-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/th-diode-min.jpg -------------------------------------------------------------------------------- /deploy/img/trrs-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/trrs-min.jpg -------------------------------------------------------------------------------- /deploy/img/usb-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/usb-min.jpg -------------------------------------------------------------------------------- /deploy/img/wiring-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/deploy/img/wiring-min.jpg -------------------------------------------------------------------------------- /deploy/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ErgoDox Mechanical Keyboard 6 | 7 | 8 | 9 | 10 | 11 | 12 | index | ErgoDox Mechanical Keyboard 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | close 31 |
32 | ErgoDox Mechanical Keyboard 33 |
34 | 35 | 189 |
190 | 191 |
192 | open 193 | 194 | 195 | 196 |
197 | 198 |

The Keyboard

199 | 200 | 201 |

Ergodox is a keyboard project designed with ergonomics in mind, available either as a DIY kit or an assembled, commercial version. It uses 76-80 Cherry MX style mechanical switches (such as Cherry or Gateron) laid out in a columnar stagger (rather than the more conventional row stagger) layout with components that can easily be sourced. The keyboard is completely programmable and can be flashed with several different firmware options.

202 | 203 |

The entire project (including this website) is open source, allowing you the freedom to modify and tweak the project as you see fit.

204 | 205 |

Assembling this project will require some patience, soldering ability, and access to a computer to flash the firmware onto the keyboard.

206 | 207 |

Ergodox

208 | 209 | 210 |
211 | 212 | 213 | 214 |
215 | 216 |

Who built this?

217 | 218 | 219 |

The ErgoDox keyboard is a DIY keyboard project originally developed by “Dox” (Dominic Beauchamp) inspired by the Key64 Keyboard.

220 | 221 |

The printed circuit board was designed by “bpiphany” (Fredrik Atmer).

222 | 223 |

The original 3D printable case was designed by Dox but a far more popular and less expensive option was a layered acrylic design by litster.

224 | 225 |

The original firmware was designed by Ben Blazak.

226 | 227 |

The ErgoDox EZ was commercialized and manufactured by Erez Zukerman, Dmitry Slepov, and Yaara Lancet.

228 | 229 |

QMK Firmware which runs on the ErgoDox EZ was created by Jack Humbert, based on TMK.

230 | 231 |

This website was built by robotmaxtron with some help from the community as a way to centralize the documentation after ErgoDox.org went defunct. 232 | If you want to contribute to the project, pull requests, bugs (via Github issues) can be filed at our Github

233 | 234 |

Both the keyboard design and hardware files are licensed under the GNU Public License 3

235 | 236 |

GeekHack Thread

237 | 238 |
239 | 240 | 241 | 242 |
243 | 244 |

Guide

245 | 246 | 247 |

A few things will need to be decided in advance before choosing parts or cases. The ErgoDox supports either the standard 76 key or 80 key layout.

248 | 249 |

This project will require some tools such as a soldering iron, flush cutters, wire strippers, solder, and possibly a screwdriver.

250 | 251 |

The build guide also assumes that you already know how to solder, if you do not know how to solder or want a refresher there are several guides available on YouTube and other places on the internet.

252 | 253 | 254 |
255 | 256 | 257 | 258 |
259 | 260 |

Parts Needed

261 | 262 | 263 |

To build an ErgoDox, some readily available components will need to be procured.

264 | 265 |
    266 |
  • Some notes on the electronics before purchasing: 267 |
      268 |
    • The Cherry MX style switches can be either pcb or plate mounted.
    • 269 |
    • Either through hole or surface mount diodes can be used as the pcb supports both including in-switch through hole diodes.
    • 270 |
    • If the typical 3mm red leds are not used, be sure to replace the 220 Ω resistors with ones that match the leds chosen.
    • 271 |
    • PJRC sells a Teensy 2.0 both with and without header pins pre-installed. If you use a Teensy without the header pins pre-installed, you will need to obtain and install them.
    • 272 |
    • The pcb only supports currently three in switch LEDs on the inner colum of the right hand labeled LEDa, LEDb, and LEDc.
    • 273 |
    • Many if not all of the small components can be easily found online at vendors such as Mouser or Digikey.
    • 274 |
    275 |
  • 276 |
277 | 278 | 279 |
280 | 281 | 282 | 283 |
284 | 285 |

Printed Circuit Boards

286 | 287 | 288 |

The pcb files are available in a separate repo available here should you wish to modify and/or produce them.

289 | 290 |
    291 |
  • The latest revision of the pcbs can be purchased from the following vendors 292 | 295 |
  • 296 |
  • Several vendors are available who generally stock some of the older revisions of the pcbs. 297 | 301 |
  • 302 |
303 | 304 |

You could also buy the updated pcb from a vendor of choice by providing them the KiCad or Gerber files in the repo listed above or purchase a batch from OSH Park

305 | 306 |

Keep an eye out on the ErgoDox repo revision changelogs for updates and differences between pcb versions.

307 | 308 |
309 | 310 | 311 | 312 |
313 | 314 |

Small Electronics

315 | 316 | 317 |
    318 |
  • Full Parts list: 319 |
      320 |
    • 1x Pair of pcbs (one for each hand)
    • 321 |
    • 1x Teensy USB Board, Version 2.0
    • 322 |
    • 24x Teensy header pins, male (unless pre-installed)
    • 323 |
    • 1x MCP23018-E/SP I/O expander
    • 324 |
    • 76-80x Cherry MX switches, (depending on your layout)
    • 325 |
    • 76-80x 1N4148 diodes, SOD-123 package (Surface mount) or DO-35,(0.3” pitch) (through hole) (again, the amount needed will depend on your layout)
    • 326 |
    • 2x 2.2k Ω resistors (red, red, red)
    • 327 |
    • 3x 3mm T1 LEDs
    • 328 |
    • 3x 220 Ω resistors, or match to LED. (red, red, brown)
    • 329 |
    • 5x Short jumpers (You can also use the clipped off legs from your resistors)
    • 330 |
    • 1x 0.1 µF ceramic capacitor (marked “104” for 10*104 picofarad). Not strictly necessary but suggested
    • 331 |
    • 1x USB mini B connector WM17115
    • 332 |
    • 1x USB mini B plug with short cable (such as H2955)
    • 333 |
    • 1x USB cable male A to male mini B
    • 334 |
    • 2x 3.5 mm TRRS sockets, CP-43514. FC68129 will also work if its extra pins are snipped off
    • 335 |
    • 1x Cable with two 3.5 mm TRRS plugs
    • 336 |
    • 1x Ergodox Keyboard case
    • 337 |
    • 76-80x MX Keycaps
    • 338 |
    339 |
  • 340 |
341 | 342 | 343 |
344 | 345 | 346 | 347 |
348 | 349 |

Case & Keycaps

350 | 351 | 352 |

While there are many options of materials available (such as cases carved out of wood) generally ErgoDox cases are either 3D printed or layered acrylic sheets.

353 | 354 |

The 3D printable case options are available in our repo and have been uploaded to Shapeways

355 | 356 |

The most popular and less expensive option is the layered acrylic design. 357 | Github Repo assembled with m3 bolts.

358 | 359 |

There is also a 3D printable tenting stand in the repo organization. This will prop up the ErgoDox using Litster’s case at a very natural and comfortable angle.

360 | 361 |
    362 |
  • Like any mechanical keyboard, keycaps will need to be obtained. In a normal 76 key configuration the following keycaps will be needed: 363 |
      364 |
    • 12x 1.5u
    • 365 |
    • 4x 2u
    • 366 |
    • 60x 1u
    • 367 |
    368 |
  • 369 |
370 | 371 |

The 1.5u outer column keys can optionally be mounted closer in and 1u keycaps can be used.

372 | 373 |
Note: This layout is only supported on the newer (post 2012) revisions of the pcb and will require a modified plate design to support the new placement.
374 | 
375 | 376 |
    377 |
  • If the 80 key layout is used, a slightly different keycap configuration will be needed replacing the 2u keys with two 1u keys each: 378 |
      379 |
    • 12x 1.5u
    • 380 |
    • 68x 1u
    • 381 |
    382 |
  • 383 |
384 | 385 | 386 |
387 | 388 | 389 | 390 |
391 | 392 |

Assembly Guide

393 | 394 | 395 |

Now the section where the soldering and real assembly happens, in the next subsection there will be a couple external links to other build guides including both a photo and video build log.

396 | 397 |
    398 |
  1. Arrange the pcbs face down and solder in the diodes to this side. 399 |
      400 |
    • 1a. If surface mount diodes are chosen, place them on the small square copper pads but be sure to orient the diodes so that the line on the diode faces the square hole. The line on the diode indicates the cathode/negative side. Solder the diodes and repeat for each switch on both hands.
    • 401 |
    • diode
    • 402 |
    • 1b. If through hole diodes are chosen, place them through the two hole immediately to the left and right of copper pads under the square that the switch will take up. Be sure to check the orientation to be sure that the cathode/negative side of the diode is closest to the square hole. Solder and repeat for each switch on both hands.
    • 403 |
    • Through-hole diode 404 |
       Note: The additional holes in this second image are for through switch LEDs. Only one diode per switch is needed.
      405 | 
      406 |
    • 407 |
    408 |
  2. 409 |
  3. 410 |

    Flip both of the pcbs over, this face up side (without the diodes) will be the side that the remaining components will be placed.

    411 |
  4. 412 |
  5. Insert both the 2.2k ohm resistors and 220 ohm (or whatever resistors chosen appropriate for the leds selected) onto the right hand where labled on the pcb and solder into place. 413 |
    Note: Keep the legs clipped off the resistors, they can be used in a later step when the TRRS connections are installed.
    414 | 
    415 |
  6. 416 |
  7. On the left hand pcb, insert the I/O expander around the MCP23018 rectangle. The I/O expander is directional and the notch on the I/O expander should match up with the silkscreen. The notch on the expander will be facing ErgoDox printing on the circuit board. See the image in the next step for an example. 417 |
    Note: There are three holes without copper pads and do not need to be soldered.
    418 | 
    419 |
  8. 420 |
  9. (Optional but suggested step) On the left hand pcb, insert the ceramic capacitor into the first and third holes of the top row and solder in place. 421 |
      422 |
    • 5a. Bridge with solder the two copper pads immediately to the left of the ceramic capacitor.
    • 423 |
    • capacitor
    • 424 |
    425 |
  10. 426 |
  11. Insert either jumper wire or the legs clipped from the resistors bent into a U, into both of the the white pairs of holes on either side of where the 3.5mm connections will go and solder in place. 427 |
      428 |
    • 6a. Place 3.5mm connection, solder the 4 connection points.
    • 429 |
    • 6b. Repeat both the jumper and 3.5mm connectors on the other hand.
    • 430 |
    • trrs
    • 431 |
    432 |
  12. 433 |
  13. Install the male jumper pins to the underside of the Teensy with the button face up and solder the pins to the top side of the Teensy. 434 |
    Note: If the Teensy already has jumpers already installed, skip this step.
    435 | 
    436 |
  14. 437 |
  15. Insert the Teensy jumper legs from the Teensy assembly onto the right hand pcb with the usb facing the direction of the resistors and solder in place. 438 |
      439 |
    • teensy
    • 440 |
    441 |
  16. 442 |
  17. Cut one of the mini usb cables about 1.5” from the connector. 443 |
      444 |
    • 9a. Strip off all of the sheathing from the cable, exposing the 4 wires.
    • 445 |
    • 9b. Place the following wires into their respective holes: 446 |
      White: D-
      447 | Red:   5v
      448 | Green: D+
      449 | Black: GND
      450 | 
      451 |
    • 452 |
    • 9c. Solder wires to the pcb.
    • 453 |
    • wiring
    • 454 |
    455 |
  18. 456 |
  19. On the right hand, insert the mini usb connector into the holes marked on the pcb and solder into place. 457 |
      458 |
    • usb
    • 459 |
    460 |
  20. 461 |
  21. Prepare the chosen case. 462 |
      463 |
    • 11a. If the layered acrylic case design is being used, peel off the protective film off the acrylic pieces. 464 |
        465 |
      • Place the pcb under the 3rd acrylic layer and insert the switches into the acylic plate making sure that both pins from the switch are extending out through the pcb.
      • 466 |
      467 |
    • 468 |
    • 11b. If the 3D printed case is being used 469 |
        470 |
      • Place the pcb under the top section and push the switches into the case making sure that both pins from the switch are extending out through the pcb.
      • 471 |
      472 |
    • 473 |
    • 11c. Solder switches in place. 474 |
      Note: Make note of the location for the three switches on the right hand that will support the LEDs
      475 | 
      476 |
    • 477 |
    478 |
  22. 479 |
  23. On the right hand, insert the three leds through the housing of the three switches and solder into place. 480 |
    Note: LEDs have polarity so be sure that the negative leg (which is the shorter of the two legs) of the LEDs goes into the (face up) square hole.
    481 | 
    482 |
  24. 483 |
  25. Finish assembling the case, plug in the TRRS cable between the two halves and proceed to building and flashing the selected firmware.
  26. 484 |
485 | 486 | 487 |
488 | 489 | 490 | 491 |
492 | 493 |

Other Assembly Guides

494 | 495 | 496 |

External links to some popular guides to building the ErgoDox Keyboard

497 | 498 |

More the video type? YouTube has several other good guides, this one I think does an excellent job of balancing information and length.

499 | 500 |

Imgur Build Log: user robotmaxtron shares his build log (including mistakes).

501 | 502 | 503 |
504 | 505 | 506 | 507 |
508 | 509 |

Firmware Guide

510 | 511 | 512 |

There are a number of options for the firmware powering the ErgoDox keyboard, each with their own sets of features and options. Please consult the README guides for each firmware for specific instructions on how to use and compile it.

513 | 514 | 515 |
516 | 517 | 518 | 519 |
520 | 521 |

QMK

522 | 523 | 524 |

A build guide for compiling and customizing your firmware is best found in the repo’s readme

525 | 526 |
Note: There are many users who have committed their keymaps that can be built on and easily adapted to suit your needs.
527 | 
528 | 529 |

The ErgoDox-EZ Configurator tool can also be used to generate keymappings and their .hex files with QMK.

530 | 531 |

Homepage

532 | 533 | 534 |
535 | 536 | 537 | 538 |
539 | 540 |

ErgoDox-EZ Configurator

541 | 542 | 543 |

This is a powerful graphical configurator that lets you define layers, dual-function keys, LED control, and more without having to code.

544 | 545 |

The configurator is based on QMK and outputs QMK source code which can be used as a starting point for your own configuration/editing.

546 | 547 |

Homepage

548 | 549 | 550 |
551 | 552 | 553 | 554 |
555 | 556 |

TMK

557 | 558 | 559 |

The popular TMK firmware has also been ported to the ErgoDox.

560 | 561 |

Github Repo

562 | 563 |

Evan from TheVanKeyboards.com has built a TMK powered graphical configuration tool that supports the ErgoDox that can be used to create .hex files for flashing.

564 | 565 |

ErgoDox TMK Configurator

566 | 567 |
568 | 569 | 570 | 571 |
572 | 573 |

Original Ergodox Firmware

574 | 575 | 576 |

The originally designed firmware is also available, though somewhat fallen out of favor due to QMK and TMK’s improved functionalty and larger community support. The project has not had much movement since late 2015.

577 | 578 |

GitHub

579 | 580 | 581 |
582 | 583 | 584 | 585 |
586 | 587 |

Online Massdrop Configurator

588 | 589 | 590 |

Massdrop has developed an online tool for generating ErgoDox keymaps without the need to compile your own firmware, suggested for users who might not be comfortable compiling their own firmware.

591 | 592 |

The underlying firmware behind the graphical tool is based on the original firmware by Ben Blazak.

593 | 594 |

Homepage

595 | 596 | 597 |
598 | 599 | 600 | 601 |
602 | 603 |

Flashing your Ergodox

604 | 605 | 606 |

Once the firmware has been compiled down into a .hex file, it will need to be uploaded to the keyboard typically called flashing.

607 | 608 |
    609 |
  • Flashing your Ergodox is typically done with the Teensy Loader, and will be needed for the following guide. 610 |
      611 |
    1. Locate your .hex file generated by your firmware of choice
    2. 612 |
    3. Start the Teensy Loader program
    4. 613 |
    5. Load the .hex file into it.
    6. 614 |
    7. Press the Reset button by pressing the reset button onboard the Teensy, you may need to insert something such as a paperclip or small screwdriver gently into the reset hole in the top right corner of your case. 615 |
      Note: Some firmware (such as QMK and TMK) allow for the resetting of your atmel chip to be programmed as a keycode.
      616 | 
      617 |
    8. 618 |
    9. Click the button in the Teensy app to upload the firmware to your keyboard.
    10. 619 |
    620 |
  • 621 |
622 | 623 | 624 |
625 | 626 | 627 | 628 |
629 | 630 |

Variants

631 | 632 | 633 |

The open source nature of the ErgoDox has lead to several variants of the original design. The following list is not a comprehensive list, but does list many of the more popular designs.

634 | 635 | 636 |
637 | 638 | 639 | 640 |
641 | 642 |

Dactyl

643 | 644 | 645 |

Created by Matthew Adereth, the Dactyl Keyboard is a parameterized, split-hand, concave, columnar, ergonomic keyboard is an outstanding variation on the ErgoDox design.

646 | 647 |

dactyl

648 | 649 |

Build Guide for the brave (will be improved over time)

650 | 651 |

The case is uploaded to the things directory of the Dactyl repo and has been uploaded to Shapeways

652 | 653 |

Clojure/conj Talk on 3D Printing Keyboards: Adereth gave a very interesting talk on the history of keyboards and the creation of the very interesting shape of the Dactyl Keyboard.

654 | 655 |
    656 |
  • Differences between the ErgoDox and the Dactyl: 657 |
      658 |
    • 70 key layout, removes the inner column of keys.
    • 659 |
    • 1u outer column keys rather than the standard 1.5u
    • 660 |
    • Handwired or flexible pcb
    • 661 |
    • Concave shaped switch mounting
    • 662 |
    • No official firmware but several options available.
    • 663 |
    664 |
  • 665 |
666 | 667 |

GitHub Project Homepage

668 | 669 | 670 |
671 | 672 | 673 | 674 |
675 | 676 |

ErgoDox EZ

677 | 678 | 679 |

Another fork of the ErgoDox is a pre-built version with a case that supports legs that will allow you to ‘tent’ or angle the ErgoDox-EZ.

680 | 681 |
    682 |
  • Firmware: 683 | 688 |
  • 689 |
  • Differences between the original ErgoDox and the ErgoDox-EZ: 690 |
      691 |
    • Preassembled
    • 692 |
    • Custom-tooled case made from ABS plastic
    • 693 |
    • Two-year warranty
    • 694 |
    • Custom-built tilt/tent kit with metal legs that allow you to control the angle of the keyboard on your desk
    • 695 |
    • Custom-made wrist rest (wing) available
    • 696 |
    • Available with RGB LED case underglow
    • 697 |
    • As of January 2018, the ErgoDox-EZ now ships with hot swappable switches called CIY (Change It Yourself).
    • 698 |
    699 |
  • 700 |
701 | 702 |

Homepage

703 | 704 | 705 |
706 | 707 | 708 | 709 |
710 | 711 |

Infinity

712 | 713 | 714 |

Another variant of the ErgoDox is the ErgoDox Infinity developed by Input.club. This variant has added an LCD screen built into each half as well as a few other updates to the original design.

715 | 716 | 759 | 760 |

Homepage

761 | 762 | 763 |
764 | 765 | 766 | 767 |
768 | 769 |

Gamepad

770 | 771 | 772 |

User Profet23 of profetkeyboards.com has made some pcb updates that have been merged into the main pcb repo to allow for left hand only ErgoDox support. This is ideal as a gamepad or other single left-handed usage.

773 | 774 |

Gamepad

775 | 776 |

An example of the a finished build

777 | 778 |

Gamepad

779 | 780 |

The PCB has now has pads that support the installation of an optional reset switch. The Teensy 2.0 is actually installed upside down, the built in reset switch is not accessible. There is also an extra hole for the Teensy to solder a header pin for the reset switch.

781 | 782 |

Gamepad

783 | 784 |

The new “top” of PCB. Teensy is installed upside down. 2.2k resistors, jumpers, and USB port installed on top. In this revision of the PCB, the jumpers dictate which side the USB port can be installed on as well as the TRRS port (which isn’t used in gamepad configuration).

785 |
	Note: that the USB connection wires are installed (from left to right) empty, black, green, red, white. This is different from the silk screen layout as the usb port is now on "backwards".
786 | 
787 |

Gamepad

788 | 789 |

The new “bottom” of the PCB. The reset switch has been soldered to the bottom. LED resistors have also been soldered to bottom.

790 | 791 | 792 |
793 | 794 | 795 | 796 |
797 | 798 |
799 | X 800 | SPONSORED BY 801 |
802 |
803 | 804 |
805 | 806 |
807 |
Pre-assembled, improved, with a 2-year warranty.
808 | Customize yours today 809 |
810 |
811 |
812 | 813 |
814 | 815 | 816 | 817 | 818 | 819 | 820 | 828 | 829 | 830 | -------------------------------------------------------------------------------- /deploy/js/jquery.nav.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery One Page Nav Plugin 3 | * http://github.com/davist11/jQuery-One-Page-Nav 4 | * 5 | * Copyright (c) 2010 Trevor Davis (http://trevordavis.net) 6 | * Dual licensed under the MIT and GPL licenses. 7 | * Uses the same license as jQuery, see: 8 | * http://jquery.org/license 9 | * 10 | * @version 3.0.0 11 | * 12 | * Example usage: 13 | * $('#nav').onePageNav({ 14 | * currentClass: 'current', 15 | * changeHash: false, 16 | * scrollSpeed: 750 17 | * }); 18 | */ 19 | 20 | ;(function($, window, document, undefined){ 21 | 22 | // our plugin constructor 23 | var OnePageNav = function(elem, options){ 24 | this.elem = elem; 25 | this.$elem = $(elem); 26 | this.options = options; 27 | this.metadata = this.$elem.data('plugin-options'); 28 | this.$win = $(window); 29 | this.sections = {}; 30 | this.didScroll = false; 31 | this.$doc = $(document); 32 | this.docHeight = this.$doc.height(); 33 | }; 34 | 35 | // the plugin prototype 36 | OnePageNav.prototype = { 37 | defaults: { 38 | navItems: 'a', 39 | currentClass: 'current', 40 | changeHash: false, 41 | easing: 'swing', 42 | filter: '', 43 | scrollSpeed: 750, 44 | scrollThreshold: 0.5, 45 | begin: false, 46 | end: false, 47 | scrollChange: false 48 | }, 49 | 50 | init: function() { 51 | // Introduce defaults that can be extended either 52 | // globally or using an object literal. 53 | this.config = $.extend({}, this.defaults, this.options, this.metadata); 54 | 55 | this.$nav = this.$elem.find(this.config.navItems); 56 | 57 | //Filter any links out of the nav 58 | if(this.config.filter !== '') { 59 | this.$nav = this.$nav.filter(this.config.filter); 60 | } 61 | 62 | //Handle clicks on the nav 63 | this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this)); 64 | 65 | //Get the section positions 66 | this.getPositions(); 67 | 68 | //Handle scroll changes 69 | this.bindInterval(); 70 | 71 | //Update the positions on resize too 72 | this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this)); 73 | 74 | return this; 75 | }, 76 | 77 | adjustNav: function(self, $parent) { 78 | self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass); 79 | $parent.addClass(self.config.currentClass); 80 | }, 81 | 82 | bindInterval: function() { 83 | var self = this; 84 | var docHeight; 85 | 86 | self.$win.on('scroll.onePageNav', function() { 87 | self.didScroll = true; 88 | }); 89 | 90 | self.t = setInterval(function() { 91 | docHeight = self.$doc.height(); 92 | 93 | //If it was scrolled 94 | if(self.didScroll) { 95 | self.didScroll = false; 96 | self.scrollChange(); 97 | } 98 | 99 | //If the document height changes 100 | if(docHeight !== self.docHeight) { 101 | self.docHeight = docHeight; 102 | self.getPositions(); 103 | } 104 | }, 250); 105 | }, 106 | 107 | getHash: function($link) { 108 | return $link.attr('href').split('#')[1]; 109 | }, 110 | 111 | getPositions: function() { 112 | var self = this; 113 | var linkHref; 114 | var topPos; 115 | var $target; 116 | 117 | self.$nav.each(function() { 118 | linkHref = self.getHash($(this)); 119 | $target = $('#' + linkHref); 120 | 121 | if($target.length) { 122 | topPos = $target.offset().top; 123 | self.sections[linkHref] = Math.round(topPos); 124 | } 125 | }); 126 | }, 127 | 128 | getSection: function(windowPos) { 129 | var returnValue = null; 130 | var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold); 131 | 132 | for(var section in this.sections) { 133 | if((this.sections[section] - windowHeight) < windowPos) { 134 | returnValue = section; 135 | } 136 | } 137 | 138 | return returnValue; 139 | }, 140 | 141 | handleClick: function(e) { 142 | var self = this; 143 | var $link = $(e.currentTarget); 144 | var $parent = $link.parent(); 145 | var newLoc = '#' + self.getHash($link); 146 | 147 | if(!$parent.hasClass(self.config.currentClass)) { 148 | //Start callback 149 | if(self.config.begin) { 150 | self.config.begin(); 151 | } 152 | 153 | //Change the highlighted nav item 154 | self.adjustNav(self, $parent); 155 | 156 | //Removing the auto-adjust on scroll 157 | self.unbindInterval(); 158 | 159 | //Scroll to the correct position 160 | self.scrollTo(newLoc, function() { 161 | //Do we need to change the hash? 162 | if(self.config.changeHash) { 163 | window.location.hash = newLoc; 164 | } 165 | 166 | //Add the auto-adjust on scroll back in 167 | self.bindInterval(); 168 | 169 | //End callback 170 | if(self.config.end) { 171 | self.config.end(); 172 | } 173 | }); 174 | } 175 | 176 | e.preventDefault(); 177 | }, 178 | 179 | scrollChange: function() { 180 | var windowTop = this.$win.scrollTop(); 181 | var position = this.getSection(windowTop); 182 | var $parent; 183 | 184 | //If the position is set 185 | if(position !== null) { 186 | $parent = this.$elem.find('a[href$="#' + position + '"]').parent(); 187 | 188 | //If it's not already the current section 189 | if(!$parent.hasClass(this.config.currentClass)) { 190 | //Change the highlighted nav item 191 | this.adjustNav(this, $parent); 192 | 193 | //If there is a scrollChange callback 194 | if(this.config.scrollChange) { 195 | this.config.scrollChange($parent); 196 | } 197 | } 198 | } 199 | }, 200 | 201 | scrollTo: function(target, callback) { 202 | var offset = $(target).offset().top; 203 | 204 | $('html, body').animate({ 205 | scrollTop: offset 206 | }, this.config.scrollSpeed, this.config.easing, callback); 207 | }, 208 | 209 | unbindInterval: function() { 210 | clearInterval(this.t); 211 | this.$win.unbind('scroll.onePageNav'); 212 | } 213 | }; 214 | 215 | OnePageNav.defaults = OnePageNav.prototype.defaults; 216 | 217 | $.fn.onePageNav = function(options) { 218 | return this.each(function() { 219 | new OnePageNav(this, options).init(); 220 | }); 221 | }; 222 | 223 | })( jQuery, window , document ); 224 | -------------------------------------------------------------------------------- /deploy/js/jquery.scrollTo.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery.scrollTo 3 | * Copyright (c) 2007-2014 Ariel Flesler - afleslergmailcom | http://flesler.blogspot.com 4 | * Licensed under MIT 5 | * http://flesler.blogspot.com/2007/10/jqueryscrollto.html 6 | * @projectDescription Easy element scrolling using jQuery. 7 | * @author Ariel Flesler 8 | * @version 1.4.13 9 | */ 10 | ;(function (define) { 11 | 'use strict'; 12 | 13 | define(['jquery'], function ($) { 14 | 15 | var $scrollTo = $.scrollTo = function( target, duration, settings ) { 16 | return $(window).scrollTo( target, duration, settings ); 17 | }; 18 | 19 | $scrollTo.defaults = { 20 | axis:'xy', 21 | duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1, 22 | limit:true 23 | }; 24 | 25 | // Returns the element that needs to be animated to scroll the window. 26 | // Kept for backwards compatibility (specially for localScroll & serialScroll) 27 | $scrollTo.window = function( scope ) { 28 | return $(window)._scrollable(); 29 | }; 30 | 31 | // Hack, hack, hack :) 32 | // Returns the real elements to scroll (supports window/iframes, documents and regular nodes) 33 | $.fn._scrollable = function() { 34 | return this.map(function() { 35 | var elem = this, 36 | isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1; 37 | 38 | if (!isWin) 39 | return elem; 40 | 41 | var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem; 42 | 43 | return /webkit/i.test(navigator.userAgent) || doc.compatMode == 'BackCompat' ? 44 | doc.body : 45 | doc.documentElement; 46 | }); 47 | }; 48 | 49 | $.fn.scrollTo = function( target, duration, settings ) { 50 | if (typeof duration == 'object') { 51 | settings = duration; 52 | duration = 0; 53 | } 54 | if (typeof settings == 'function') 55 | settings = { onAfter:settings }; 56 | 57 | if (target == 'max') 58 | target = 9e9; 59 | 60 | settings = $.extend( {}, $scrollTo.defaults, settings ); 61 | // Speed is still recognized for backwards compatibility 62 | duration = duration || settings.duration; 63 | // Make sure the settings are given right 64 | settings.queue = settings.queue && settings.axis.length > 1; 65 | 66 | if (settings.queue) 67 | // Let's keep the overall duration 68 | duration /= 2; 69 | settings.offset = both( settings.offset ); 70 | settings.over = both( settings.over ); 71 | 72 | return this._scrollable().each(function() { 73 | // Null target yields nothing, just like jQuery does 74 | if (target == null) return; 75 | 76 | var elem = this, 77 | $elem = $(elem), 78 | targ = target, toff, attr = {}, 79 | win = $elem.is('html,body'); 80 | 81 | switch (typeof targ) { 82 | // A number will pass the regex 83 | case 'number': 84 | case 'string': 85 | if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) { 86 | targ = both( targ ); 87 | // We are done 88 | break; 89 | } 90 | // Relative/Absolute selector, no break! 91 | targ = win ? $(targ) : $(targ, this); 92 | if (!targ.length) return; 93 | case 'object': 94 | // DOMElement / jQuery 95 | if (targ.is || targ.style) 96 | // Get the real position of the target 97 | toff = (targ = $(targ)).offset(); 98 | } 99 | 100 | var offset = $.isFunction(settings.offset) && settings.offset(elem, targ) || settings.offset; 101 | 102 | $.each( settings.axis.split(''), function( i, axis ) { 103 | var Pos = axis == 'x' ? 'Left' : 'Top', 104 | pos = Pos.toLowerCase(), 105 | key = 'scroll' + Pos, 106 | old = elem[key], 107 | max = $scrollTo.max(elem, axis); 108 | 109 | if (toff) {// jQuery / DOMElement 110 | attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] ); 111 | 112 | // If it's a dom element, reduce the margin 113 | if (settings.margin) { 114 | attr[key] -= parseInt(targ.css('margin'+Pos)) || 0; 115 | attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0; 116 | } 117 | 118 | attr[key] += offset[pos] || 0; 119 | 120 | if(settings.over[pos]) 121 | // Scroll to a fraction of its width/height 122 | attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos]; 123 | } else { 124 | var val = targ[pos]; 125 | // Handle percentage values 126 | attr[key] = val.slice && val.slice(-1) == '%' ? 127 | parseFloat(val) / 100 * max 128 | : val; 129 | } 130 | 131 | // Number or 'number' 132 | if (settings.limit && /^\d+$/.test(attr[key])) 133 | // Check the limits 134 | attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max ); 135 | 136 | // Queueing axes 137 | if (!i && settings.queue) { 138 | // Don't waste time animating, if there's no need. 139 | if (old != attr[key]) 140 | // Intermediate animation 141 | animate( settings.onAfterFirst ); 142 | // Don't animate this axis again in the next iteration. 143 | delete attr[key]; 144 | } 145 | }); 146 | 147 | animate( settings.onAfter ); 148 | 149 | function animate( callback ) { 150 | $elem.animate( attr, duration, settings.easing, callback && function() { 151 | callback.call(this, targ, settings); 152 | }); 153 | } 154 | }).end(); 155 | }; 156 | 157 | // Max scrolling position, works on quirks mode 158 | // It only fails (not too badly) on IE, quirks mode. 159 | $scrollTo.max = function( elem, axis ) { 160 | var Dim = axis == 'x' ? 'Width' : 'Height', 161 | scroll = 'scroll'+Dim; 162 | 163 | if (!$(elem).is('html,body')) 164 | return elem[scroll] - $(elem)[Dim.toLowerCase()](); 165 | 166 | var size = 'client' + Dim, 167 | html = elem.ownerDocument.documentElement, 168 | body = elem.ownerDocument.body; 169 | 170 | return Math.max( html[scroll], body[scroll] ) - Math.min( html[size] , body[size] ); 171 | }; 172 | 173 | function both( val ) { 174 | return $.isFunction(val) || typeof val == 'object' ? val : { top:val, left:val }; 175 | } 176 | 177 | // AMD requirement 178 | return $scrollTo; 179 | }) 180 | }(typeof define === 'function' && define.amd ? define : function (deps, factory) { 181 | if (typeof module !== 'undefined' && module.exports) { 182 | // Node 183 | module.exports = factory(require('jquery')); 184 | } else { 185 | factory(jQuery); 186 | } 187 | })); 188 | -------------------------------------------------------------------------------- /deploy/js/scripts.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('#nav').onePageNav(); 3 | 4 | $('a[href^="http"]').attr('target','_blank'); 5 | 6 | $('.toggle').click(function(){ 7 | $('.overview').toggleClass('open'); 8 | }); 9 | 10 | fixedBanner() 11 | }); 12 | 13 | function fixedBanner() { 14 | var $banner = $('#fixedBanner'), 15 | cookieName = 'hideBanner' 16 | 17 | if (getCookie(cookieName) !== 'true') { 18 | $banner.addClass('show') 19 | } 20 | 21 | $banner.find('.close').click(function() { 22 | $banner.removeClass('show') 23 | setCookie(cookieName, true, 30) 24 | }) 25 | } 26 | function setCookie(cname, cvalue, exdays) { 27 | var d = new Date(); 28 | d.setTime(d.getTime() + (exdays*24*60*60*1000)); 29 | var expires = "expires="+ d.toUTCString(); 30 | document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 31 | } 32 | 33 | function getCookie(cname) { 34 | var name = cname + "="; 35 | var decodedCookie = decodeURIComponent(document.cookie); 36 | var ca = decodedCookie.split(';'); 37 | for(var i = 0; i 2 | 3 | 4 | http://localhost:4000/ 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | # https://git-scm.com/docs/gitignore 2 | # https://help.github.com/articles/ignoring-files 3 | # Example .gitignore files: https://github.com/github/gitignore 4 | /bower_components/ 5 | /node_modules/ 6 | /_site/ 7 | /.sass-cache/ 8 | /.jekyll-metadata 9 | /.brackets.json 10 | /Gemfile 11 | -------------------------------------------------------------------------------- /src/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.5.0) 5 | public_suffix (~> 2.0, >= 2.0.2) 6 | colorator (1.1.0) 7 | ffi (1.9.14) 8 | forwardable-extended (2.6.0) 9 | jekyll (3.3.0) 10 | addressable (~> 2.4) 11 | colorator (~> 1.0) 12 | jekyll-sass-converter (~> 1.0) 13 | jekyll-watch (~> 1.1) 14 | kramdown (~> 1.3) 15 | liquid (~> 3.0) 16 | mercenary (~> 0.3.3) 17 | pathutil (~> 0.9) 18 | rouge (~> 1.7) 19 | safe_yaml (~> 1.0) 20 | jekyll-sass-converter (1.4.0) 21 | sass (~> 3.4) 22 | jekyll-seo-tag (2.1.0) 23 | jekyll (~> 3.3) 24 | jekyll-sitemap (0.12.0) 25 | jekyll (~> 3.3) 26 | jekyll-watch (1.5.0) 27 | listen (~> 3.0, < 3.1) 28 | kramdown (1.12.0) 29 | liquid (3.0.6) 30 | listen (3.0.8) 31 | rb-fsevent (~> 0.9, >= 0.9.4) 32 | rb-inotify (~> 0.9, >= 0.9.7) 33 | mercenary (0.3.6) 34 | pathutil (0.14.0) 35 | forwardable-extended (~> 2.6) 36 | public_suffix (2.0.4) 37 | rb-fsevent (0.9.8) 38 | rb-inotify (0.9.7) 39 | ffi (>= 0.5.0) 40 | rouge (1.11.1) 41 | safe_yaml (1.0.4) 42 | sass (3.4.22) 43 | 44 | PLATFORMS 45 | ruby 46 | 47 | DEPENDENCIES 48 | jekyll-seo-tag 49 | jekyll-sitemap 50 | 51 | BUNDLED WITH 52 | 1.13.6 53 | -------------------------------------------------------------------------------- /src/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 DigitalMindCH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/_config.yml: -------------------------------------------------------------------------------- 1 | full_rebuild: true 2 | name: ErgoDox Mechanical Keyboard 3 | description: Documentation and build guide for the ErgoDox mechanical keyboard 4 | url: https://www.ergodox.io 5 | encoding: utf-8 6 | defaults: 7 | - 8 | values: 9 | layout: "index" 10 | markdown: kramdown 11 | kramdown: 12 | input: GFM 13 | relative_permalinks: false 14 | collections: 15 | - entries 16 | sass: 17 | sass_dir: _sass 18 | style: :compressed 19 | plugins: 20 | - jekyll-seo-tag 21 | - jekyll-sitemap 22 | exclude: [ 23 | .git, 24 | .gitignore, 25 | README.md, 26 | .sass-cache 27 | ] 28 | destination: ../deploy 29 | -------------------------------------------------------------------------------- /src/_entries/assembly-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: assemble-2 3 | sectionclass: h4 4 | parent-id: assemble 5 | title: Other Assembly Guides 6 | number: 2210 7 | --- 8 | External links to some popular guides to building the ErgoDox Keyboard 9 | 10 | [More the video type?](https://www.youtube.com/watch?v=x1irVrAl3Ts) YouTube has several other good guides, this one I think does an excellent job of balancing information and length. 11 | 12 | [Imgur Build Log](http://imgur.com/a/3riAB): user robotmaxtron shares his build log \(including mistakes\). 13 | 14 | -------------------------------------------------------------------------------- /src/_entries/assembly.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: assemble 3 | sectionclass: h2 4 | parent-id: guide 5 | is-parent: yes 6 | title: Assembly Guide 7 | number: 2200 8 | --- 9 | 10 | Now the section where the soldering and real assembly happens, in the next subsection there will be a couple external links to other build guides including both a photo and video build log. 11 | 12 | 1. Arrange the pcbs face down and solder in the diodes to this side. 13 | * 1a. If _surface mount_ diodes are chosen, place them on the small square copper pads but be sure to orient the diodes so that the line on the diode faces the square hole. The line on the diode indicates the cathode/negative side. Solder the diodes and repeat for each switch on both hands. 14 | * ![diode](../img/diode-min.jpg) 15 | * 1b. If _through hole_ diodes are chosen, place them through the two hole immediately to the left and right of copper pads under the square that the switch will take up. Be sure to check the orientation to be sure that the cathode/negative side of the diode is closest to the square hole. Solder and repeat for each switch on both hands. 16 | * ![Through-hole diode](../img/th-diode-min.jpg) 17 | ~~~ 18 | Note: The additional holes in this second image are for through switch LEDs. Only one diode per switch is needed. 19 | ~~~ 20 | 21 | 2. Flip both of the pcbs over, this face up side (without the diodes) will be the side that the remaining components will be placed. 22 | 23 | 3. Insert both the 2.2k ohm resistors and 220 ohm (or whatever resistors chosen appropriate for the leds selected) onto the right hand where labled on the pcb and solder into place. 24 | ~~~ 25 | Note: Keep the legs clipped off the resistors, they can be used in a later step when the TRRS connections are installed. 26 | ~~~ 27 | 28 | 4. On the left hand pcb, insert the I/O expander around the MCP23018 rectangle. The I/O expander is directional and the notch on the I/O expander should match up with the silkscreen. The notch on the expander will be facing ErgoDox printing on the circuit board. See the image in the next step for an example. 29 | ~~~ 30 | Note: There are three holes without copper pads and do not need to be soldered. 31 | ~~~ 32 | 33 | 5. _(Optional but suggested step)_ On the left hand pcb, insert the ceramic capacitor into the first and third holes of the top row and solder in place. 34 | * 5a. Bridge with solder the two copper pads immediately to the left of the ceramic capacitor. 35 | * ![capacitor](../img/ceramic-min.jpg) 36 | 37 | 6. Insert either jumper wire or the legs clipped from the resistors bent into a U, into both of the the white pairs of holes on either side of where the 3.5mm connections will go and solder in place. 38 | * 6a. Place 3.5mm connection, solder the 4 connection points. 39 | * 6b. Repeat both the jumper and 3.5mm connectors on the other hand. 40 | * ![trrs](../img/trrs-min.jpg) 41 | 42 | 7. Install the male jumper pins to the underside of the Teensy with the button face up and solder the pins to the top side of the Teensy. 43 | ~~~ 44 | Note: If the Teensy already has jumpers already installed, skip this step. 45 | ~~~ 46 | 47 | 48 | 8. Insert the Teensy jumper legs from the Teensy assembly onto the right hand pcb with the usb facing the direction of the resistors and solder in place. 49 | * ![teensy](../img/teensy-min.jpg) 50 | 51 | 9. Cut one of the mini usb cables about 1.5" from the connector. 52 | * 9a. Strip off all of the sheathing from the cable, exposing the 4 wires. 53 | * 9b. Place the following wires into their respective holes: 54 | ~~~ 55 | White: D- 56 | Red: 5v 57 | Green: D+ 58 | Black: GND 59 | ~~~ 60 | * 9c. Solder wires to the pcb. 61 | * ![wiring](../img/wiring-min.jpg) 62 | 63 | 10. On the right hand, insert the mini usb connector into the holes marked on the pcb and solder into place. 64 | * ![usb](../img/usb-min.jpg) 65 | 66 | 11. Prepare the chosen case. 67 | * 11a. If the layered acrylic case design is being used, peel off the protective film off the acrylic pieces. 68 | * Place the pcb under the 3rd acrylic layer and insert the switches into the acylic plate making sure that both pins from the switch are extending out through the pcb. 69 | * 11b. If the 3D printed case is being used 70 | * Place the pcb under the top section and push the switches into the case making sure that both pins from the switch are extending out through the pcb. 71 | * 11c. Solder switches in place. 72 | ~~~ 73 | Note: Make note of the location for the three switches on the right hand that will support the LEDs 74 | ~~~ 75 | 76 | 12. On the right hand, insert the three leds through the housing of the three switches and solder into place. 77 | ~~~ 78 | Note: LEDs have polarity so be sure that the negative leg (which is the shorter of the two legs) of the LEDs goes into the (face up) square hole. 79 | ~~~ 80 | 81 | 13. Finish assembling the case, plug in the TRRS cable between the two halves and proceed to building and flashing the selected firmware. 82 | 83 | -------------------------------------------------------------------------------- /src/_entries/case.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: case 3 | sectionclass: h4 4 | parent-id: parts 5 | number: 2130 6 | title: Case & Keycaps 7 | --- 8 | While there are many options of materials available (such as cases carved out of wood) generally ErgoDox cases are either 3D printed or layered acrylic sheets. 9 | 10 | The 3D printable case options are available in our [repo](https://github.com/Ergodox-io/ergodox-case) and have been uploaded to [Shapeways](http://www.shapeways.com/shops/Dox) 11 | 12 | The most popular and less expensive option is the layered acrylic design. 13 | [Github Repo](https://github.com/Ergodox-io/ErgoDox/tree/master/ErgoDox%20Acrylic%20Case) assembled with m3 bolts. 14 | 15 | There is also a 3D printable [tenting stand](https://github.com/Ergodox-io/ergodox-tent) in the repo organization. This will prop up the ErgoDox using Litster's case at a very natural and comfortable angle. 16 | 17 | 18 | - Like any mechanical keyboard, keycaps will need to be obtained. In a normal 76 key configuration the following keycaps will be needed: 19 | - 12x 1.5u 20 | - 4x 2u 21 | - 60x 1u 22 | 23 | The 1.5u outer column keys can optionally be mounted closer in and 1u keycaps can be used. 24 | 25 | Note: This layout is only supported on the newer (post 2012) revisions of the pcb and will require a modified plate design to support the new placement. 26 | 27 | - If the 80 key layout is used, a slightly different keycap configuration will be needed replacing the 2u keys with two 1u keys each: 28 | - 12x 1.5u 29 | - 68x 1u 30 | 31 | -------------------------------------------------------------------------------- /src/_entries/credits.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: credits 3 | sectionclass: h2 4 | parent-id: intro 5 | title: Who built this? 6 | is-parent: yes 7 | number: 1100 8 | --- 9 | The ErgoDox keyboard is a DIY keyboard project originally developed by "Dox" (Dominic Beauchamp) inspired by the [Key64 Keyboard](https://www.key64.org). 10 | 11 | The printed circuit board was designed by "bpiphany" (Fredrik Atmer). 12 | 13 | The original 3D printable case was designed by Dox but a far more popular and less expensive option was a layered acrylic design by litster. 14 | 15 | The original firmware was designed by Ben Blazak. 16 | 17 | The [ErgoDox EZ](http://ergodox-ez.com) was commercialized and manufactured by Erez Zukerman, Dmitry Slepov, and Yaara Lancet. 18 | 19 | [QMK Firmware](https://github.com/jackhumbert/qmk_firmware) which runs on the ErgoDox EZ was created by Jack Humbert, based on TMK. 20 | 21 | This website was built by robotmaxtron with some help from the community as a way to centralize the documentation after ErgoDox.org went defunct. 22 | If you want to contribute to the project, pull requests, bugs (via Github issues) can be filed at our [Github](https://github.com/Ergodox-io/ergodox-io) 23 | 24 | Both the keyboard design and hardware files are licensed under the GNU Public License 3 25 | 26 | [GeekHack Thread](https://geekhack.org/index.php?topic=22780.0) 27 | -------------------------------------------------------------------------------- /src/_entries/dactyl.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionclass: h2 3 | sectionid: dactyl 4 | parent-id: variants 5 | is-parent: yes 6 | number: 3100 7 | title: Dactyl 8 | --- 9 | Created by Matthew Adereth, the Dactyl Keyboard is a parameterized, split-hand, concave, columnar, ergonomic keyboard is an outstanding variation on the ErgoDox design. 10 | 11 | ![dactyl](https://raw.githubusercontent.com/adereth/dactyl-cave/master/resources/glamourshot.png) 12 | 13 | [Build Guide](https://github.com/adereth/dactyl-keyboard/blob/master/guide/README.org#wiring) for the brave (will be improved over time) 14 | 15 | The case is uploaded to the [things directory](https://github.com/adereth/dactyl-keyboard/blob/master/things) of the Dactyl repo and has been uploaded to [Shapeways](https://www.shapeways.com/shops/bespokeys) 16 | 17 | [Clojure/conj Talk on 3D Printing Keyboards](http://adereth.github.io/blog/2015/11/19/clojure-slash-conj-talk-on-3d-printing-keyboards/): Adereth gave a very interesting talk on the history of keyboards and the creation of the very interesting shape of the Dactyl Keyboard. 18 | 19 | - Differences between the ErgoDox and the Dactyl: 20 | - 70 key layout, removes the inner column of keys. 21 | - 1u outer column keys rather than the standard 1.5u 22 | - Handwired or flexible pcb 23 | - Concave shaped switch mounting 24 | - No official firmware but several options available. 25 | 26 | **[GitHub Project Homepage](https://github.com/adereth/dactyl-keyboard)** 27 | 28 | -------------------------------------------------------------------------------- /src/_entries/electronics.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: electronics 3 | sectionclass: h4 4 | parent-id: parts 5 | number: 2120 6 | title: Small Electronics 7 | --- 8 | 9 | - Full Parts list: 10 | - 1x Pair of pcbs (one for each hand) 11 | - 1x Teensy USB Board, Version 2.0 12 | - 24x Teensy header pins, male (unless pre-installed) 13 | - 1x MCP23018-E/SP I/O expander 14 | - 76-80x Cherry MX switches, (depending on your layout) 15 | - 76-80x 1N4148 diodes, SOD-123 package (Surface mount) or DO-35,(0.3" pitch) (through hole) (again, the amount needed will depend on your layout) 16 | - 2x 2.2k Ω resistors (red, red, red) 17 | - 3x 3mm T1 LEDs 18 | - 3x 220 Ω resistors, or match to LED. (red, red, brown) 19 | - 5x Short jumpers (You can also use the clipped off legs from your resistors) 20 | - 1x 0.1 µF ceramic capacitor (marked "104" for 10\*104 picofarad). Not strictly necessary but suggested 21 | - 1x USB mini B connector WM17115 22 | - 1x USB mini B plug with short cable (such as H2955) 23 | - 1x USB cable male A to male mini B 24 | - 2x 3.5 mm TRRS sockets, CP-43514. FC68129 will also work if its extra pins are snipped off 25 | - 1x Cable with two 3.5 mm TRRS plugs 26 | - 1x Ergodox Keyboard case 27 | - 76-80x MX Keycaps 28 | 29 | -------------------------------------------------------------------------------- /src/_entries/ergodox-firmware.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: ergodox-firmware 3 | sectionclass: h4 4 | parent-id: firmware 5 | number: 2304 6 | title: Original Ergodox Firmware 7 | --- 8 | The originally designed firmware is also available, though somewhat fallen out of favor due to QMK and TMK's improved functionalty and larger community support. The project has not had much movement since late 2015. 9 | 10 | **[GitHub](https://github.com/benblazak/ergodox-firmware)** 11 | 12 | -------------------------------------------------------------------------------- /src/_entries/ez-config.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: ez-config 3 | sectionclass: h4 4 | parent-id: firmware 5 | number: 2302 6 | title: ErgoDox-EZ Configurator 7 | --- 8 | 9 | This is a powerful graphical configurator that lets you define layers, dual-function keys, LED control, and more without having to code. 10 | 11 | The configurator is based on QMK and outputs QMK source code which can be used as a starting point for your own configuration/editing. 12 | 13 | **[Homepage](http://configure.ergodox-ez.com)** 14 | 15 | -------------------------------------------------------------------------------- /src/_entries/ez.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionclass: h2 3 | sectionid: ez 4 | parent-id: variants 5 | is-parent: yes 6 | number: 3200 7 | title: ErgoDox EZ 8 | --- 9 | Another fork of the ErgoDox is a pre-built version with a case that supports legs that will allow you to 'tent' or angle the ErgoDox-EZ. 10 | 11 | - Firmware: 12 | - [QMK](http://qmk.fm/) 13 | - [ErgoDox EZ Online Configurator](http://configure.ergodox-ez.com/keyboard_layouts/new) for graphically configuring layouts (no coding required) 14 | - [TMK](https://github.com/ErgoDox-EZ/reactor/blob/master/lib/firmware/TMK_README.md) 15 | 16 | - Differences between the original ErgoDox and the ErgoDox-EZ: 17 | - Preassembled 18 | - Custom-tooled case made from ABS plastic 19 | - Two-year warranty 20 | - Custom-built tilt/tent kit with metal legs that allow you to control the angle of the keyboard on your desk 21 | - Custom-made wrist rest (wing) available 22 | - Available with RGB LED case underglow 23 | - As of January 2018, the ErgoDox-EZ now ships with hot swappable switches called CIY (Change It Yourself). 24 | 25 | **[Homepage](https://ergodox-ez.com)** 26 | 27 | -------------------------------------------------------------------------------- /src/_entries/firmware.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: firmware 3 | sectionclass: h2 4 | parent-id: guide 5 | title: Firmware Guide 6 | is-parent: yes 7 | number: 2300 8 | --- 9 | There are a number of options for the firmware powering the ErgoDox keyboard, each with their own sets of features and options. Please consult the README guides for each firmware for specific instructions on how to use and compile it. 10 | 11 | -------------------------------------------------------------------------------- /src/_entries/flash.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: flashing 3 | sectionclass: h3 4 | parent-id: firmware 5 | number: 2320 6 | title: Flashing your Ergodox 7 | --- 8 | Once the firmware has been compiled down into a .hex file, it will need to be uploaded to the keyboard typically called flashing. 9 | 10 | - Flashing your Ergodox is typically done with the [Teensy Loader](https://www.pjrc.com/teensy/loader.html), and will be needed for the following guide. 11 | 1. Locate your .hex file generated by your firmware of choice 12 | 2. Start the Teensy Loader program 13 | 3. Load the .hex file into it. 14 | 4. Press the Reset button by pressing the reset button onboard the Teensy, you may need to insert something such as a paperclip or small screwdriver gently into the reset hole in the top right corner of your case. 15 | ~~~ 16 | Note: Some firmware (such as QMK and TMK) allow for the resetting of your atmel chip to be programmed as a keycode. 17 | ~~~ 18 | 5. Click the button in the Teensy app to upload the firmware to your keyboard. 19 | 20 | -------------------------------------------------------------------------------- /src/_entries/gamepad.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionclass: h2 3 | sectionid: infinity 4 | parent-id: variants 5 | is-parent: yes 6 | number: 3400 7 | title: Gamepad 8 | --- 9 | User Profet23 of [profetkeyboards.com](http://profetkeyboards.com) has made some pcb updates that have been merged into the main pcb repo to allow for left hand only ErgoDox support. This is ideal as a gamepad or other single left-handed usage. 10 | 11 | ![Gamepad](../img/gamepad0-min.jpg) 12 | 13 | An example of the a finished build 14 | 15 | ![Gamepad](../img/gamepad1-min.jpg) 16 | 17 | The PCB has now has pads that support the installation of an optional reset switch. The Teensy 2.0 is actually installed upside down, the built in reset switch is not accessible. There is also an extra hole for the Teensy to solder a header pin for the reset switch. 18 | 19 | ![Gamepad](../img/gamepad2-min.jpg) 20 | 21 | The new "top" of PCB. Teensy is installed upside down. 2.2k resistors, jumpers, and USB port installed on top. In this revision of the PCB, the jumpers dictate which side the USB port can be installed on as well as the TRRS port (which isn't used in gamepad configuration). 22 | ~~~ 23 | Note: that the USB connection wires are installed (from left to right) empty, black, green, red, white. This is different from the silk screen layout as the usb port is now on "backwards". 24 | ~~~ 25 | ![Gamepad](../img/gamepad4-min.jpg) 26 | 27 | The new "bottom" of the PCB. The reset switch has been soldered to the bottom. LED resistors have also been soldered to bottom. 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/_entries/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: guide 3 | sectionclass: h1 4 | is-parent: yes 5 | title: Guide 6 | number: 2000 7 | --- 8 | A few things will need to be decided in advance before choosing parts or cases. The ErgoDox supports either the standard 76 key or 80 key layout. 9 | 10 | This project will require some tools such as a soldering iron, flush cutters, wire strippers, solder, and possibly a screwdriver. 11 | 12 | The build guide also assumes that you already know how to solder, if you do not know how to solder or want a refresher there are several guides available on YouTube and other places on the internet. 13 | 14 | -------------------------------------------------------------------------------- /src/_entries/infinity.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionclass: h2 3 | sectionid: infinity 4 | parent-id: variants 5 | is-parent: yes 6 | number: 3300 7 | title: Infinity 8 | --- 9 | Another variant of the ErgoDox is the ErgoDox Infinity developed by Input.club. This variant has added an LCD screen built into each half as well as a few other updates to the original design. 10 | 11 | - Firmware options: 12 | - [QMK](http://qmk.fm/) 13 | - [TMK](https://github.com/tmk/infinity_ergodox) 14 | - [KLL Online Configurator](https://input.club/configurator-ergodox) 15 | 16 | - Cases: 17 | - [Offically Designed Case](https://github.com/kiibohd/case) 18 | - [Datamancer Infinity Hardwood Case](https://www.massdrop.com/buy/datamancer-infinity-ergodox-hardwood-case) 19 | 20 | - Printed Circuit Board: 21 | - [Github PCB Repo](https://github.com/kiibohd/pcb) 22 | 23 | - Guides: 24 | - [Official Build Guide](https://input.club/devices/infinity-ergodox/infinity-ergodox-build-guide/) 25 | - Reddit user keredomo has put together a set of Linux guides 26 | 1. [The Infinity Ergodox: A Linux Guide](https://www.reddit.com/r/MechanicalKeyboards/comments/5bjdxe/guide_the_infinity_ergodox_a_linux_guide/) 27 | 2. [Modifying Firmware for Advanced Macros](https://www.reddit.com/r/MechanicalKeyboards/comments/5bjtt8/guide_infinity_ergodox_linux_guide_modifying/) 28 | 3. [Altering the Default LCD Screen](https://www.reddit.com/r/MechanicalKeyboards/comments/5coiu8/guide_infinity_ergodox_linux_guide_altering_the/) 29 | 30 | - Differences between the original ErgoDox and the Infinity: 31 | - Full In-switch backlighting 32 | - USB-C replaces TRRS between the two halves 33 | - Each half can be used independently 34 | - Pre-soldered smd components, only switches and LEDs will need to be soldered 35 | - LCD screens on each keyboard half 36 | - Proper costar stabilizer support 37 | - ALPS switch support 38 | 39 | **[Homepage](https://input.club/devices/infinity-ergodox/)** 40 | 41 | -------------------------------------------------------------------------------- /src/_entries/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: intro 3 | sectionclass: h1 4 | title: The Keyboard 5 | is-parent: yes 6 | number: 1000 7 | --- 8 | Ergodox is a keyboard project designed with ergonomics in mind, available either as a DIY kit or an [assembled, commercial version](http://ergodox-ez.com). It uses 76-80 Cherry MX style mechanical switches (such as Cherry or Gateron) laid out in a columnar stagger (rather than the more conventional row stagger) layout with components that can easily be sourced. The keyboard is completely programmable and can be flashed with several different firmware options. 9 | 10 | The entire project (including this website) is open source, allowing you the freedom to modify and tweak the project as you see fit. 11 | 12 | Assembling this project will require some patience, soldering ability, and access to a computer to flash the firmware onto the keyboard. 13 | 14 | ![Ergodox](../img/ErgoDox-original-min.png) 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/_entries/massdrop-config.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: massdrop-config 3 | sectionclass: h4 4 | parent-id: firmware 5 | number: 2304 6 | title: Online Massdrop Configurator 7 | --- 8 | Massdrop has developed an online tool for generating ErgoDox keymaps without the need to compile your own firmware, suggested for users who might not be comfortable compiling their own firmware. 9 | 10 | The underlying firmware behind the graphical tool is based on the original firmware by Ben Blazak. 11 | 12 | **[Homepage](https://www.massdrop.com/configurator/ergodox)** 13 | 14 | -------------------------------------------------------------------------------- /src/_entries/parts.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: parts 3 | sectionclass: h2 4 | parent-id: guide 5 | is-parent: yes 6 | title: Parts Needed 7 | number: 2100 8 | --- 9 | To build an ErgoDox, some readily available components will need to be procured. 10 | 11 | - Some notes on the electronics before purchasing: 12 | - The Cherry MX style switches can be either pcb or plate mounted. 13 | - Either through hole or surface mount diodes can be used as the pcb supports both including in-switch through hole diodes. 14 | - If the typical 3mm red leds are not used, be sure to replace the 220 Ω resistors with ones that match the leds chosen. 15 | - PJRC sells a Teensy 2.0 both with and without header pins pre-installed. If you use a Teensy without the header pins pre-installed, you will need to obtain and install them. 16 | - The pcb only supports currently three in switch LEDs on the inner colum of the right hand labeled LEDa, LEDb, and LEDc. 17 | - Many if not all of the small components can be easily found online at vendors such as Mouser or Digikey. 18 | 19 | -------------------------------------------------------------------------------- /src/_entries/pcbs.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: pcbs 3 | sectionclass: h4 4 | parent-id: parts 5 | number: 2110 6 | title: Printed Circuit Boards 7 | --- 8 | The pcb files are available in a separate repo available [here](https://github.com/Ergodox-io/ErgoDox) should you wish to modify and/or produce them. 9 | 10 | * The latest revision of the pcbs can be purchased from the following vendors 11 | * [ProfetKeyboards.com](http://shop.profetkeyboards.com/product/ergodox-pcbs) 12 | 13 | * Several vendors are available who generally stock some of the older revisions of the pcbs. 14 | * [MechanicalKeyboards.com](https://mechanicalkeyboards.com/shop/index.php?l=product_detail&p=537) 15 | * [Falbatech.pl](http://falbatech.pl/prestashop/index.php?id_product=10&controller=product&id_lang=2) 16 | 17 | You could also buy the updated pcb from a vendor of choice by providing them the KiCad or Gerber files in the repo listed above or purchase a batch from OSH Park 18 | 19 | Keep an eye out on the ErgoDox repo [revision](https://github.com/Ergodox-io/ErgoDox/releases) changelogs for updates and differences between pcb versions. 20 | -------------------------------------------------------------------------------- /src/_entries/qmk.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: qmk 3 | sectionclass: h4 4 | parent-id: firmware 5 | number: 2301 6 | title: QMK 7 | --- 8 | A build guide for compiling and customizing your firmware is best found in the repo's [readme](https://github.com/jackhumbert/qmk_firmware) 9 | 10 | Note: There are many users who have committed their keymaps that can be built on and easily adapted to suit your needs. 11 | 12 | The ErgoDox-EZ Configurator tool can also be used to generate keymappings and their .hex files with QMK. 13 | 14 | **[Homepage](http://qmk.fm/keyboards/ergodox/)** 15 | 16 | -------------------------------------------------------------------------------- /src/_entries/tmk.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionid: tmk 3 | sectionclass: h4 4 | parent-id: firmware 5 | number: 2303 6 | title: TMK 7 | --- 8 | The popular TMK firmware has also been ported to the ErgoDox. 9 | 10 | **[Github Repo](https://github.com/cub-uanic/tmk_keyboard/tree/master/keyboard/ergodox)** 11 | 12 | Evan from TheVanKeyboards.com has built a TMK powered graphical configuration tool that supports the ErgoDox that can be used to create .hex files for flashing. 13 | 14 | **[ErgoDox TMK Configurator](http://minivan.config.thevankeyboards.com/)** 15 | -------------------------------------------------------------------------------- /src/_entries/variants.md: -------------------------------------------------------------------------------- 1 | --- 2 | sectionclass: h1 3 | sectionid: variants 4 | is-parent: yes 5 | title: Variants 6 | number: 3000 7 | --- 8 | The open source nature of the ErgoDox has lead to several variants of the original design. The following list is not a comprehensive list, but does list many of the more popular designs. 9 | 10 | -------------------------------------------------------------------------------- /src/_includes/fixed-banner.html: -------------------------------------------------------------------------------- 1 |
2 | X 3 | SPONSORED BY 4 |
5 |
6 | 7 |
8 | 9 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /src/_includes/head.html: -------------------------------------------------------------------------------- 1 | 2 | {{ site.name }} 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/_includes/header.html: -------------------------------------------------------------------------------- 1 |
2 | {{ site.name }} {{ site.author }} {{ site.version }} 3 |
4 | -------------------------------------------------------------------------------- /src/_includes/nav.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/_layouts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include head.html %} 5 | {% seo %} 6 | 7 | 8 | 9 |
10 |
11 | close 12 | {% include header.html %} 13 | {% include nav.html %} 14 |
15 | 16 |
17 | open 18 | {{ content }} 19 |
20 | 21 | {% include fixed-banner.html %} 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/_sass/modules/_all.scss: -------------------------------------------------------------------------------- 1 | @import "colors"; 2 | @import "typography"; 3 | @import "functions"; 4 | @import "mixins"; 5 | @import "partials/fixed-banner"; -------------------------------------------------------------------------------- /src/_sass/modules/_colors.scss: -------------------------------------------------------------------------------- 1 | $white: #FDFDFD; 2 | $black: #121212; 3 | 4 | $darkgray: #333; 5 | $mediumgray: #C7C6C5; 6 | $lightgray: #e3e3e3; 7 | 8 | $gray: #5e5e5e; 9 | $green: #385958; 10 | $darkgreen: darken($green, 20%); 11 | -------------------------------------------------------------------------------- /src/_sass/modules/_functions.scss: -------------------------------------------------------------------------------- 1 | @function set-button-shadow($c){ 2 | @if (lightness($c) >= 70) { 3 | @return 8%; 4 | } 5 | 6 | @if (lightness($c) <= 69){ 7 | @return 14%; 8 | } 9 | 10 | @if (lightness($c) <= 30) { 11 | @return 27%; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/_sass/modules/_mixins.scss: -------------------------------------------------------------------------------- 1 | //Mixins 2 | @mixin flexbox($direction, $wrap, $justify, $align){ 3 | display: flex; 4 | flex-direction: $direction; 5 | flex-wrap: $wrap; 6 | justify-content: $justify; 7 | align-items: $align; 8 | } 9 | //@include flexbox(direction, wrap, justify, align) 10 | 11 | @mixin rowMachine($numPerRow, $marginright, $marginbottom) { 12 | width: ((100% - (($numPerRow - 1) * $marginright)) / $numPerRow); 13 | 14 | &:nth-child(n) { 15 | margin-bottom: $marginbottom; 16 | margin-right: $marginright; 17 | } 18 | 19 | &:nth-child(#{$numPerRow}n) { 20 | margin-right: 0; 21 | } 22 | } 23 | //@include rowMachine(numPerRow, margin) 24 | 25 | @mixin paddinghack($containerwidth, $ratiowidth, $ratioheight){ 26 | position: relative; 27 | width: $containerwidth; 28 | height: 0; 29 | padding: (($ratioheight / $ratiowidth) * $containerwidth) 0 0 0; 30 | } 31 | // @include paddinghack(width, ratiowidth, ratioheight) 32 | 33 | // Button 34 | @mixin button($c){ 35 | margin-top: 10px; 36 | margin-right: 10px; 37 | padding: 14px 26px; 38 | font-size: 1em; 39 | color: set-button-color($c); 40 | display:inline-block; 41 | vertical-align: middle; 42 | text-align: center; 43 | cursor: pointer; 44 | transition: background 0.1s ease-in-out; 45 | border-radius: 2px; 46 | outline: 0 none; 47 | background-color: $c; 48 | box-shadow: 0px 3px 0px 0px darken($c, set-button-shadow($c)); 49 | 50 | &:hover, 51 | &:focus{ 52 | background-color: saturate($c, 20%); 53 | } 54 | 55 | &:active, 56 | &:focus{ 57 | padding-top: 15px; 58 | margin-bottom: -1px; 59 | outline: 0 none; 60 | box-shadow: 0px 1px 0px 0px darken($c, 25%); 61 | } 62 | } 63 | // @include button(color) 64 | 65 | // Basic Triangle 66 | @mixin triangle($bw, $dir, $c){ 67 | width: 0; 68 | height: 0; 69 | border-style: solid; 70 | @if $dir == right{ 71 | border-color: transparent transparent transparent $c; 72 | } 73 | @if $dir == left { 74 | border-color: transparent $c transparent transparent; 75 | } 76 | @if $dir == bottom or $dir == down { 77 | border-color: $c transparent transparent transparent; 78 | } 79 | @if $dir == top or $dir == up { 80 | border-color: transparent transparent $c transparent; 81 | } 82 | border-width: $bw; 83 | } 84 | // @include triangle(border-width, direction[use: right, left, top/up, bottom/down], color); 85 | 86 | // Right-Angled Triangle 87 | @mixin triangle_ra($w, $h, $dir, $c){ 88 | width: 0; 89 | height: 0; 90 | border-style: solid; 91 | @if $dir == bottom-left{ 92 | border-color: transparent transparent transparent $c; 93 | border-width: $h 0 0 $w; 94 | } 95 | @if $dir == bottom-right { 96 | border-color: transparent transparent $c transparent; 97 | border-width: 0 0 $h $w; 98 | } 99 | @if $dir == top-left { 100 | border-color: $c transparent transparent transparent; 101 | border-width: $h $w 0 0; 102 | } 103 | @if $dir == top-right { 104 | border-color: transparent $c transparent transparent; 105 | border-width: 0px $w $h 0px; 106 | } 107 | } 108 | // @include triangle_ra(width, height, direction[use: bottom-left, bottom-right, top-left, top-right], color); 109 | 110 | // equilateral triangle 111 | @mixin triangle_eqla($sl, $dir, $c){ 112 | width: 0; 113 | height: 0; 114 | border-style: solid; 115 | @if $dir == right{ 116 | border-color: transparent transparent transparent $c; 117 | } 118 | @if $dir == left { 119 | border-color: transparent $c transparent transparent; 120 | } 121 | @if $dir == bottom or $dir == down { 122 | border-color: $c transparent transparent transparent; 123 | } 124 | @if $dir == top or $dir == up { 125 | border-color: transparent transparent $c transparent; 126 | } 127 | @if $dir == right or $dir == left { 128 | border-width: ($sl/2) (1.73205*($sl/2)); 129 | } 130 | @if $dir == top or $dir == down or $dir == bottom or $dir == up{ 131 | border-width: (1.73205*($sl/2)) ($sl/2); 132 | } 133 | } 134 | // @include tirangle_eqla(sidelength, direction, color) 135 | 136 | // Flag 137 | @mixin flag($w, $h, $peak, $dir, $c){ 138 | width: 0; 139 | height: 0; 140 | border-style: solid; 141 | @if $dir == top or $dir == up{ 142 | border-color: transparent $c $c $c; 143 | border-width: $peak ($w / 2) ($h - $peak); 144 | } 145 | @if $dir == right{ 146 | border-color: $c transparent $c $c; 147 | border-width: ($h / 2) $peak ($h / 2) ($w - $peak); 148 | } 149 | @if $dir == bottom or $dir == down{ 150 | border-color: $c $c transparent $c; 151 | border-width: ($h - $peak) ($w / 2) $peak; 152 | } 153 | @if $dir == left{ 154 | border-color: $c $c $c transparent; 155 | border-width: ($h / 2) ($w - $peak) ($h / 2) $peak; 156 | } 157 | } 158 | // @include flag(width, height, peak, direction, color) 159 | -------------------------------------------------------------------------------- /src/_sass/modules/_typography.scss: -------------------------------------------------------------------------------- 1 | @import url("https://overpass-30e2.kxcdn.com/overpass.css"); 2 | 3 | $overpass: "Overpass", sans-serif; 4 | 5 | // Overpass Font Weights 6 | $bold: 700; 7 | $light: 300; 8 | -------------------------------------------------------------------------------- /src/_sass/partials/_base.scss: -------------------------------------------------------------------------------- 1 | // Modules 2 | @import "../modules/all"; 3 | 4 | // Shortcuts 5 | $noborder: 0px solid transparent; 6 | 7 | // General Stuff 8 | $sidebar-collapse: 1000px; 9 | 10 | // Extendonly 11 | %clearfix { 12 | &:after { 13 | content: ""; 14 | display: table; 15 | clear: both; 16 | } 17 | } 18 | // @extend %clearfix 19 | 20 | %paddinghack{ 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | right: 0; 25 | bottom: 0; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | // @extend %paddinghack 30 | 31 | %visuallyhidden { 32 | margin: -1px; 33 | padding: 0; 34 | width: 1px; 35 | height: 1px; 36 | overflow: hidden; 37 | position: absolute; 38 | } 39 | // @extend %visuallyhidden 40 | 41 | %center{ 42 | display: block; 43 | position: relative; 44 | margin: 0px auto; 45 | } 46 | // @extend %center 47 | -------------------------------------------------------------------------------- /src/_sass/partials/_fixed-banner.scss: -------------------------------------------------------------------------------- 1 | .fixed-banner { 2 | transition : 0.3s ease-in-out transform; 3 | position : fixed; 4 | left : 323px; 5 | right : 0; 6 | bottom : 0; 7 | width : calc(100% - 343px); 8 | background : #385958; 9 | padding : 0 10px 10px !important; 10 | transform : translateY(150%); 11 | box-shadow: 0px -6px 13px rgba(0, 0, 0, 0.25); 12 | 13 | &.show { 14 | transform : translateY(0); 15 | } 16 | 17 | .detail { 18 | font-family : $overpass; 19 | font-weight : 900; 20 | font-size : 14px; 21 | color : $white; 22 | display : block; 23 | padding : 7px 0 6px; 24 | } 25 | 26 | .close { 27 | font-family : $overpass; 28 | font-size : 18px; 29 | color : $white; 30 | position : absolute; 31 | top : 0; 32 | right : 5px; 33 | cursor : pointer; 34 | transition : 0.3s ease-in-out opacity; 35 | 36 | &:hover { 37 | opacity : 0.8; 38 | } 39 | } 40 | 41 | .wrapper { 42 | padding : 10px; 43 | background : $white; 44 | box-shadow : 0 4px 4px rgba(0, 0, 0, 0.25); 45 | border-radius : 8px; 46 | display : flex; 47 | align-items : stretch; 48 | } 49 | 50 | .column { 51 | flex : 0 1 608px; 52 | } 53 | 54 | .title { 55 | margin-bottom : 6px; 56 | display : block; 57 | font-family : $overpass; 58 | font-size : 26px; 59 | color : #494949; 60 | } 61 | 62 | .link { 63 | transition : 0.3s ease-in-out background; 64 | display : inline-flex; 65 | align-items : center; 66 | justify-content : center; 67 | width : 304px; 68 | height : 48px; 69 | max-width : 100%; 70 | background : #E59620; 71 | box-shadow : 0 2px 5px rgba(0, 0, 0, 0.374); 72 | border-radius : 7px; 73 | font-family : $overpass; 74 | font-weight : $bold; 75 | font-size : 26px; 76 | line-height : normal; 77 | color : $white; 78 | 79 | &:hover { 80 | background : #bf7c1b; 81 | } 82 | } 83 | 84 | .decoration { 85 | display : inline-block; 86 | margin : 0 66px; 87 | flex : 0 0 2px; 88 | width : 2px; 89 | height : 117px; 90 | background : #D7D7D7; 91 | } 92 | 93 | .display { 94 | flex : 0 1 429px; 95 | display : inline-flex; 96 | align-items : center; 97 | justify-content : center; 98 | } 99 | 100 | img { 101 | display : block; 102 | max-width : 100%; 103 | height : auto; 104 | } 105 | 106 | @media(max-width : 1000px) { 107 | left : 0; 108 | width : calc(100% - 20px); 109 | 110 | .decoration { 111 | margin : 0 20px; 112 | } 113 | } 114 | 115 | @media(max-width : 667px) { 116 | .wrapper { 117 | flex-direction : column; 118 | } 119 | 120 | .detail { 121 | font-size : 12px; 122 | padding : 3px 0; 123 | } 124 | 125 | .decoration { 126 | display : none; 127 | } 128 | 129 | .display, 130 | .column { 131 | flex : 0 1 auto; 132 | text-align : center; 133 | } 134 | 135 | .title { 136 | font-size : 14px; 137 | } 138 | 139 | img { 140 | width : 150px; 141 | margin : 0 auto 10px; 142 | } 143 | 144 | .link { 145 | width : 304px; 146 | height : 24px; 147 | font-size : 14px; 148 | padding-top: 1px; 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/_sass/partials/_general.scss: -------------------------------------------------------------------------------- 1 | body{ 2 | font:{ 3 | family: $overpass; 4 | weight: $light; 5 | size: 22px; 6 | } 7 | line-height: 1.4; 8 | background: $white; 9 | color: $black; 10 | } 11 | 12 | .container{ 13 | max-width: 100%; 14 | position: relative; 15 | margin: 0 auto; 16 | } 17 | 18 | .overview{ 19 | width: 320px; 20 | font-size: 18px; 21 | } 22 | 23 | .content{ 24 | counter-reset: h1-counter; 25 | width: calc(100% - 320px); 26 | position: absolute; 27 | right: 0; 28 | 29 | @media screen and (max-width: $sidebar-collapse){ 30 | width: 100%; 31 | } 32 | 33 | .toggle{ 34 | position: absolute; 35 | top: 5px; 36 | left: 5px; 37 | } 38 | } 39 | 40 | section{ 41 | 42 | &:last-of-type{ 43 | padding-bottom: 300px; 44 | } 45 | 46 | > p, 47 | > ul, 48 | > ol, 49 | > div{ 50 | text-align: justify; 51 | padding-left: 5%; 52 | padding-right: 5%; 53 | box-sizing: border-box; 54 | } 55 | 56 | pre { 57 | margin-left: 5%; 58 | margin-right: 5%; 59 | } 60 | > ol{ 61 | padding-left: calc(5% + 40px); 62 | } 63 | } 64 | 65 | h1, h2, h3, h4, h5, h6{ 66 | text-transform: uppercase; 67 | font-weight: $bold; 68 | line-height: 1; 69 | color: $green; 70 | } 71 | 72 | h1 { 73 | font-size: 3.1em; 74 | padding: 30px 0 0; 75 | text-align: right; 76 | border-bottom: $green 9px solid; 77 | width: 100%; 78 | line-height: 0.61; 79 | margin: 0 0 20px; 80 | 81 | &:before { 82 | content: counter(h1-counter) " "; 83 | } 84 | } 85 | 86 | .h1{ 87 | counter-increment: h1-counter; 88 | counter-reset: h2-counter; 89 | padding-top: 80px; 90 | } 91 | 92 | h2 { 93 | font-size: 2em; 94 | padding: 30px 0 0; 95 | width: 90%; 96 | text-align: center; 97 | border-bottom: 5px solid $green; 98 | margin: 0 auto 20px; 99 | line-height: 0.63; 100 | 101 | &:before { 102 | content: counter(h1-counter) "." counter(h2-counter) " "; 103 | } 104 | } 105 | 106 | .h2{ 107 | counter-increment: h2-counter; 108 | counter-reset: h3-counter; 109 | padding-top: 60px; 110 | } 111 | 112 | 113 | h3{ 114 | font-size: 1.7em; 115 | padding: 20px 0 0; 116 | width: 90%; 117 | text-align: left; 118 | border-bottom: 4px solid $green; 119 | margin: 0 auto 20px; 120 | line-height: 0.65; 121 | 122 | &:before { 123 | content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) " "; 124 | } 125 | } 126 | 127 | .h3{ 128 | counter-increment: h3-counter; 129 | counter-reset: h4-counter; 130 | padding-top: 40px; 131 | } 132 | 133 | h4{ 134 | font-size: 1.5em; 135 | padding: 18px 0 0; 136 | width: 90%; 137 | text-align: left; 138 | border-bottom: 3px solid $green; 139 | margin: 0 auto 18px; 140 | line-height: 0.67; 141 | 142 | &:before { 143 | content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) " "; 144 | } 145 | } 146 | 147 | .h4{ 148 | counter-increment: h4-counter; 149 | counter-reset: h5-counter 1; 150 | padding-top: 30px; 151 | } 152 | 153 | 154 | h5{ 155 | font-size: 1.3em; 156 | padding: 40px 0 0; 157 | width: 90%; 158 | text-align: left; 159 | border-bottom: 2px solid $green; 160 | margin: 0 auto 15px; 161 | line-height: 0.68; 162 | 163 | &:before { 164 | content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter) "." counter(h4-counter) "." counter(h5-counter) " "; 165 | } 166 | } 167 | 168 | 169 | a{ 170 | transition: .3s all; 171 | color: $green; 172 | text-decoration: none; 173 | 174 | .content &{ 175 | border-bottom: $darkgreen 1px solid; 176 | padding: 0px 2px; 177 | 178 | &:hover{ 179 | border-bottom: transparent 1px solid; 180 | } 181 | } 182 | 183 | &:hover{ 184 | color: $darkgreen; 185 | } 186 | } 187 | 188 | 189 | img{ 190 | display: block; 191 | max-width: 100%; 192 | margin: 20px 0; 193 | } 194 | 195 | code{ 196 | font-family: 'Overpass', 'Overpass-mono', monospace; 197 | } 198 | 199 | .video_container{ 200 | margin: 30px auto; 201 | @include paddinghack(90%, 894, 510); 202 | 203 | iframe{ 204 | @extend %paddinghack; 205 | } 206 | } 207 | 208 | #intro{ 209 | padding-top: 20px; 210 | } 211 | 212 | code, 213 | pre{ 214 | white-space: pre-wrap; 215 | border-radius: 0px; 216 | border: 0; 217 | } 218 | 219 | iframe{ 220 | padding-left: 5%; 221 | padding-right: 5%; 222 | box-sizing: border-box; 223 | width: 100%; 224 | } 225 | 226 | p + p{ 227 | margin-top: 20px; 228 | } 229 | -------------------------------------------------------------------------------- /src/_sass/partials/_header.scss: -------------------------------------------------------------------------------- 1 | header{ 2 | background:{ 3 | size: auto; 4 | repeat: repeat; 5 | image: url(../img/bg.jpg); 6 | } 7 | height: 150px; 8 | text-align: center; 9 | position: relative; 10 | max-width: 100%; 11 | 12 | span{ 13 | position: absolute; 14 | top: 50%; 15 | left: 50%; 16 | -webkit-transform: translate(-50%, -50%); 17 | -ms-transform: translate(-50%, -50%); 18 | transform: translate(-50%, -50%); 19 | color: $white; 20 | text-transform: uppercase; 21 | font-weight: bold; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/_sass/partials/_nav.scss: -------------------------------------------------------------------------------- 1 | .toggle{ 2 | &:hover{ 3 | cursor: pointer; 4 | opacity: .8; 5 | } 6 | 7 | @media screen and (min-width: $sidebar-collapse + 1){ 8 | display: none; 9 | } 10 | } 11 | 12 | // Overview 13 | .overview { 14 | position: fixed; 15 | top: 0px; 16 | left: 0px; 17 | height: 100%; 18 | overflow-y: auto; 19 | transition: .3s all; 20 | background: $white; 21 | border-right: 3px solid $green; 22 | 23 | @media screen and (max-width: $sidebar-collapse){ 24 | left: -320px; 25 | transition: .3s all ease; 26 | transform: translate(0, 0); 27 | z-index: 100; 28 | 29 | &.open{ 30 | transform: translate(320px, 0); 31 | } 32 | } 33 | 34 | .toggle{ 35 | position: absolute; 36 | top: 5px; 37 | right: 5px; 38 | z-index: 100; 39 | } 40 | ul { 41 | list-style: none; 42 | counter-reset: nested-counter; 43 | padding-left: 0; 44 | li { 45 | counter-increment: nested-counter; 46 | font-size: 98%; 47 | } 48 | } 49 | #nav { 50 | width: 100%; 51 | box-sizing: border-box; 52 | > li { 53 | border-bottom: 1px solid rgba($green, .3); 54 | a { 55 | display: block; 56 | padding: 10px 20px; 57 | line-height: 1; 58 | border-bottom: 1px solid rgba($green, .2); 59 | &:before { 60 | content: counters(nested-counter, ".") " "; 61 | font-size: 0; 62 | } 63 | &:hover { 64 | background: rgba($green, .1); 65 | } 66 | } 67 | li { 68 | a { 69 | padding: 8px 30px; 70 | } 71 | li { 72 | a { 73 | padding: 6px 40px; 74 | } 75 | li { 76 | a { 77 | padding: 4px 50px; 78 | } 79 | } 80 | } 81 | } 82 | } 83 | .current { 84 | > a { 85 | &:before { 86 | font-size: 1em; 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | .current { 94 | > a { 95 | font-weight: $bold; 96 | } 97 | } 98 | 99 | #ezbanner{ 100 | display: block; 101 | width: 180px; 102 | margin-right: auto; 103 | margin-left: auto; 104 | } 105 | -------------------------------------------------------------------------------- /src/_sass/partials/_reset.scss: -------------------------------------------------------------------------------- 1 | // Reset by Eric Meyer 2 | html, body, div, span, applet, object, iframe, 3 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 4 | a, abbr, acronym, address, big, cite, code, 5 | del, dfn, em, img, ins, kbd, q, s, samp, 6 | small, strike, strong, tt, var, 7 | b, u, i, center, 8 | dl, dt, dd, li, 9 | fieldset, form, label, legend, 10 | table, caption, tbody, tfoot, thead, tr, th, td, 11 | article, aside, canvas, details, embed, 12 | figure, figcaption, footer, header, hgroup, 13 | menu, nav, output, ruby, section, summary, 14 | time, mark, audio, video { 15 | margin: 0; 16 | padding: 0; 17 | border: 0; 18 | font-size: 100%; 19 | font: inherit; 20 | vertical-align: baseline; 21 | } 22 | 23 | article, aside, details, figcaption, figure, 24 | footer, header, hgroup, menu, nav, section { 25 | display: block; 26 | } 27 | 28 | body { 29 | line-height: 1; 30 | } 31 | 32 | ul { 33 | list-style: none; 34 | } 35 | 36 | blockquote, q { 37 | quotes: none; 38 | } 39 | 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | 46 | table { 47 | border-collapse: collapse; 48 | border-spacing: 0; 49 | } 50 | 51 | // add bold and italics back 52 | b, strong{ 53 | font-weight: bold; 54 | } 55 | 56 | i, em{ 57 | font-style: italic; 58 | } 59 | -------------------------------------------------------------------------------- /src/_sass/partials/_syntax.scss: -------------------------------------------------------------------------------- 1 | pre{ 2 | background-color: #f8f8f8; 3 | padding: 6px 10px; 4 | border-radius: 2px; 5 | overflow-x:auto; 6 | font-size: .9em; 7 | margin: 15px 0; 8 | } 9 | 10 | $olivegray: #999988; 11 | $palepink: #e3d2d2; 12 | $darkred: #a61717; 13 | $medgray: #999; 14 | 15 | .highlight{ 16 | 17 | pre, 18 | .hll { 19 | @extend pre; 20 | } 21 | 22 | .c, 23 | .cm, 24 | .c1 { 25 | color: $olivegray; 26 | } 27 | 28 | .err, 29 | .gr, 30 | .gt { 31 | color: $darkred; 32 | } 33 | 34 | .k, 35 | .o, 36 | .cp, 37 | .cs, 38 | .gs, 39 | .kc, 40 | .kd, 41 | .kn, 42 | .kp, 43 | .kr, 44 | .gu, 45 | .ne, 46 | .nf, 47 | .ow { 48 | font-weight: bold; 49 | } 50 | 51 | .cp, 52 | .cs, 53 | .gh { 54 | color: $medgray; 55 | } 56 | 57 | .gd, 58 | .gd .x, 59 | .gi, 60 | .gi .x { 61 | color: black; 62 | } 63 | 64 | .gd{ 65 | background-color: $palepink; 66 | } 67 | 68 | .gd .x { 69 | background-color: #ffaaaa; 70 | } 71 | 72 | .gi { 73 | background-color: #ddffdd; 74 | 75 | .x{ 76 | background-color: #aaffaa; 77 | } 78 | } 79 | 80 | .go { 81 | color: #888; 82 | } 83 | 84 | .gp { 85 | color: #555; 86 | } 87 | 88 | .gu { 89 | color: #800080; 90 | } 91 | 92 | .kt { 93 | color: #445588; 94 | font-weight: bold; 95 | } 96 | 97 | .m { 98 | color: #009999; 99 | } 100 | 101 | .s { 102 | color: $green; 103 | } 104 | 105 | .n { 106 | color: #333; 107 | } 108 | 109 | .na { 110 | color: teal; 111 | } 112 | 113 | .nb { 114 | color: #0086b3; 115 | } 116 | 117 | .nc { 118 | color: #445588; 119 | font-weight: bold; 120 | } 121 | 122 | .no { 123 | color: teal; 124 | } 125 | 126 | .ni { 127 | color: purple; 128 | } 129 | 130 | .ne { 131 | color: #990000; 132 | } 133 | 134 | .nf { 135 | color: #990000; 136 | } 137 | 138 | .nn { 139 | color: #555555; 140 | } 141 | 142 | .nt { 143 | color: navy; 144 | } 145 | 146 | .nv { 147 | color: teal; 148 | } 149 | 150 | .w { 151 | color: #bbbbbb; 152 | } 153 | 154 | .mf { 155 | color: #009999; 156 | } 157 | 158 | .mh { 159 | color: #009999; 160 | } 161 | 162 | .mi { 163 | color: #009999; 164 | } 165 | 166 | .mo { 167 | color: #009999; 168 | } 169 | 170 | .sb { 171 | color: #dd1144; 172 | } 173 | 174 | .sc { 175 | color: #dd1144; 176 | } 177 | 178 | .sd { 179 | color: #dd1144; 180 | } 181 | 182 | .s2 { 183 | color: $green; 184 | } 185 | 186 | .se { 187 | color: #dd1144; 188 | } 189 | 190 | .sh { 191 | color: #dd1144; 192 | } 193 | 194 | .si { 195 | color: #dd1144; 196 | } 197 | 198 | .sx { 199 | color: #dd1144; 200 | } 201 | 202 | .sr { 203 | color: #009926; 204 | } 205 | 206 | .s1 { 207 | color: #dd1144; 208 | } 209 | 210 | .ss { 211 | color: #990073; 212 | } 213 | 214 | .bp { 215 | color: $medgray; 216 | } 217 | 218 | .vc { 219 | color: teal; 220 | } 221 | 222 | .vg { 223 | color: teal; 224 | } 225 | 226 | .vi { 227 | color: teal; 228 | } 229 | 230 | .il { 231 | color: #009999; 232 | } 233 | 234 | .gc { 235 | color: #999; 236 | background-color: #EAF2F5; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/css/main.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | @import "partials/reset"; 4 | @import "partials/base"; 5 | @import "partials/general"; 6 | @import "partials/header"; 7 | @import "partials/nav"; 8 | @import "partials/syntax"; 9 | -------------------------------------------------------------------------------- /src/img/ErgoDox-original-min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/ErgoDox-original-min.png -------------------------------------------------------------------------------- /src/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/bg.jpg -------------------------------------------------------------------------------- /src/img/ceramic-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/ceramic-min.jpg -------------------------------------------------------------------------------- /src/img/diode-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/diode-min.jpg -------------------------------------------------------------------------------- /src/img/ergodox-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/ergodox-logo.png -------------------------------------------------------------------------------- /src/img/ergodox_ez.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/img/ergodox_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/ergodox_logo.png -------------------------------------------------------------------------------- /src/img/gamepad0-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/gamepad0-min.jpg -------------------------------------------------------------------------------- /src/img/gamepad1-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/gamepad1-min.jpg -------------------------------------------------------------------------------- /src/img/gamepad2-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/gamepad2-min.jpg -------------------------------------------------------------------------------- /src/img/gamepad3-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/gamepad3-min.jpg -------------------------------------------------------------------------------- /src/img/gamepad4-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/gamepad4-min.jpg -------------------------------------------------------------------------------- /src/img/gamepad5-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/gamepad5-min.jpg -------------------------------------------------------------------------------- /src/img/teensy-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/teensy-min.jpg -------------------------------------------------------------------------------- /src/img/th-diode-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/th-diode-min.jpg -------------------------------------------------------------------------------- /src/img/trrs-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/trrs-min.jpg -------------------------------------------------------------------------------- /src/img/usb-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/usb-min.jpg -------------------------------------------------------------------------------- /src/img/wiring-min.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ergodox-io/ergodox-io/9a52adbea8a259605e3ebcc5fc3e75ab11f55ef3/src/img/wiring-min.jpg -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: index 3 | title: index 4 | --- 5 | 6 | {% assign entries = site.entries | sort: "number" %} 7 | {% for entry in entries %} 8 | {% if entry.title != 'index'%} 9 |
10 | {% case entry.sectionclass %} 11 | {% when 'h1' %} 12 |

{{ entry.title }}

13 | {% when 'h2' %} 14 |

{{ entry.title }}

15 | {% when 'h3' %} 16 |

{{ entry.title }}

17 | {% when 'h4' %} 18 |

{{ entry.title }}

19 | {% endcase %} 20 | 21 | {{ entry.content }} 22 |
23 | {% endif %} 24 | {% endfor %} 25 | -------------------------------------------------------------------------------- /src/js/jquery.nav.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery One Page Nav Plugin 3 | * http://github.com/davist11/jQuery-One-Page-Nav 4 | * 5 | * Copyright (c) 2010 Trevor Davis (http://trevordavis.net) 6 | * Dual licensed under the MIT and GPL licenses. 7 | * Uses the same license as jQuery, see: 8 | * http://jquery.org/license 9 | * 10 | * @version 3.0.0 11 | * 12 | * Example usage: 13 | * $('#nav').onePageNav({ 14 | * currentClass: 'current', 15 | * changeHash: false, 16 | * scrollSpeed: 750 17 | * }); 18 | */ 19 | 20 | ;(function($, window, document, undefined){ 21 | 22 | // our plugin constructor 23 | var OnePageNav = function(elem, options){ 24 | this.elem = elem; 25 | this.$elem = $(elem); 26 | this.options = options; 27 | this.metadata = this.$elem.data('plugin-options'); 28 | this.$win = $(window); 29 | this.sections = {}; 30 | this.didScroll = false; 31 | this.$doc = $(document); 32 | this.docHeight = this.$doc.height(); 33 | }; 34 | 35 | // the plugin prototype 36 | OnePageNav.prototype = { 37 | defaults: { 38 | navItems: 'a', 39 | currentClass: 'current', 40 | changeHash: false, 41 | easing: 'swing', 42 | filter: '', 43 | scrollSpeed: 750, 44 | scrollThreshold: 0.5, 45 | begin: false, 46 | end: false, 47 | scrollChange: false 48 | }, 49 | 50 | init: function() { 51 | // Introduce defaults that can be extended either 52 | // globally or using an object literal. 53 | this.config = $.extend({}, this.defaults, this.options, this.metadata); 54 | 55 | this.$nav = this.$elem.find(this.config.navItems); 56 | 57 | //Filter any links out of the nav 58 | if(this.config.filter !== '') { 59 | this.$nav = this.$nav.filter(this.config.filter); 60 | } 61 | 62 | //Handle clicks on the nav 63 | this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this)); 64 | 65 | //Get the section positions 66 | this.getPositions(); 67 | 68 | //Handle scroll changes 69 | this.bindInterval(); 70 | 71 | //Update the positions on resize too 72 | this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this)); 73 | 74 | return this; 75 | }, 76 | 77 | adjustNav: function(self, $parent) { 78 | self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass); 79 | $parent.addClass(self.config.currentClass); 80 | }, 81 | 82 | bindInterval: function() { 83 | var self = this; 84 | var docHeight; 85 | 86 | self.$win.on('scroll.onePageNav', function() { 87 | self.didScroll = true; 88 | }); 89 | 90 | self.t = setInterval(function() { 91 | docHeight = self.$doc.height(); 92 | 93 | //If it was scrolled 94 | if(self.didScroll) { 95 | self.didScroll = false; 96 | self.scrollChange(); 97 | } 98 | 99 | //If the document height changes 100 | if(docHeight !== self.docHeight) { 101 | self.docHeight = docHeight; 102 | self.getPositions(); 103 | } 104 | }, 250); 105 | }, 106 | 107 | getHash: function($link) { 108 | return $link.attr('href').split('#')[1]; 109 | }, 110 | 111 | getPositions: function() { 112 | var self = this; 113 | var linkHref; 114 | var topPos; 115 | var $target; 116 | 117 | self.$nav.each(function() { 118 | linkHref = self.getHash($(this)); 119 | $target = $('#' + linkHref); 120 | 121 | if($target.length) { 122 | topPos = $target.offset().top; 123 | self.sections[linkHref] = Math.round(topPos); 124 | } 125 | }); 126 | }, 127 | 128 | getSection: function(windowPos) { 129 | var returnValue = null; 130 | var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold); 131 | 132 | for(var section in this.sections) { 133 | if((this.sections[section] - windowHeight) < windowPos) { 134 | returnValue = section; 135 | } 136 | } 137 | 138 | return returnValue; 139 | }, 140 | 141 | handleClick: function(e) { 142 | var self = this; 143 | var $link = $(e.currentTarget); 144 | var $parent = $link.parent(); 145 | var newLoc = '#' + self.getHash($link); 146 | 147 | if(!$parent.hasClass(self.config.currentClass)) { 148 | //Start callback 149 | if(self.config.begin) { 150 | self.config.begin(); 151 | } 152 | 153 | //Change the highlighted nav item 154 | self.adjustNav(self, $parent); 155 | 156 | //Removing the auto-adjust on scroll 157 | self.unbindInterval(); 158 | 159 | //Scroll to the correct position 160 | self.scrollTo(newLoc, function() { 161 | //Do we need to change the hash? 162 | if(self.config.changeHash) { 163 | window.location.hash = newLoc; 164 | } 165 | 166 | //Add the auto-adjust on scroll back in 167 | self.bindInterval(); 168 | 169 | //End callback 170 | if(self.config.end) { 171 | self.config.end(); 172 | } 173 | }); 174 | } 175 | 176 | e.preventDefault(); 177 | }, 178 | 179 | scrollChange: function() { 180 | var windowTop = this.$win.scrollTop(); 181 | var position = this.getSection(windowTop); 182 | var $parent; 183 | 184 | //If the position is set 185 | if(position !== null) { 186 | $parent = this.$elem.find('a[href$="#' + position + '"]').parent(); 187 | 188 | //If it's not already the current section 189 | if(!$parent.hasClass(this.config.currentClass)) { 190 | //Change the highlighted nav item 191 | this.adjustNav(this, $parent); 192 | 193 | //If there is a scrollChange callback 194 | if(this.config.scrollChange) { 195 | this.config.scrollChange($parent); 196 | } 197 | } 198 | } 199 | }, 200 | 201 | scrollTo: function(target, callback) { 202 | var offset = $(target).offset().top; 203 | 204 | $('html, body').animate({ 205 | scrollTop: offset 206 | }, this.config.scrollSpeed, this.config.easing, callback); 207 | }, 208 | 209 | unbindInterval: function() { 210 | clearInterval(this.t); 211 | this.$win.unbind('scroll.onePageNav'); 212 | } 213 | }; 214 | 215 | OnePageNav.defaults = OnePageNav.prototype.defaults; 216 | 217 | $.fn.onePageNav = function(options) { 218 | return this.each(function() { 219 | new OnePageNav(this, options).init(); 220 | }); 221 | }; 222 | 223 | })( jQuery, window , document ); 224 | -------------------------------------------------------------------------------- /src/js/jquery.scrollTo.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery.scrollTo 3 | * Copyright (c) 2007-2014 Ariel Flesler - afleslergmailcom | http://flesler.blogspot.com 4 | * Licensed under MIT 5 | * http://flesler.blogspot.com/2007/10/jqueryscrollto.html 6 | * @projectDescription Easy element scrolling using jQuery. 7 | * @author Ariel Flesler 8 | * @version 1.4.13 9 | */ 10 | ;(function (define) { 11 | 'use strict'; 12 | 13 | define(['jquery'], function ($) { 14 | 15 | var $scrollTo = $.scrollTo = function( target, duration, settings ) { 16 | return $(window).scrollTo( target, duration, settings ); 17 | }; 18 | 19 | $scrollTo.defaults = { 20 | axis:'xy', 21 | duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1, 22 | limit:true 23 | }; 24 | 25 | // Returns the element that needs to be animated to scroll the window. 26 | // Kept for backwards compatibility (specially for localScroll & serialScroll) 27 | $scrollTo.window = function( scope ) { 28 | return $(window)._scrollable(); 29 | }; 30 | 31 | // Hack, hack, hack :) 32 | // Returns the real elements to scroll (supports window/iframes, documents and regular nodes) 33 | $.fn._scrollable = function() { 34 | return this.map(function() { 35 | var elem = this, 36 | isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1; 37 | 38 | if (!isWin) 39 | return elem; 40 | 41 | var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem; 42 | 43 | return /webkit/i.test(navigator.userAgent) || doc.compatMode == 'BackCompat' ? 44 | doc.body : 45 | doc.documentElement; 46 | }); 47 | }; 48 | 49 | $.fn.scrollTo = function( target, duration, settings ) { 50 | if (typeof duration == 'object') { 51 | settings = duration; 52 | duration = 0; 53 | } 54 | if (typeof settings == 'function') 55 | settings = { onAfter:settings }; 56 | 57 | if (target == 'max') 58 | target = 9e9; 59 | 60 | settings = $.extend( {}, $scrollTo.defaults, settings ); 61 | // Speed is still recognized for backwards compatibility 62 | duration = duration || settings.duration; 63 | // Make sure the settings are given right 64 | settings.queue = settings.queue && settings.axis.length > 1; 65 | 66 | if (settings.queue) 67 | // Let's keep the overall duration 68 | duration /= 2; 69 | settings.offset = both( settings.offset ); 70 | settings.over = both( settings.over ); 71 | 72 | return this._scrollable().each(function() { 73 | // Null target yields nothing, just like jQuery does 74 | if (target == null) return; 75 | 76 | var elem = this, 77 | $elem = $(elem), 78 | targ = target, toff, attr = {}, 79 | win = $elem.is('html,body'); 80 | 81 | switch (typeof targ) { 82 | // A number will pass the regex 83 | case 'number': 84 | case 'string': 85 | if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) { 86 | targ = both( targ ); 87 | // We are done 88 | break; 89 | } 90 | // Relative/Absolute selector, no break! 91 | targ = win ? $(targ) : $(targ, this); 92 | if (!targ.length) return; 93 | case 'object': 94 | // DOMElement / jQuery 95 | if (targ.is || targ.style) 96 | // Get the real position of the target 97 | toff = (targ = $(targ)).offset(); 98 | } 99 | 100 | var offset = $.isFunction(settings.offset) && settings.offset(elem, targ) || settings.offset; 101 | 102 | $.each( settings.axis.split(''), function( i, axis ) { 103 | var Pos = axis == 'x' ? 'Left' : 'Top', 104 | pos = Pos.toLowerCase(), 105 | key = 'scroll' + Pos, 106 | old = elem[key], 107 | max = $scrollTo.max(elem, axis); 108 | 109 | if (toff) {// jQuery / DOMElement 110 | attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] ); 111 | 112 | // If it's a dom element, reduce the margin 113 | if (settings.margin) { 114 | attr[key] -= parseInt(targ.css('margin'+Pos)) || 0; 115 | attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0; 116 | } 117 | 118 | attr[key] += offset[pos] || 0; 119 | 120 | if(settings.over[pos]) 121 | // Scroll to a fraction of its width/height 122 | attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos]; 123 | } else { 124 | var val = targ[pos]; 125 | // Handle percentage values 126 | attr[key] = val.slice && val.slice(-1) == '%' ? 127 | parseFloat(val) / 100 * max 128 | : val; 129 | } 130 | 131 | // Number or 'number' 132 | if (settings.limit && /^\d+$/.test(attr[key])) 133 | // Check the limits 134 | attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max ); 135 | 136 | // Queueing axes 137 | if (!i && settings.queue) { 138 | // Don't waste time animating, if there's no need. 139 | if (old != attr[key]) 140 | // Intermediate animation 141 | animate( settings.onAfterFirst ); 142 | // Don't animate this axis again in the next iteration. 143 | delete attr[key]; 144 | } 145 | }); 146 | 147 | animate( settings.onAfter ); 148 | 149 | function animate( callback ) { 150 | $elem.animate( attr, duration, settings.easing, callback && function() { 151 | callback.call(this, targ, settings); 152 | }); 153 | } 154 | }).end(); 155 | }; 156 | 157 | // Max scrolling position, works on quirks mode 158 | // It only fails (not too badly) on IE, quirks mode. 159 | $scrollTo.max = function( elem, axis ) { 160 | var Dim = axis == 'x' ? 'Width' : 'Height', 161 | scroll = 'scroll'+Dim; 162 | 163 | if (!$(elem).is('html,body')) 164 | return elem[scroll] - $(elem)[Dim.toLowerCase()](); 165 | 166 | var size = 'client' + Dim, 167 | html = elem.ownerDocument.documentElement, 168 | body = elem.ownerDocument.body; 169 | 170 | return Math.max( html[scroll], body[scroll] ) - Math.min( html[size] , body[size] ); 171 | }; 172 | 173 | function both( val ) { 174 | return $.isFunction(val) || typeof val == 'object' ? val : { top:val, left:val }; 175 | } 176 | 177 | // AMD requirement 178 | return $scrollTo; 179 | }) 180 | }(typeof define === 'function' && define.amd ? define : function (deps, factory) { 181 | if (typeof module !== 'undefined' && module.exports) { 182 | // Node 183 | module.exports = factory(require('jquery')); 184 | } else { 185 | factory(jQuery); 186 | } 187 | })); 188 | -------------------------------------------------------------------------------- /src/js/scripts.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | $('#nav').onePageNav(); 3 | 4 | $('a[href^="http"]').attr('target','_blank'); 5 | 6 | $('.toggle').click(function(){ 7 | $('.overview').toggleClass('open'); 8 | }); 9 | 10 | fixedBanner() 11 | }); 12 | 13 | function fixedBanner() { 14 | var $banner = $('#fixedBanner'), 15 | cookieName = 'hideBanner' 16 | 17 | if (getCookie(cookieName) !== 'true') { 18 | $banner.addClass('show') 19 | } 20 | 21 | $banner.find('.close').click(function() { 22 | $banner.removeClass('show') 23 | setCookie(cookieName, true, 30) 24 | }) 25 | } 26 | function setCookie(cname, cvalue, exdays) { 27 | var d = new Date(); 28 | d.setTime(d.getTime() + (exdays*24*60*60*1000)); 29 | var expires = "expires="+ d.toUTCString(); 30 | document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 31 | } 32 | 33 | function getCookie(cname) { 34 | var name = cname + "="; 35 | var decodedCookie = decodeURIComponent(document.cookie); 36 | var ca = decodedCookie.split(';'); 37 | for(var i = 0; i