diff --git a/hackpads/blipyboard/README.md b/hackpads/blipyboard/README.md
new file mode 100644
index 0000000000..8083e06fdc
--- /dev/null
+++ b/hackpads/blipyboard/README.md
@@ -0,0 +1,34 @@
+# blipyboard
+An 8 key macropad with an OLED screen and potentiometer for HackPad. It also has 8 SK6812 leds for lighting and utilizes custom KMK firmware.
+
+
+
+
+# **CAD Model**
+
+Designed and Modeled using Fusion 360
+
+# **Schematic**
+
+
+# **PCB**
+
+Schematic and PCB created using KiCad
+
+
+
+# **BOM**
+8x Cherry MX Switches
+9x 1N4148 Diodes
+8x SK6812 Mini LED
+8x Keycaps
+1x Rotary Encoder with push button
+1x 0.91" OLED Display (128x32)
+1x XIAO-RP2040 microcontroller
+4x M3x10mm screws
+1x Custom PCB
+1x 1kg spool of white filament from Amazon
+I will print my own case
+
+# **Inspiration/Challenges**
+I created this macropad to learn more about hardware and firmware creation. I wanted to be able to perform my most used functions with singular key presses such as copy/paste and inserting long strings. While working on this hackpad, I encountered issues with the firmware, the pcb, and 3d models associated with the footprints. By looking at other people's submissions and asking for help on slack, I overcame these issues. In the future I want to learn how to integrate QMK firmware and add more advanced animations for the OLED.
diff --git a/hackpads/blipyboard/cad/blipyboard_complete.step b/hackpads/blipyboard/cad/blipyboard_complete.step
new file mode 100644
index 0000000000..a3b2f40781
--- /dev/null
+++ b/hackpads/blipyboard/cad/blipyboard_complete.step
@@ -0,0 +1,4630 @@
+ISO-10303-21;
+HEADER;
+/* Generated by software containing ST-Developer
+ * from STEP Tools, Inc. (www.steptools.com)
+ */
+
+FILE_DESCRIPTION(
+/* description */ (''),
+/* implementation_level */ '2;1');
+
+FILE_NAME(
+/* name */ 'blipyboard_complete.step',
+/* time_stamp */ '2025-06-27T21:56:00-07:00',
+/* author */ (''),
+/* organization */ (''),
+/* preprocessor_version */ 'ST-DEVELOPER v20.1',
+/* originating_system */ 'Autodesk Translation Framework v14.10.0.0',
+/* authorisation */ '');
+
+FILE_SCHEMA (('AUTOMOTIVE_DESIGN { 1 0 10303 214 3 1 1 }'));
+ENDSEC;
+
+DATA;
+#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#13,#14,
+#15),#4546);
+#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#4552,#12);
+#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#16,#17,#18),#4545);
+#13=STYLED_ITEM('',(#4561),#16);
+#14=STYLED_ITEM('',(#4561),#17);
+#15=STYLED_ITEM('',(#4561),#18);
+#16=MANIFOLD_SOLID_BREP('bottom',#2724);
+#17=MANIFOLD_SOLID_BREP('plate',#2725);
+#18=MANIFOLD_SOLID_BREP('top',#2726);
+#19=FACE_BOUND('',#277,.T.);
+#20=FACE_BOUND('',#278,.T.);
+#21=FACE_BOUND('',#279,.T.);
+#22=FACE_BOUND('',#280,.T.);
+#23=FACE_BOUND('',#302,.T.);
+#24=FACE_BOUND('',#303,.T.);
+#25=FACE_BOUND('',#304,.T.);
+#26=FACE_BOUND('',#305,.T.);
+#27=FACE_BOUND('',#309,.T.);
+#28=FACE_BOUND('',#310,.T.);
+#29=FACE_BOUND('',#311,.T.);
+#30=FACE_BOUND('',#312,.T.);
+#31=FACE_BOUND('',#313,.T.);
+#32=FACE_BOUND('',#314,.T.);
+#33=FACE_BOUND('',#315,.T.);
+#34=FACE_BOUND('',#316,.T.);
+#35=FACE_BOUND('',#317,.T.);
+#36=FACE_BOUND('',#318,.T.);
+#37=FACE_BOUND('',#319,.T.);
+#38=FACE_BOUND('',#320,.T.);
+#39=FACE_BOUND('',#321,.T.);
+#40=FACE_BOUND('',#322,.T.);
+#41=FACE_BOUND('',#414,.T.);
+#42=FACE_BOUND('',#415,.T.);
+#43=FACE_BOUND('',#416,.T.);
+#44=FACE_BOUND('',#417,.T.);
+#45=FACE_BOUND('',#418,.T.);
+#46=FACE_BOUND('',#419,.T.);
+#47=FACE_BOUND('',#420,.T.);
+#48=FACE_BOUND('',#421,.T.);
+#49=FACE_BOUND('',#422,.T.);
+#50=FACE_BOUND('',#423,.T.);
+#51=FACE_BOUND('',#424,.T.);
+#52=FACE_BOUND('',#425,.T.);
+#53=FACE_BOUND('',#426,.T.);
+#54=FACE_BOUND('',#427,.T.);
+#55=FACE_BOUND('',#431,.T.);
+#56=FACE_BOUND('',#432,.T.);
+#57=FACE_BOUND('',#433,.T.);
+#58=FACE_BOUND('',#434,.T.);
+#59=FACE_BOUND('',#435,.T.);
+#60=FACE_BOUND('',#451,.T.);
+#61=FACE_BOUND('',#452,.T.);
+#62=FACE_BOUND('',#453,.T.);
+#63=FACE_BOUND('',#454,.T.);
+#64=FACE_BOUND('',#455,.T.);
+#65=PLANE('',#2731);
+#66=PLANE('',#2739);
+#67=PLANE('',#2744);
+#68=PLANE('',#2747);
+#69=PLANE('',#2748);
+#70=PLANE('',#2749);
+#71=PLANE('',#2750);
+#72=PLANE('',#2751);
+#73=PLANE('',#2752);
+#74=PLANE('',#2753);
+#75=PLANE('',#2754);
+#76=PLANE('',#2755);
+#77=PLANE('',#2756);
+#78=PLANE('',#2765);
+#79=PLANE('',#2766);
+#80=PLANE('',#2770);
+#81=PLANE('',#2771);
+#82=PLANE('',#2817);
+#83=PLANE('',#2822);
+#84=PLANE('',#2833);
+#85=PLANE('',#2836);
+#86=PLANE('',#2839);
+#87=PLANE('',#2842);
+#88=PLANE('',#2845);
+#89=PLANE('',#2848);
+#90=PLANE('',#2851);
+#91=PLANE('',#2854);
+#92=PLANE('',#2857);
+#93=PLANE('',#2860);
+#94=PLANE('',#2863);
+#95=PLANE('',#2866);
+#96=PLANE('',#2869);
+#97=PLANE('',#2872);
+#98=PLANE('',#2875);
+#99=PLANE('',#2878);
+#100=PLANE('',#2881);
+#101=PLANE('',#2884);
+#102=PLANE('',#2887);
+#103=PLANE('',#2890);
+#104=PLANE('',#2893);
+#105=PLANE('',#2896);
+#106=PLANE('',#2899);
+#107=PLANE('',#2902);
+#108=PLANE('',#2905);
+#109=PLANE('',#2908);
+#110=PLANE('',#2911);
+#111=PLANE('',#2914);
+#112=PLANE('',#2917);
+#113=PLANE('',#2920);
+#114=PLANE('',#2923);
+#115=PLANE('',#2926);
+#116=PLANE('',#2929);
+#117=PLANE('',#2932);
+#118=PLANE('',#2935);
+#119=PLANE('',#2938);
+#120=PLANE('',#2939);
+#121=PLANE('',#2940);
+#122=PLANE('',#2941);
+#123=PLANE('',#2942);
+#124=PLANE('',#2943);
+#125=PLANE('',#2944);
+#126=PLANE('',#2945);
+#127=PLANE('',#2946);
+#128=PLANE('',#2947);
+#129=PLANE('',#2948);
+#130=PLANE('',#2952);
+#131=PLANE('',#2953);
+#132=PLANE('',#2963);
+#133=PLANE('',#2966);
+#134=PLANE('',#2975);
+#135=PLANE('',#2976);
+#136=PLANE('',#2977);
+#137=PLANE('',#2978);
+#138=PLANE('',#2981);
+#139=PLANE('',#2982);
+#140=FACE_OUTER_BOUND('',#275,.T.);
+#141=FACE_OUTER_BOUND('',#276,.T.);
+#142=FACE_OUTER_BOUND('',#281,.T.);
+#143=FACE_OUTER_BOUND('',#282,.T.);
+#144=FACE_OUTER_BOUND('',#283,.T.);
+#145=FACE_OUTER_BOUND('',#284,.T.);
+#146=FACE_OUTER_BOUND('',#285,.T.);
+#147=FACE_OUTER_BOUND('',#286,.T.);
+#148=FACE_OUTER_BOUND('',#287,.T.);
+#149=FACE_OUTER_BOUND('',#288,.T.);
+#150=FACE_OUTER_BOUND('',#289,.T.);
+#151=FACE_OUTER_BOUND('',#290,.T.);
+#152=FACE_OUTER_BOUND('',#291,.T.);
+#153=FACE_OUTER_BOUND('',#292,.T.);
+#154=FACE_OUTER_BOUND('',#293,.T.);
+#155=FACE_OUTER_BOUND('',#294,.T.);
+#156=FACE_OUTER_BOUND('',#295,.T.);
+#157=FACE_OUTER_BOUND('',#296,.T.);
+#158=FACE_OUTER_BOUND('',#297,.T.);
+#159=FACE_OUTER_BOUND('',#298,.T.);
+#160=FACE_OUTER_BOUND('',#299,.T.);
+#161=FACE_OUTER_BOUND('',#300,.T.);
+#162=FACE_OUTER_BOUND('',#301,.T.);
+#163=FACE_OUTER_BOUND('',#306,.T.);
+#164=FACE_OUTER_BOUND('',#307,.T.);
+#165=FACE_OUTER_BOUND('',#308,.T.);
+#166=FACE_OUTER_BOUND('',#323,.T.);
+#167=FACE_OUTER_BOUND('',#324,.T.);
+#168=FACE_OUTER_BOUND('',#325,.T.);
+#169=FACE_OUTER_BOUND('',#326,.T.);
+#170=FACE_OUTER_BOUND('',#327,.T.);
+#171=FACE_OUTER_BOUND('',#328,.T.);
+#172=FACE_OUTER_BOUND('',#329,.T.);
+#173=FACE_OUTER_BOUND('',#330,.T.);
+#174=FACE_OUTER_BOUND('',#331,.T.);
+#175=FACE_OUTER_BOUND('',#332,.T.);
+#176=FACE_OUTER_BOUND('',#333,.T.);
+#177=FACE_OUTER_BOUND('',#334,.T.);
+#178=FACE_OUTER_BOUND('',#335,.T.);
+#179=FACE_OUTER_BOUND('',#336,.T.);
+#180=FACE_OUTER_BOUND('',#337,.T.);
+#181=FACE_OUTER_BOUND('',#338,.T.);
+#182=FACE_OUTER_BOUND('',#339,.T.);
+#183=FACE_OUTER_BOUND('',#340,.T.);
+#184=FACE_OUTER_BOUND('',#341,.T.);
+#185=FACE_OUTER_BOUND('',#342,.T.);
+#186=FACE_OUTER_BOUND('',#343,.T.);
+#187=FACE_OUTER_BOUND('',#344,.T.);
+#188=FACE_OUTER_BOUND('',#345,.T.);
+#189=FACE_OUTER_BOUND('',#346,.T.);
+#190=FACE_OUTER_BOUND('',#347,.T.);
+#191=FACE_OUTER_BOUND('',#348,.T.);
+#192=FACE_OUTER_BOUND('',#349,.T.);
+#193=FACE_OUTER_BOUND('',#350,.T.);
+#194=FACE_OUTER_BOUND('',#351,.T.);
+#195=FACE_OUTER_BOUND('',#352,.T.);
+#196=FACE_OUTER_BOUND('',#353,.T.);
+#197=FACE_OUTER_BOUND('',#354,.T.);
+#198=FACE_OUTER_BOUND('',#355,.T.);
+#199=FACE_OUTER_BOUND('',#356,.T.);
+#200=FACE_OUTER_BOUND('',#357,.T.);
+#201=FACE_OUTER_BOUND('',#358,.T.);
+#202=FACE_OUTER_BOUND('',#359,.T.);
+#203=FACE_OUTER_BOUND('',#360,.T.);
+#204=FACE_OUTER_BOUND('',#361,.T.);
+#205=FACE_OUTER_BOUND('',#362,.T.);
+#206=FACE_OUTER_BOUND('',#363,.T.);
+#207=FACE_OUTER_BOUND('',#364,.T.);
+#208=FACE_OUTER_BOUND('',#365,.T.);
+#209=FACE_OUTER_BOUND('',#366,.T.);
+#210=FACE_OUTER_BOUND('',#367,.T.);
+#211=FACE_OUTER_BOUND('',#368,.T.);
+#212=FACE_OUTER_BOUND('',#369,.T.);
+#213=FACE_OUTER_BOUND('',#370,.T.);
+#214=FACE_OUTER_BOUND('',#371,.T.);
+#215=FACE_OUTER_BOUND('',#372,.T.);
+#216=FACE_OUTER_BOUND('',#373,.T.);
+#217=FACE_OUTER_BOUND('',#374,.T.);
+#218=FACE_OUTER_BOUND('',#375,.T.);
+#219=FACE_OUTER_BOUND('',#376,.T.);
+#220=FACE_OUTER_BOUND('',#377,.T.);
+#221=FACE_OUTER_BOUND('',#378,.T.);
+#222=FACE_OUTER_BOUND('',#379,.T.);
+#223=FACE_OUTER_BOUND('',#380,.T.);
+#224=FACE_OUTER_BOUND('',#381,.T.);
+#225=FACE_OUTER_BOUND('',#382,.T.);
+#226=FACE_OUTER_BOUND('',#383,.T.);
+#227=FACE_OUTER_BOUND('',#384,.T.);
+#228=FACE_OUTER_BOUND('',#385,.T.);
+#229=FACE_OUTER_BOUND('',#386,.T.);
+#230=FACE_OUTER_BOUND('',#387,.T.);
+#231=FACE_OUTER_BOUND('',#388,.T.);
+#232=FACE_OUTER_BOUND('',#389,.T.);
+#233=FACE_OUTER_BOUND('',#390,.T.);
+#234=FACE_OUTER_BOUND('',#391,.T.);
+#235=FACE_OUTER_BOUND('',#392,.T.);
+#236=FACE_OUTER_BOUND('',#393,.T.);
+#237=FACE_OUTER_BOUND('',#394,.T.);
+#238=FACE_OUTER_BOUND('',#395,.T.);
+#239=FACE_OUTER_BOUND('',#396,.T.);
+#240=FACE_OUTER_BOUND('',#397,.T.);
+#241=FACE_OUTER_BOUND('',#398,.T.);
+#242=FACE_OUTER_BOUND('',#399,.T.);
+#243=FACE_OUTER_BOUND('',#400,.T.);
+#244=FACE_OUTER_BOUND('',#401,.T.);
+#245=FACE_OUTER_BOUND('',#402,.T.);
+#246=FACE_OUTER_BOUND('',#403,.T.);
+#247=FACE_OUTER_BOUND('',#404,.T.);
+#248=FACE_OUTER_BOUND('',#405,.T.);
+#249=FACE_OUTER_BOUND('',#406,.T.);
+#250=FACE_OUTER_BOUND('',#407,.T.);
+#251=FACE_OUTER_BOUND('',#408,.T.);
+#252=FACE_OUTER_BOUND('',#409,.T.);
+#253=FACE_OUTER_BOUND('',#410,.T.);
+#254=FACE_OUTER_BOUND('',#411,.T.);
+#255=FACE_OUTER_BOUND('',#412,.T.);
+#256=FACE_OUTER_BOUND('',#413,.T.);
+#257=FACE_OUTER_BOUND('',#428,.T.);
+#258=FACE_OUTER_BOUND('',#429,.T.);
+#259=FACE_OUTER_BOUND('',#430,.T.);
+#260=FACE_OUTER_BOUND('',#436,.T.);
+#261=FACE_OUTER_BOUND('',#437,.T.);
+#262=FACE_OUTER_BOUND('',#438,.T.);
+#263=FACE_OUTER_BOUND('',#439,.T.);
+#264=FACE_OUTER_BOUND('',#440,.T.);
+#265=FACE_OUTER_BOUND('',#441,.T.);
+#266=FACE_OUTER_BOUND('',#442,.T.);
+#267=FACE_OUTER_BOUND('',#443,.T.);
+#268=FACE_OUTER_BOUND('',#444,.T.);
+#269=FACE_OUTER_BOUND('',#445,.T.);
+#270=FACE_OUTER_BOUND('',#446,.T.);
+#271=FACE_OUTER_BOUND('',#447,.T.);
+#272=FACE_OUTER_BOUND('',#448,.T.);
+#273=FACE_OUTER_BOUND('',#449,.T.);
+#274=FACE_OUTER_BOUND('',#450,.T.);
+#275=EDGE_LOOP('',(#1755,#1756,#1757,#1758));
+#276=EDGE_LOOP('',(#1759,#1760,#1761,#1762,#1763,#1764,#1765,#1766,#1767,
+#1768,#1769,#1770,#1771,#1772,#1773,#1774,#1775));
+#277=EDGE_LOOP('',(#1776));
+#278=EDGE_LOOP('',(#1777));
+#279=EDGE_LOOP('',(#1778));
+#280=EDGE_LOOP('',(#1779));
+#281=EDGE_LOOP('',(#1780,#1781,#1782,#1783));
+#282=EDGE_LOOP('',(#1784,#1785,#1786,#1787));
+#283=EDGE_LOOP('',(#1788,#1789,#1790,#1791));
+#284=EDGE_LOOP('',(#1792,#1793,#1794,#1795));
+#285=EDGE_LOOP('',(#1796,#1797,#1798,#1799));
+#286=EDGE_LOOP('',(#1800,#1801,#1802,#1803,#1804,#1805,#1806,#1807));
+#287=EDGE_LOOP('',(#1808,#1809,#1810,#1811));
+#288=EDGE_LOOP('',(#1812,#1813,#1814,#1815));
+#289=EDGE_LOOP('',(#1816,#1817,#1818,#1819));
+#290=EDGE_LOOP('',(#1820,#1821,#1822,#1823));
+#291=EDGE_LOOP('',(#1824,#1825,#1826,#1827,#1828));
+#292=EDGE_LOOP('',(#1829,#1830,#1831,#1832));
+#293=EDGE_LOOP('',(#1833,#1834,#1835,#1836));
+#294=EDGE_LOOP('',(#1837,#1838,#1839,#1840,#1841,#1842,#1843,#1844));
+#295=EDGE_LOOP('',(#1845,#1846,#1847,#1848));
+#296=EDGE_LOOP('',(#1849,#1850,#1851,#1852));
+#297=EDGE_LOOP('',(#1853,#1854,#1855,#1856));
+#298=EDGE_LOOP('',(#1857,#1858,#1859,#1860));
+#299=EDGE_LOOP('',(#1861,#1862,#1863,#1864));
+#300=EDGE_LOOP('',(#1865,#1866,#1867,#1868));
+#301=EDGE_LOOP('',(#1869,#1870,#1871,#1872,#1873,#1874,#1875,#1876));
+#302=EDGE_LOOP('',(#1877));
+#303=EDGE_LOOP('',(#1878));
+#304=EDGE_LOOP('',(#1879));
+#305=EDGE_LOOP('',(#1880));
+#306=EDGE_LOOP('',(#1881,#1882,#1883,#1884));
+#307=EDGE_LOOP('',(#1885,#1886,#1887,#1888));
+#308=EDGE_LOOP('',(#1889,#1890,#1891,#1892,#1893,#1894,#1895,#1896,#1897,
+#1898,#1899,#1900));
+#309=EDGE_LOOP('',(#1901,#1902,#1903,#1904));
+#310=EDGE_LOOP('',(#1905,#1906,#1907,#1908,#1909,#1910,#1911,#1912));
+#311=EDGE_LOOP('',(#1913,#1914,#1915,#1916,#1917,#1918,#1919,#1920));
+#312=EDGE_LOOP('',(#1921,#1922,#1923,#1924,#1925,#1926,#1927,#1928));
+#313=EDGE_LOOP('',(#1929,#1930,#1931,#1932,#1933,#1934,#1935,#1936));
+#314=EDGE_LOOP('',(#1937,#1938,#1939,#1940,#1941,#1942,#1943,#1944));
+#315=EDGE_LOOP('',(#1945,#1946,#1947,#1948,#1949,#1950,#1951,#1952));
+#316=EDGE_LOOP('',(#1953,#1954,#1955,#1956,#1957,#1958,#1959,#1960));
+#317=EDGE_LOOP('',(#1961,#1962,#1963,#1964,#1965,#1966,#1967,#1968));
+#318=EDGE_LOOP('',(#1969,#1970,#1971,#1972,#1973,#1974,#1975,#1976));
+#319=EDGE_LOOP('',(#1977));
+#320=EDGE_LOOP('',(#1978));
+#321=EDGE_LOOP('',(#1979));
+#322=EDGE_LOOP('',(#1980));
+#323=EDGE_LOOP('',(#1981,#1982,#1983,#1984));
+#324=EDGE_LOOP('',(#1985,#1986,#1987,#1988));
+#325=EDGE_LOOP('',(#1989,#1990,#1991,#1992));
+#326=EDGE_LOOP('',(#1993,#1994,#1995,#1996));
+#327=EDGE_LOOP('',(#1997,#1998,#1999,#2000));
+#328=EDGE_LOOP('',(#2001,#2002,#2003,#2004));
+#329=EDGE_LOOP('',(#2005,#2006,#2007,#2008));
+#330=EDGE_LOOP('',(#2009,#2010,#2011,#2012));
+#331=EDGE_LOOP('',(#2013,#2014,#2015,#2016));
+#332=EDGE_LOOP('',(#2017,#2018,#2019,#2020));
+#333=EDGE_LOOP('',(#2021,#2022,#2023,#2024));
+#334=EDGE_LOOP('',(#2025,#2026,#2027,#2028));
+#335=EDGE_LOOP('',(#2029,#2030,#2031,#2032));
+#336=EDGE_LOOP('',(#2033,#2034,#2035,#2036));
+#337=EDGE_LOOP('',(#2037,#2038,#2039,#2040));
+#338=EDGE_LOOP('',(#2041,#2042,#2043,#2044));
+#339=EDGE_LOOP('',(#2045,#2046,#2047,#2048));
+#340=EDGE_LOOP('',(#2049,#2050,#2051,#2052));
+#341=EDGE_LOOP('',(#2053,#2054,#2055,#2056));
+#342=EDGE_LOOP('',(#2057,#2058,#2059,#2060));
+#343=EDGE_LOOP('',(#2061,#2062,#2063,#2064));
+#344=EDGE_LOOP('',(#2065,#2066,#2067,#2068));
+#345=EDGE_LOOP('',(#2069,#2070,#2071,#2072));
+#346=EDGE_LOOP('',(#2073,#2074,#2075,#2076));
+#347=EDGE_LOOP('',(#2077,#2078,#2079,#2080));
+#348=EDGE_LOOP('',(#2081,#2082,#2083,#2084));
+#349=EDGE_LOOP('',(#2085,#2086,#2087,#2088));
+#350=EDGE_LOOP('',(#2089,#2090,#2091,#2092));
+#351=EDGE_LOOP('',(#2093,#2094,#2095,#2096));
+#352=EDGE_LOOP('',(#2097,#2098,#2099,#2100));
+#353=EDGE_LOOP('',(#2101,#2102,#2103,#2104));
+#354=EDGE_LOOP('',(#2105,#2106,#2107,#2108));
+#355=EDGE_LOOP('',(#2109,#2110,#2111,#2112));
+#356=EDGE_LOOP('',(#2113,#2114,#2115,#2116));
+#357=EDGE_LOOP('',(#2117,#2118,#2119,#2120));
+#358=EDGE_LOOP('',(#2121,#2122,#2123,#2124));
+#359=EDGE_LOOP('',(#2125,#2126,#2127,#2128));
+#360=EDGE_LOOP('',(#2129,#2130,#2131,#2132));
+#361=EDGE_LOOP('',(#2133,#2134,#2135,#2136));
+#362=EDGE_LOOP('',(#2137,#2138,#2139,#2140));
+#363=EDGE_LOOP('',(#2141,#2142,#2143,#2144));
+#364=EDGE_LOOP('',(#2145,#2146,#2147,#2148));
+#365=EDGE_LOOP('',(#2149,#2150,#2151,#2152));
+#366=EDGE_LOOP('',(#2153,#2154,#2155,#2156));
+#367=EDGE_LOOP('',(#2157,#2158,#2159,#2160));
+#368=EDGE_LOOP('',(#2161,#2162,#2163,#2164));
+#369=EDGE_LOOP('',(#2165,#2166,#2167,#2168));
+#370=EDGE_LOOP('',(#2169,#2170,#2171,#2172));
+#371=EDGE_LOOP('',(#2173,#2174,#2175,#2176));
+#372=EDGE_LOOP('',(#2177,#2178,#2179,#2180));
+#373=EDGE_LOOP('',(#2181,#2182,#2183,#2184));
+#374=EDGE_LOOP('',(#2185,#2186,#2187,#2188));
+#375=EDGE_LOOP('',(#2189,#2190,#2191,#2192));
+#376=EDGE_LOOP('',(#2193,#2194,#2195,#2196));
+#377=EDGE_LOOP('',(#2197,#2198,#2199,#2200));
+#378=EDGE_LOOP('',(#2201,#2202,#2203,#2204));
+#379=EDGE_LOOP('',(#2205,#2206,#2207,#2208));
+#380=EDGE_LOOP('',(#2209,#2210,#2211,#2212));
+#381=EDGE_LOOP('',(#2213,#2214,#2215,#2216));
+#382=EDGE_LOOP('',(#2217,#2218,#2219,#2220));
+#383=EDGE_LOOP('',(#2221,#2222,#2223,#2224));
+#384=EDGE_LOOP('',(#2225,#2226,#2227,#2228));
+#385=EDGE_LOOP('',(#2229,#2230,#2231,#2232));
+#386=EDGE_LOOP('',(#2233,#2234,#2235,#2236));
+#387=EDGE_LOOP('',(#2237,#2238,#2239,#2240));
+#388=EDGE_LOOP('',(#2241,#2242,#2243,#2244));
+#389=EDGE_LOOP('',(#2245,#2246,#2247,#2248));
+#390=EDGE_LOOP('',(#2249,#2250,#2251,#2252));
+#391=EDGE_LOOP('',(#2253,#2254,#2255,#2256));
+#392=EDGE_LOOP('',(#2257,#2258,#2259,#2260));
+#393=EDGE_LOOP('',(#2261,#2262,#2263,#2264));
+#394=EDGE_LOOP('',(#2265,#2266,#2267,#2268));
+#395=EDGE_LOOP('',(#2269,#2270,#2271,#2272));
+#396=EDGE_LOOP('',(#2273,#2274,#2275,#2276));
+#397=EDGE_LOOP('',(#2277,#2278,#2279,#2280));
+#398=EDGE_LOOP('',(#2281,#2282,#2283,#2284));
+#399=EDGE_LOOP('',(#2285,#2286,#2287,#2288));
+#400=EDGE_LOOP('',(#2289,#2290,#2291,#2292));
+#401=EDGE_LOOP('',(#2293,#2294,#2295,#2296));
+#402=EDGE_LOOP('',(#2297,#2298,#2299,#2300));
+#403=EDGE_LOOP('',(#2301,#2302,#2303,#2304));
+#404=EDGE_LOOP('',(#2305,#2306,#2307,#2308));
+#405=EDGE_LOOP('',(#2309,#2310,#2311,#2312));
+#406=EDGE_LOOP('',(#2313,#2314,#2315,#2316));
+#407=EDGE_LOOP('',(#2317,#2318,#2319,#2320));
+#408=EDGE_LOOP('',(#2321,#2322,#2323,#2324));
+#409=EDGE_LOOP('',(#2325,#2326,#2327,#2328));
+#410=EDGE_LOOP('',(#2329,#2330,#2331,#2332));
+#411=EDGE_LOOP('',(#2333,#2334,#2335,#2336));
+#412=EDGE_LOOP('',(#2337,#2338,#2339,#2340));
+#413=EDGE_LOOP('',(#2341,#2342,#2343,#2344,#2345,#2346,#2347,#2348,#2349,
+#2350,#2351,#2352));
+#414=EDGE_LOOP('',(#2353,#2354,#2355,#2356));
+#415=EDGE_LOOP('',(#2357,#2358,#2359,#2360,#2361,#2362,#2363,#2364));
+#416=EDGE_LOOP('',(#2365,#2366,#2367,#2368,#2369,#2370,#2371,#2372));
+#417=EDGE_LOOP('',(#2373,#2374,#2375,#2376,#2377,#2378,#2379,#2380));
+#418=EDGE_LOOP('',(#2381,#2382,#2383,#2384,#2385,#2386,#2387,#2388));
+#419=EDGE_LOOP('',(#2389,#2390,#2391,#2392,#2393,#2394,#2395,#2396));
+#420=EDGE_LOOP('',(#2397,#2398,#2399,#2400,#2401,#2402,#2403,#2404));
+#421=EDGE_LOOP('',(#2405,#2406,#2407,#2408,#2409,#2410,#2411,#2412));
+#422=EDGE_LOOP('',(#2413,#2414,#2415,#2416,#2417,#2418,#2419,#2420));
+#423=EDGE_LOOP('',(#2421,#2422,#2423,#2424,#2425,#2426,#2427,#2428));
+#424=EDGE_LOOP('',(#2429));
+#425=EDGE_LOOP('',(#2430));
+#426=EDGE_LOOP('',(#2431));
+#427=EDGE_LOOP('',(#2432));
+#428=EDGE_LOOP('',(#2433,#2434,#2435,#2436));
+#429=EDGE_LOOP('',(#2437,#2438,#2439,#2440));
+#430=EDGE_LOOP('',(#2441,#2442,#2443,#2444,#2445,#2446,#2447,#2448));
+#431=EDGE_LOOP('',(#2449));
+#432=EDGE_LOOP('',(#2450,#2451,#2452,#2453));
+#433=EDGE_LOOP('',(#2454));
+#434=EDGE_LOOP('',(#2455));
+#435=EDGE_LOOP('',(#2456));
+#436=EDGE_LOOP('',(#2457,#2458,#2459,#2460));
+#437=EDGE_LOOP('',(#2461,#2462,#2463,#2464));
+#438=EDGE_LOOP('',(#2465,#2466,#2467,#2468));
+#439=EDGE_LOOP('',(#2469,#2470,#2471,#2472));
+#440=EDGE_LOOP('',(#2473,#2474,#2475,#2476));
+#441=EDGE_LOOP('',(#2477,#2478,#2479,#2480));
+#442=EDGE_LOOP('',(#2481,#2482,#2483,#2484));
+#443=EDGE_LOOP('',(#2485,#2486,#2487,#2488));
+#444=EDGE_LOOP('',(#2489,#2490,#2491,#2492));
+#445=EDGE_LOOP('',(#2493,#2494,#2495,#2496));
+#446=EDGE_LOOP('',(#2497,#2498,#2499,#2500));
+#447=EDGE_LOOP('',(#2501,#2502,#2503,#2504));
+#448=EDGE_LOOP('',(#2505,#2506,#2507,#2508));
+#449=EDGE_LOOP('',(#2509,#2510,#2511,#2512));
+#450=EDGE_LOOP('',(#2513,#2514,#2515,#2516,#2517,#2518,#2519,#2520));
+#451=EDGE_LOOP('',(#2521));
+#452=EDGE_LOOP('',(#2522,#2523,#2524,#2525));
+#453=EDGE_LOOP('',(#2526));
+#454=EDGE_LOOP('',(#2527));
+#455=EDGE_LOOP('',(#2528));
+#456=LINE('',#3768,#723);
+#457=LINE('',#3771,#724);
+#458=LINE('',#3774,#725);
+#459=LINE('',#3778,#726);
+#460=LINE('',#3782,#727);
+#461=LINE('',#3786,#728);
+#462=LINE('',#3788,#729);
+#463=LINE('',#3790,#730);
+#464=LINE('',#3792,#731);
+#465=LINE('',#3794,#732);
+#466=LINE('',#3796,#733);
+#467=LINE('',#3798,#734);
+#468=LINE('',#3800,#735);
+#469=LINE('',#3802,#736);
+#470=LINE('',#3803,#737);
+#471=LINE('',#3814,#738);
+#472=LINE('',#3815,#739);
+#473=LINE('',#3819,#740);
+#474=LINE('',#3822,#741);
+#475=LINE('',#3825,#742);
+#476=LINE('',#3828,#743);
+#477=LINE('',#3829,#744);
+#478=LINE('',#3833,#745);
+#479=LINE('',#3836,#746);
+#480=LINE('',#3838,#747);
+#481=LINE('',#3839,#748);
+#482=LINE('',#3840,#749);
+#483=LINE('',#3843,#750);
+#484=LINE('',#3844,#751);
+#485=LINE('',#3847,#752);
+#486=LINE('',#3848,#753);
+#487=LINE('',#3850,#754);
+#488=LINE('',#3853,#755);
+#489=LINE('',#3854,#756);
+#490=LINE('',#3856,#757);
+#491=LINE('',#3860,#758);
+#492=LINE('',#3861,#759);
+#493=LINE('',#3862,#760);
+#494=LINE('',#3865,#761);
+#495=LINE('',#3866,#762);
+#496=LINE('',#3869,#763);
+#497=LINE('',#3870,#764);
+#498=LINE('',#3872,#765);
+#499=LINE('',#3875,#766);
+#500=LINE('',#3879,#767);
+#501=LINE('',#3883,#768);
+#502=LINE('',#3887,#769);
+#503=LINE('',#3896,#770);
+#504=LINE('',#3899,#771);
+#505=LINE('',#3902,#772);
+#506=LINE('',#3904,#773);
+#507=LINE('',#3905,#774);
+#508=LINE('',#3908,#775);
+#509=LINE('',#3912,#776);
+#510=LINE('',#3916,#777);
+#511=LINE('',#3920,#778);
+#512=LINE('',#3922,#779);
+#513=LINE('',#3924,#780);
+#514=LINE('',#3925,#781);
+#515=LINE('',#3928,#782);
+#516=LINE('',#3930,#783);
+#517=LINE('',#3932,#784);
+#518=LINE('',#3933,#785);
+#519=LINE('',#3936,#786);
+#520=LINE('',#3940,#787);
+#521=LINE('',#3944,#788);
+#522=LINE('',#3948,#789);
+#523=LINE('',#3952,#790);
+#524=LINE('',#3956,#791);
+#525=LINE('',#3960,#792);
+#526=LINE('',#3964,#793);
+#527=LINE('',#3968,#794);
+#528=LINE('',#3972,#795);
+#529=LINE('',#3976,#796);
+#530=LINE('',#3980,#797);
+#531=LINE('',#3984,#798);
+#532=LINE('',#3988,#799);
+#533=LINE('',#3992,#800);
+#534=LINE('',#3996,#801);
+#535=LINE('',#4000,#802);
+#536=LINE('',#4004,#803);
+#537=LINE('',#4008,#804);
+#538=LINE('',#4012,#805);
+#539=LINE('',#4016,#806);
+#540=LINE('',#4020,#807);
+#541=LINE('',#4024,#808);
+#542=LINE('',#4028,#809);
+#543=LINE('',#4032,#810);
+#544=LINE('',#4036,#811);
+#545=LINE('',#4040,#812);
+#546=LINE('',#4044,#813);
+#547=LINE('',#4048,#814);
+#548=LINE('',#4052,#815);
+#549=LINE('',#4056,#816);
+#550=LINE('',#4060,#817);
+#551=LINE('',#4064,#818);
+#552=LINE('',#4068,#819);
+#553=LINE('',#4072,#820);
+#554=LINE('',#4076,#821);
+#555=LINE('',#4090,#822);
+#556=LINE('',#4091,#823);
+#557=LINE('',#4094,#824);
+#558=LINE('',#4095,#825);
+#559=LINE('',#4099,#826);
+#560=LINE('',#4104,#827);
+#561=LINE('',#4105,#828);
+#562=LINE('',#4108,#829);
+#563=LINE('',#4109,#830);
+#564=LINE('',#4113,#831);
+#565=LINE('',#4117,#832);
+#566=LINE('',#4121,#833);
+#567=LINE('',#4125,#834);
+#568=LINE('',#4128,#835);
+#569=LINE('',#4131,#836);
+#570=LINE('',#4134,#837);
+#571=LINE('',#4135,#838);
+#572=LINE('',#4139,#839);
+#573=LINE('',#4142,#840);
+#574=LINE('',#4143,#841);
+#575=LINE('',#4147,#842);
+#576=LINE('',#4150,#843);
+#577=LINE('',#4151,#844);
+#578=LINE('',#4155,#845);
+#579=LINE('',#4157,#846);
+#580=LINE('',#4160,#847);
+#581=LINE('',#4163,#848);
+#582=LINE('',#4166,#849);
+#583=LINE('',#4167,#850);
+#584=LINE('',#4171,#851);
+#585=LINE('',#4174,#852);
+#586=LINE('',#4175,#853);
+#587=LINE('',#4179,#854);
+#588=LINE('',#4182,#855);
+#589=LINE('',#4183,#856);
+#590=LINE('',#4187,#857);
+#591=LINE('',#4189,#858);
+#592=LINE('',#4192,#859);
+#593=LINE('',#4195,#860);
+#594=LINE('',#4198,#861);
+#595=LINE('',#4199,#862);
+#596=LINE('',#4203,#863);
+#597=LINE('',#4206,#864);
+#598=LINE('',#4207,#865);
+#599=LINE('',#4211,#866);
+#600=LINE('',#4214,#867);
+#601=LINE('',#4215,#868);
+#602=LINE('',#4219,#869);
+#603=LINE('',#4221,#870);
+#604=LINE('',#4224,#871);
+#605=LINE('',#4227,#872);
+#606=LINE('',#4230,#873);
+#607=LINE('',#4231,#874);
+#608=LINE('',#4235,#875);
+#609=LINE('',#4238,#876);
+#610=LINE('',#4239,#877);
+#611=LINE('',#4243,#878);
+#612=LINE('',#4246,#879);
+#613=LINE('',#4247,#880);
+#614=LINE('',#4251,#881);
+#615=LINE('',#4253,#882);
+#616=LINE('',#4256,#883);
+#617=LINE('',#4259,#884);
+#618=LINE('',#4262,#885);
+#619=LINE('',#4263,#886);
+#620=LINE('',#4267,#887);
+#621=LINE('',#4270,#888);
+#622=LINE('',#4271,#889);
+#623=LINE('',#4275,#890);
+#624=LINE('',#4278,#891);
+#625=LINE('',#4279,#892);
+#626=LINE('',#4283,#893);
+#627=LINE('',#4285,#894);
+#628=LINE('',#4288,#895);
+#629=LINE('',#4291,#896);
+#630=LINE('',#4294,#897);
+#631=LINE('',#4295,#898);
+#632=LINE('',#4299,#899);
+#633=LINE('',#4302,#900);
+#634=LINE('',#4303,#901);
+#635=LINE('',#4307,#902);
+#636=LINE('',#4310,#903);
+#637=LINE('',#4311,#904);
+#638=LINE('',#4315,#905);
+#639=LINE('',#4317,#906);
+#640=LINE('',#4320,#907);
+#641=LINE('',#4323,#908);
+#642=LINE('',#4326,#909);
+#643=LINE('',#4327,#910);
+#644=LINE('',#4331,#911);
+#645=LINE('',#4334,#912);
+#646=LINE('',#4335,#913);
+#647=LINE('',#4339,#914);
+#648=LINE('',#4342,#915);
+#649=LINE('',#4343,#916);
+#650=LINE('',#4347,#917);
+#651=LINE('',#4349,#918);
+#652=LINE('',#4352,#919);
+#653=LINE('',#4355,#920);
+#654=LINE('',#4358,#921);
+#655=LINE('',#4359,#922);
+#656=LINE('',#4363,#923);
+#657=LINE('',#4366,#924);
+#658=LINE('',#4367,#925);
+#659=LINE('',#4371,#926);
+#660=LINE('',#4374,#927);
+#661=LINE('',#4375,#928);
+#662=LINE('',#4379,#929);
+#663=LINE('',#4381,#930);
+#664=LINE('',#4384,#931);
+#665=LINE('',#4387,#932);
+#666=LINE('',#4390,#933);
+#667=LINE('',#4391,#934);
+#668=LINE('',#4395,#935);
+#669=LINE('',#4398,#936);
+#670=LINE('',#4399,#937);
+#671=LINE('',#4403,#938);
+#672=LINE('',#4406,#939);
+#673=LINE('',#4407,#940);
+#674=LINE('',#4411,#941);
+#675=LINE('',#4413,#942);
+#676=LINE('',#4416,#943);
+#677=LINE('',#4418,#944);
+#678=LINE('',#4419,#945);
+#679=LINE('',#4422,#946);
+#680=LINE('',#4423,#947);
+#681=LINE('',#4426,#948);
+#682=LINE('',#4427,#949);
+#683=LINE('',#4429,#950);
+#684=LINE('',#4432,#951);
+#685=LINE('',#4434,#952);
+#686=LINE('',#4435,#953);
+#687=LINE('',#4437,#954);
+#688=LINE('',#4439,#955);
+#689=LINE('',#4441,#956);
+#690=LINE('',#4443,#957);
+#691=LINE('',#4450,#958);
+#692=LINE('',#4453,#959);
+#693=LINE('',#4456,#960);
+#694=LINE('',#4458,#961);
+#695=LINE('',#4459,#962);
+#696=LINE('',#4462,#963);
+#697=LINE('',#4466,#964);
+#698=LINE('',#4470,#965);
+#699=LINE('',#4476,#966);
+#700=LINE('',#4478,#967);
+#701=LINE('',#4480,#968);
+#702=LINE('',#4481,#969);
+#703=LINE('',#4491,#970);
+#704=LINE('',#4494,#971);
+#705=LINE('',#4495,#972);
+#706=LINE('',#4499,#973);
+#707=LINE('',#4502,#974);
+#708=LINE('',#4503,#975);
+#709=LINE('',#4507,#976);
+#710=LINE('',#4511,#977);
+#711=LINE('',#4515,#978);
+#712=LINE('',#4519,#979);
+#713=LINE('',#4522,#980);
+#714=LINE('',#4524,#981);
+#715=LINE('',#4525,#982);
+#716=LINE('',#4528,#983);
+#717=LINE('',#4529,#984);
+#718=LINE('',#4532,#985);
+#719=LINE('',#4533,#986);
+#720=LINE('',#4535,#987);
+#721=LINE('',#4539,#988);
+#722=LINE('',#4541,#989);
+#723=VECTOR('',#2989,10.);
+#724=VECTOR('',#2992,10.);
+#725=VECTOR('',#2995,10.);
+#726=VECTOR('',#2998,10.);
+#727=VECTOR('',#3001,10.);
+#728=VECTOR('',#3004,10.);
+#729=VECTOR('',#3005,10.);
+#730=VECTOR('',#3006,10.);
+#731=VECTOR('',#3007,10.);
+#732=VECTOR('',#3008,10.);
+#733=VECTOR('',#3009,10.);
+#734=VECTOR('',#3010,10.);
+#735=VECTOR('',#3011,10.);
+#736=VECTOR('',#3012,10.);
+#737=VECTOR('',#3013,10.);
+#738=VECTOR('',#3024,10.);
+#739=VECTOR('',#3025,10.);
+#740=VECTOR('',#3030,10.);
+#741=VECTOR('',#3033,10.);
+#742=VECTOR('',#3036,10.);
+#743=VECTOR('',#3039,10.);
+#744=VECTOR('',#3040,10.);
+#745=VECTOR('',#3045,10.);
+#746=VECTOR('',#3048,10.);
+#747=VECTOR('',#3049,10.);
+#748=VECTOR('',#3050,10.);
+#749=VECTOR('',#3051,10.);
+#750=VECTOR('',#3054,10.);
+#751=VECTOR('',#3055,10.);
+#752=VECTOR('',#3058,10.);
+#753=VECTOR('',#3059,10.);
+#754=VECTOR('',#3062,10.);
+#755=VECTOR('',#3065,10.);
+#756=VECTOR('',#3066,10.);
+#757=VECTOR('',#3069,10.);
+#758=VECTOR('',#3072,10.);
+#759=VECTOR('',#3073,10.);
+#760=VECTOR('',#3074,10.);
+#761=VECTOR('',#3077,10.);
+#762=VECTOR('',#3078,10.);
+#763=VECTOR('',#3081,10.);
+#764=VECTOR('',#3082,10.);
+#765=VECTOR('',#3085,10.);
+#766=VECTOR('',#3088,1.45);
+#767=VECTOR('',#3093,1.45);
+#768=VECTOR('',#3098,1.45);
+#769=VECTOR('',#3103,1.45);
+#770=VECTOR('',#3114,10.);
+#771=VECTOR('',#3117,10.);
+#772=VECTOR('',#3120,10.);
+#773=VECTOR('',#3121,10.);
+#774=VECTOR('',#3122,10.);
+#775=VECTOR('',#3125,10.);
+#776=VECTOR('',#3128,10.);
+#777=VECTOR('',#3131,10.);
+#778=VECTOR('',#3134,10.);
+#779=VECTOR('',#3135,10.);
+#780=VECTOR('',#3136,10.);
+#781=VECTOR('',#3137,10.);
+#782=VECTOR('',#3138,10.);
+#783=VECTOR('',#3139,10.);
+#784=VECTOR('',#3140,10.);
+#785=VECTOR('',#3141,10.);
+#786=VECTOR('',#3142,10.);
+#787=VECTOR('',#3145,10.);
+#788=VECTOR('',#3148,10.);
+#789=VECTOR('',#3151,10.);
+#790=VECTOR('',#3154,10.);
+#791=VECTOR('',#3157,10.);
+#792=VECTOR('',#3160,10.);
+#793=VECTOR('',#3163,10.);
+#794=VECTOR('',#3166,10.);
+#795=VECTOR('',#3169,10.);
+#796=VECTOR('',#3172,10.);
+#797=VECTOR('',#3175,10.);
+#798=VECTOR('',#3178,10.);
+#799=VECTOR('',#3181,10.);
+#800=VECTOR('',#3184,10.);
+#801=VECTOR('',#3187,10.);
+#802=VECTOR('',#3190,10.);
+#803=VECTOR('',#3193,10.);
+#804=VECTOR('',#3196,10.);
+#805=VECTOR('',#3199,10.);
+#806=VECTOR('',#3202,10.);
+#807=VECTOR('',#3205,10.);
+#808=VECTOR('',#3208,10.);
+#809=VECTOR('',#3211,10.);
+#810=VECTOR('',#3214,10.);
+#811=VECTOR('',#3217,10.);
+#812=VECTOR('',#3220,10.);
+#813=VECTOR('',#3223,10.);
+#814=VECTOR('',#3226,10.);
+#815=VECTOR('',#3229,10.);
+#816=VECTOR('',#3232,10.);
+#817=VECTOR('',#3235,10.);
+#818=VECTOR('',#3238,10.);
+#819=VECTOR('',#3241,10.);
+#820=VECTOR('',#3244,10.);
+#821=VECTOR('',#3247,10.);
+#822=VECTOR('',#3262,10.);
+#823=VECTOR('',#3263,10.);
+#824=VECTOR('',#3266,10.);
+#825=VECTOR('',#3267,10.);
+#826=VECTOR('',#3272,10.);
+#827=VECTOR('',#3277,10.);
+#828=VECTOR('',#3278,10.);
+#829=VECTOR('',#3281,10.);
+#830=VECTOR('',#3282,10.);
+#831=VECTOR('',#3287,1.45);
+#832=VECTOR('',#3292,1.45);
+#833=VECTOR('',#3297,1.45);
+#834=VECTOR('',#3302,1.45);
+#835=VECTOR('',#3305,10.);
+#836=VECTOR('',#3308,10.);
+#837=VECTOR('',#3311,10.);
+#838=VECTOR('',#3312,10.);
+#839=VECTOR('',#3317,10.);
+#840=VECTOR('',#3320,10.);
+#841=VECTOR('',#3321,10.);
+#842=VECTOR('',#3326,10.);
+#843=VECTOR('',#3329,10.);
+#844=VECTOR('',#3330,10.);
+#845=VECTOR('',#3335,10.);
+#846=VECTOR('',#3338,10.);
+#847=VECTOR('',#3341,10.);
+#848=VECTOR('',#3344,10.);
+#849=VECTOR('',#3347,10.);
+#850=VECTOR('',#3348,10.);
+#851=VECTOR('',#3353,10.);
+#852=VECTOR('',#3356,10.);
+#853=VECTOR('',#3357,10.);
+#854=VECTOR('',#3362,10.);
+#855=VECTOR('',#3365,10.);
+#856=VECTOR('',#3366,10.);
+#857=VECTOR('',#3371,10.);
+#858=VECTOR('',#3374,10.);
+#859=VECTOR('',#3377,10.);
+#860=VECTOR('',#3380,10.);
+#861=VECTOR('',#3383,10.);
+#862=VECTOR('',#3384,10.);
+#863=VECTOR('',#3389,10.);
+#864=VECTOR('',#3392,10.);
+#865=VECTOR('',#3393,10.);
+#866=VECTOR('',#3398,10.);
+#867=VECTOR('',#3401,10.);
+#868=VECTOR('',#3402,10.);
+#869=VECTOR('',#3407,10.);
+#870=VECTOR('',#3410,10.);
+#871=VECTOR('',#3413,10.);
+#872=VECTOR('',#3416,10.);
+#873=VECTOR('',#3419,10.);
+#874=VECTOR('',#3420,10.);
+#875=VECTOR('',#3425,10.);
+#876=VECTOR('',#3428,10.);
+#877=VECTOR('',#3429,10.);
+#878=VECTOR('',#3434,10.);
+#879=VECTOR('',#3437,10.);
+#880=VECTOR('',#3438,10.);
+#881=VECTOR('',#3443,10.);
+#882=VECTOR('',#3446,10.);
+#883=VECTOR('',#3449,10.);
+#884=VECTOR('',#3452,10.);
+#885=VECTOR('',#3455,10.);
+#886=VECTOR('',#3456,10.);
+#887=VECTOR('',#3461,10.);
+#888=VECTOR('',#3464,10.);
+#889=VECTOR('',#3465,10.);
+#890=VECTOR('',#3470,10.);
+#891=VECTOR('',#3473,10.);
+#892=VECTOR('',#3474,10.);
+#893=VECTOR('',#3479,10.);
+#894=VECTOR('',#3482,10.);
+#895=VECTOR('',#3485,10.);
+#896=VECTOR('',#3488,10.);
+#897=VECTOR('',#3491,10.);
+#898=VECTOR('',#3492,10.);
+#899=VECTOR('',#3497,10.);
+#900=VECTOR('',#3500,10.);
+#901=VECTOR('',#3501,10.);
+#902=VECTOR('',#3506,10.);
+#903=VECTOR('',#3509,10.);
+#904=VECTOR('',#3510,10.);
+#905=VECTOR('',#3515,10.);
+#906=VECTOR('',#3518,10.);
+#907=VECTOR('',#3521,10.);
+#908=VECTOR('',#3524,10.);
+#909=VECTOR('',#3527,10.);
+#910=VECTOR('',#3528,10.);
+#911=VECTOR('',#3533,10.);
+#912=VECTOR('',#3536,10.);
+#913=VECTOR('',#3537,10.);
+#914=VECTOR('',#3542,10.);
+#915=VECTOR('',#3545,10.);
+#916=VECTOR('',#3546,10.);
+#917=VECTOR('',#3551,10.);
+#918=VECTOR('',#3554,10.);
+#919=VECTOR('',#3557,10.);
+#920=VECTOR('',#3560,10.);
+#921=VECTOR('',#3563,10.);
+#922=VECTOR('',#3564,10.);
+#923=VECTOR('',#3569,10.);
+#924=VECTOR('',#3572,10.);
+#925=VECTOR('',#3573,10.);
+#926=VECTOR('',#3578,10.);
+#927=VECTOR('',#3581,10.);
+#928=VECTOR('',#3582,10.);
+#929=VECTOR('',#3587,10.);
+#930=VECTOR('',#3590,10.);
+#931=VECTOR('',#3593,10.);
+#932=VECTOR('',#3596,10.);
+#933=VECTOR('',#3599,10.);
+#934=VECTOR('',#3600,10.);
+#935=VECTOR('',#3605,10.);
+#936=VECTOR('',#3608,10.);
+#937=VECTOR('',#3609,10.);
+#938=VECTOR('',#3614,10.);
+#939=VECTOR('',#3617,10.);
+#940=VECTOR('',#3618,10.);
+#941=VECTOR('',#3623,10.);
+#942=VECTOR('',#3626,10.);
+#943=VECTOR('',#3629,10.);
+#944=VECTOR('',#3630,10.);
+#945=VECTOR('',#3631,10.);
+#946=VECTOR('',#3634,10.);
+#947=VECTOR('',#3635,10.);
+#948=VECTOR('',#3638,10.);
+#949=VECTOR('',#3639,10.);
+#950=VECTOR('',#3642,10.);
+#951=VECTOR('',#3645,10.);
+#952=VECTOR('',#3646,10.);
+#953=VECTOR('',#3647,10.);
+#954=VECTOR('',#3650,10.);
+#955=VECTOR('',#3653,10.);
+#956=VECTOR('',#3656,10.);
+#957=VECTOR('',#3659,10.);
+#958=VECTOR('',#3666,10.);
+#959=VECTOR('',#3669,10.);
+#960=VECTOR('',#3672,10.);
+#961=VECTOR('',#3673,10.);
+#962=VECTOR('',#3674,10.);
+#963=VECTOR('',#3677,10.);
+#964=VECTOR('',#3680,10.);
+#965=VECTOR('',#3683,10.);
+#966=VECTOR('',#3688,10.);
+#967=VECTOR('',#3689,10.);
+#968=VECTOR('',#3690,10.);
+#969=VECTOR('',#3691,10.);
+#970=VECTOR('',#3702,10.);
+#971=VECTOR('',#3705,10.);
+#972=VECTOR('',#3706,10.);
+#973=VECTOR('',#3711,10.);
+#974=VECTOR('',#3714,10.);
+#975=VECTOR('',#3715,10.);
+#976=VECTOR('',#3720,10.);
+#977=VECTOR('',#3725,1.45);
+#978=VECTOR('',#3730,1.45);
+#979=VECTOR('',#3735,1.45);
+#980=VECTOR('',#3738,10.);
+#981=VECTOR('',#3739,10.);
+#982=VECTOR('',#3740,10.);
+#983=VECTOR('',#3743,10.);
+#984=VECTOR('',#3744,10.);
+#985=VECTOR('',#3747,10.);
+#986=VECTOR('',#3748,10.);
+#987=VECTOR('',#3751,10.);
+#988=VECTOR('',#3756,1.45);
+#989=VECTOR('',#3759,10.);
+#990=CIRCLE('',#2729,5.);
+#991=CIRCLE('',#2730,5.);
+#992=CIRCLE('',#2732,5.);
+#993=CIRCLE('',#2733,5.);
+#994=CIRCLE('',#2734,5.);
+#995=CIRCLE('',#2735,1.45);
+#996=CIRCLE('',#2736,1.45);
+#997=CIRCLE('',#2737,1.45);
+#998=CIRCLE('',#2738,1.45);
+#999=CIRCLE('',#2741,5.);
+#1000=CIRCLE('',#2743,5.);
+#1001=CIRCLE('',#2746,5.);
+#1002=CIRCLE('',#2758,1.45);
+#1003=CIRCLE('',#2760,1.45);
+#1004=CIRCLE('',#2762,1.45);
+#1005=CIRCLE('',#2764,1.45);
+#1006=CIRCLE('',#2768,5.);
+#1007=CIRCLE('',#2769,5.);
+#1008=CIRCLE('',#2772,5.);
+#1009=CIRCLE('',#2773,5.);
+#1010=CIRCLE('',#2774,5.);
+#1011=CIRCLE('',#2775,0.499999999999998);
+#1012=CIRCLE('',#2776,0.499999999999998);
+#1013=CIRCLE('',#2777,0.499999999999998);
+#1014=CIRCLE('',#2778,0.499999999999989);
+#1015=CIRCLE('',#2779,0.499999999999998);
+#1016=CIRCLE('',#2780,0.499999999999998);
+#1017=CIRCLE('',#2781,0.499999999999998);
+#1018=CIRCLE('',#2782,0.499999999999998);
+#1019=CIRCLE('',#2783,0.499999999999998);
+#1020=CIRCLE('',#2784,0.499999999999998);
+#1021=CIRCLE('',#2785,0.499999999999998);
+#1022=CIRCLE('',#2786,0.499999999999998);
+#1023=CIRCLE('',#2787,0.500000000000003);
+#1024=CIRCLE('',#2788,0.5);
+#1025=CIRCLE('',#2789,0.499999999999998);
+#1026=CIRCLE('',#2790,0.499999999999998);
+#1027=CIRCLE('',#2791,0.500000000000003);
+#1028=CIRCLE('',#2792,0.499999999999998);
+#1029=CIRCLE('',#2793,0.499999999999998);
+#1030=CIRCLE('',#2794,0.499999999999989);
+#1031=CIRCLE('',#2795,0.500000000000003);
+#1032=CIRCLE('',#2796,0.499999999999998);
+#1033=CIRCLE('',#2797,0.499999999999998);
+#1034=CIRCLE('',#2798,0.499999999999998);
+#1035=CIRCLE('',#2799,0.499999999999998);
+#1036=CIRCLE('',#2800,0.5);
+#1037=CIRCLE('',#2801,0.499999999999998);
+#1038=CIRCLE('',#2802,0.499999999999998);
+#1039=CIRCLE('',#2803,0.500000000000003);
+#1040=CIRCLE('',#2804,0.499999999999998);
+#1041=CIRCLE('',#2805,0.499999999999998);
+#1042=CIRCLE('',#2806,0.499999999999998);
+#1043=CIRCLE('',#2807,0.499999999999998);
+#1044=CIRCLE('',#2808,0.499999999999998);
+#1045=CIRCLE('',#2809,0.499999999999998);
+#1046=CIRCLE('',#2810,0.499999999999989);
+#1047=CIRCLE('',#2811,1.45);
+#1048=CIRCLE('',#2812,1.45);
+#1049=CIRCLE('',#2813,1.45);
+#1050=CIRCLE('',#2814,1.45);
+#1051=CIRCLE('',#2816,5.);
+#1052=CIRCLE('',#2819,5.);
+#1053=CIRCLE('',#2821,5.);
+#1054=CIRCLE('',#2824,1.45);
+#1055=CIRCLE('',#2826,1.45);
+#1056=CIRCLE('',#2828,1.45);
+#1057=CIRCLE('',#2830,1.45);
+#1058=CIRCLE('',#2832,0.499999999999998);
+#1059=CIRCLE('',#2835,0.499999999999998);
+#1060=CIRCLE('',#2838,0.499999999999998);
+#1061=CIRCLE('',#2841,0.499999999999989);
+#1062=CIRCLE('',#2844,0.500000000000003);
+#1063=CIRCLE('',#2847,0.499999999999998);
+#1064=CIRCLE('',#2850,0.499999999999998);
+#1065=CIRCLE('',#2853,0.499999999999998);
+#1066=CIRCLE('',#2856,0.499999999999998);
+#1067=CIRCLE('',#2859,0.5);
+#1068=CIRCLE('',#2862,0.499999999999998);
+#1069=CIRCLE('',#2865,0.499999999999998);
+#1070=CIRCLE('',#2868,0.500000000000003);
+#1071=CIRCLE('',#2871,0.499999999999998);
+#1072=CIRCLE('',#2874,0.499999999999998);
+#1073=CIRCLE('',#2877,0.499999999999998);
+#1074=CIRCLE('',#2880,0.500000000000003);
+#1075=CIRCLE('',#2883,0.499999999999998);
+#1076=CIRCLE('',#2886,0.499999999999998);
+#1077=CIRCLE('',#2889,0.499999999999989);
+#1078=CIRCLE('',#2892,0.500000000000003);
+#1079=CIRCLE('',#2895,0.5);
+#1080=CIRCLE('',#2898,0.499999999999998);
+#1081=CIRCLE('',#2901,0.499999999999998);
+#1082=CIRCLE('',#2904,0.499999999999998);
+#1083=CIRCLE('',#2907,0.499999999999998);
+#1084=CIRCLE('',#2910,0.499999999999998);
+#1085=CIRCLE('',#2913,0.499999999999998);
+#1086=CIRCLE('',#2916,0.499999999999998);
+#1087=CIRCLE('',#2919,0.499999999999998);
+#1088=CIRCLE('',#2922,0.499999999999998);
+#1089=CIRCLE('',#2925,0.499999999999998);
+#1090=CIRCLE('',#2928,0.499999999999998);
+#1091=CIRCLE('',#2931,0.499999999999998);
+#1092=CIRCLE('',#2934,0.499999999999998);
+#1093=CIRCLE('',#2937,0.499999999999989);
+#1094=CIRCLE('',#2950,5.);
+#1095=CIRCLE('',#2951,5.);
+#1096=CIRCLE('',#2954,5.);
+#1097=CIRCLE('',#2955,5.);
+#1098=CIRCLE('',#2956,5.);
+#1099=CIRCLE('',#2957,1.45);
+#1100=CIRCLE('',#2958,1.45);
+#1101=CIRCLE('',#2959,1.45);
+#1102=CIRCLE('',#2960,1.45);
+#1103=CIRCLE('',#2962,5.);
+#1104=CIRCLE('',#2965,5.);
+#1105=CIRCLE('',#2968,5.);
+#1106=CIRCLE('',#2970,1.45);
+#1107=CIRCLE('',#2972,1.45);
+#1108=CIRCLE('',#2974,1.45);
+#1109=CIRCLE('',#2980,1.45);
+#1110=VERTEX_POINT('',#3764);
+#1111=VERTEX_POINT('',#3765);
+#1112=VERTEX_POINT('',#3767);
+#1113=VERTEX_POINT('',#3769);
+#1114=VERTEX_POINT('',#3773);
+#1115=VERTEX_POINT('',#3775);
+#1116=VERTEX_POINT('',#3777);
+#1117=VERTEX_POINT('',#3779);
+#1118=VERTEX_POINT('',#3781);
+#1119=VERTEX_POINT('',#3783);
+#1120=VERTEX_POINT('',#3785);
+#1121=VERTEX_POINT('',#3787);
+#1122=VERTEX_POINT('',#3789);
+#1123=VERTEX_POINT('',#3791);
+#1124=VERTEX_POINT('',#3793);
+#1125=VERTEX_POINT('',#3795);
+#1126=VERTEX_POINT('',#3797);
+#1127=VERTEX_POINT('',#3799);
+#1128=VERTEX_POINT('',#3801);
+#1129=VERTEX_POINT('',#3804);
+#1130=VERTEX_POINT('',#3806);
+#1131=VERTEX_POINT('',#3808);
+#1132=VERTEX_POINT('',#3810);
+#1133=VERTEX_POINT('',#3813);
+#1134=VERTEX_POINT('',#3817);
+#1135=VERTEX_POINT('',#3821);
+#1136=VERTEX_POINT('',#3823);
+#1137=VERTEX_POINT('',#3827);
+#1138=VERTEX_POINT('',#3831);
+#1139=VERTEX_POINT('',#3835);
+#1140=VERTEX_POINT('',#3837);
+#1141=VERTEX_POINT('',#3842);
+#1142=VERTEX_POINT('',#3846);
+#1143=VERTEX_POINT('',#3852);
+#1144=VERTEX_POINT('',#3858);
+#1145=VERTEX_POINT('',#3859);
+#1146=VERTEX_POINT('',#3864);
+#1147=VERTEX_POINT('',#3868);
+#1148=VERTEX_POINT('',#3874);
+#1149=VERTEX_POINT('',#3878);
+#1150=VERTEX_POINT('',#3882);
+#1151=VERTEX_POINT('',#3886);
+#1152=VERTEX_POINT('',#3892);
+#1153=VERTEX_POINT('',#3893);
+#1154=VERTEX_POINT('',#3895);
+#1155=VERTEX_POINT('',#3897);
+#1156=VERTEX_POINT('',#3901);
+#1157=VERTEX_POINT('',#3903);
+#1158=VERTEX_POINT('',#3907);
+#1159=VERTEX_POINT('',#3909);
+#1160=VERTEX_POINT('',#3911);
+#1161=VERTEX_POINT('',#3913);
+#1162=VERTEX_POINT('',#3915);
+#1163=VERTEX_POINT('',#3917);
+#1164=VERTEX_POINT('',#3919);
+#1165=VERTEX_POINT('',#3921);
+#1166=VERTEX_POINT('',#3923);
+#1167=VERTEX_POINT('',#3926);
+#1168=VERTEX_POINT('',#3927);
+#1169=VERTEX_POINT('',#3929);
+#1170=VERTEX_POINT('',#3931);
+#1171=VERTEX_POINT('',#3934);
+#1172=VERTEX_POINT('',#3935);
+#1173=VERTEX_POINT('',#3937);
+#1174=VERTEX_POINT('',#3939);
+#1175=VERTEX_POINT('',#3941);
+#1176=VERTEX_POINT('',#3943);
+#1177=VERTEX_POINT('',#3945);
+#1178=VERTEX_POINT('',#3947);
+#1179=VERTEX_POINT('',#3950);
+#1180=VERTEX_POINT('',#3951);
+#1181=VERTEX_POINT('',#3953);
+#1182=VERTEX_POINT('',#3955);
+#1183=VERTEX_POINT('',#3957);
+#1184=VERTEX_POINT('',#3959);
+#1185=VERTEX_POINT('',#3961);
+#1186=VERTEX_POINT('',#3963);
+#1187=VERTEX_POINT('',#3966);
+#1188=VERTEX_POINT('',#3967);
+#1189=VERTEX_POINT('',#3969);
+#1190=VERTEX_POINT('',#3971);
+#1191=VERTEX_POINT('',#3973);
+#1192=VERTEX_POINT('',#3975);
+#1193=VERTEX_POINT('',#3977);
+#1194=VERTEX_POINT('',#3979);
+#1195=VERTEX_POINT('',#3982);
+#1196=VERTEX_POINT('',#3983);
+#1197=VERTEX_POINT('',#3985);
+#1198=VERTEX_POINT('',#3987);
+#1199=VERTEX_POINT('',#3989);
+#1200=VERTEX_POINT('',#3991);
+#1201=VERTEX_POINT('',#3993);
+#1202=VERTEX_POINT('',#3995);
+#1203=VERTEX_POINT('',#3998);
+#1204=VERTEX_POINT('',#3999);
+#1205=VERTEX_POINT('',#4001);
+#1206=VERTEX_POINT('',#4003);
+#1207=VERTEX_POINT('',#4005);
+#1208=VERTEX_POINT('',#4007);
+#1209=VERTEX_POINT('',#4009);
+#1210=VERTEX_POINT('',#4011);
+#1211=VERTEX_POINT('',#4014);
+#1212=VERTEX_POINT('',#4015);
+#1213=VERTEX_POINT('',#4017);
+#1214=VERTEX_POINT('',#4019);
+#1215=VERTEX_POINT('',#4021);
+#1216=VERTEX_POINT('',#4023);
+#1217=VERTEX_POINT('',#4025);
+#1218=VERTEX_POINT('',#4027);
+#1219=VERTEX_POINT('',#4030);
+#1220=VERTEX_POINT('',#4031);
+#1221=VERTEX_POINT('',#4033);
+#1222=VERTEX_POINT('',#4035);
+#1223=VERTEX_POINT('',#4037);
+#1224=VERTEX_POINT('',#4039);
+#1225=VERTEX_POINT('',#4041);
+#1226=VERTEX_POINT('',#4043);
+#1227=VERTEX_POINT('',#4046);
+#1228=VERTEX_POINT('',#4047);
+#1229=VERTEX_POINT('',#4049);
+#1230=VERTEX_POINT('',#4051);
+#1231=VERTEX_POINT('',#4053);
+#1232=VERTEX_POINT('',#4055);
+#1233=VERTEX_POINT('',#4057);
+#1234=VERTEX_POINT('',#4059);
+#1235=VERTEX_POINT('',#4062);
+#1236=VERTEX_POINT('',#4063);
+#1237=VERTEX_POINT('',#4065);
+#1238=VERTEX_POINT('',#4067);
+#1239=VERTEX_POINT('',#4069);
+#1240=VERTEX_POINT('',#4071);
+#1241=VERTEX_POINT('',#4073);
+#1242=VERTEX_POINT('',#4075);
+#1243=VERTEX_POINT('',#4078);
+#1244=VERTEX_POINT('',#4080);
+#1245=VERTEX_POINT('',#4082);
+#1246=VERTEX_POINT('',#4084);
+#1247=VERTEX_POINT('',#4087);
+#1248=VERTEX_POINT('',#4088);
+#1249=VERTEX_POINT('',#4093);
+#1250=VERTEX_POINT('',#4097);
+#1251=VERTEX_POINT('',#4101);
+#1252=VERTEX_POINT('',#4102);
+#1253=VERTEX_POINT('',#4107);
+#1254=VERTEX_POINT('',#4111);
+#1255=VERTEX_POINT('',#4115);
+#1256=VERTEX_POINT('',#4119);
+#1257=VERTEX_POINT('',#4123);
+#1258=VERTEX_POINT('',#4127);
+#1259=VERTEX_POINT('',#4129);
+#1260=VERTEX_POINT('',#4133);
+#1261=VERTEX_POINT('',#4137);
+#1262=VERTEX_POINT('',#4141);
+#1263=VERTEX_POINT('',#4145);
+#1264=VERTEX_POINT('',#4149);
+#1265=VERTEX_POINT('',#4153);
+#1266=VERTEX_POINT('',#4159);
+#1267=VERTEX_POINT('',#4161);
+#1268=VERTEX_POINT('',#4165);
+#1269=VERTEX_POINT('',#4169);
+#1270=VERTEX_POINT('',#4173);
+#1271=VERTEX_POINT('',#4177);
+#1272=VERTEX_POINT('',#4181);
+#1273=VERTEX_POINT('',#4185);
+#1274=VERTEX_POINT('',#4191);
+#1275=VERTEX_POINT('',#4193);
+#1276=VERTEX_POINT('',#4197);
+#1277=VERTEX_POINT('',#4201);
+#1278=VERTEX_POINT('',#4205);
+#1279=VERTEX_POINT('',#4209);
+#1280=VERTEX_POINT('',#4213);
+#1281=VERTEX_POINT('',#4217);
+#1282=VERTEX_POINT('',#4223);
+#1283=VERTEX_POINT('',#4225);
+#1284=VERTEX_POINT('',#4229);
+#1285=VERTEX_POINT('',#4233);
+#1286=VERTEX_POINT('',#4237);
+#1287=VERTEX_POINT('',#4241);
+#1288=VERTEX_POINT('',#4245);
+#1289=VERTEX_POINT('',#4249);
+#1290=VERTEX_POINT('',#4255);
+#1291=VERTEX_POINT('',#4257);
+#1292=VERTEX_POINT('',#4261);
+#1293=VERTEX_POINT('',#4265);
+#1294=VERTEX_POINT('',#4269);
+#1295=VERTEX_POINT('',#4273);
+#1296=VERTEX_POINT('',#4277);
+#1297=VERTEX_POINT('',#4281);
+#1298=VERTEX_POINT('',#4287);
+#1299=VERTEX_POINT('',#4289);
+#1300=VERTEX_POINT('',#4293);
+#1301=VERTEX_POINT('',#4297);
+#1302=VERTEX_POINT('',#4301);
+#1303=VERTEX_POINT('',#4305);
+#1304=VERTEX_POINT('',#4309);
+#1305=VERTEX_POINT('',#4313);
+#1306=VERTEX_POINT('',#4319);
+#1307=VERTEX_POINT('',#4321);
+#1308=VERTEX_POINT('',#4325);
+#1309=VERTEX_POINT('',#4329);
+#1310=VERTEX_POINT('',#4333);
+#1311=VERTEX_POINT('',#4337);
+#1312=VERTEX_POINT('',#4341);
+#1313=VERTEX_POINT('',#4345);
+#1314=VERTEX_POINT('',#4351);
+#1315=VERTEX_POINT('',#4353);
+#1316=VERTEX_POINT('',#4357);
+#1317=VERTEX_POINT('',#4361);
+#1318=VERTEX_POINT('',#4365);
+#1319=VERTEX_POINT('',#4369);
+#1320=VERTEX_POINT('',#4373);
+#1321=VERTEX_POINT('',#4377);
+#1322=VERTEX_POINT('',#4383);
+#1323=VERTEX_POINT('',#4385);
+#1324=VERTEX_POINT('',#4389);
+#1325=VERTEX_POINT('',#4393);
+#1326=VERTEX_POINT('',#4397);
+#1327=VERTEX_POINT('',#4401);
+#1328=VERTEX_POINT('',#4405);
+#1329=VERTEX_POINT('',#4409);
+#1330=VERTEX_POINT('',#4415);
+#1331=VERTEX_POINT('',#4417);
+#1332=VERTEX_POINT('',#4421);
+#1333=VERTEX_POINT('',#4425);
+#1334=VERTEX_POINT('',#4431);
+#1335=VERTEX_POINT('',#4433);
+#1336=VERTEX_POINT('',#4446);
+#1337=VERTEX_POINT('',#4447);
+#1338=VERTEX_POINT('',#4449);
+#1339=VERTEX_POINT('',#4451);
+#1340=VERTEX_POINT('',#4455);
+#1341=VERTEX_POINT('',#4457);
+#1342=VERTEX_POINT('',#4461);
+#1343=VERTEX_POINT('',#4463);
+#1344=VERTEX_POINT('',#4465);
+#1345=VERTEX_POINT('',#4467);
+#1346=VERTEX_POINT('',#4469);
+#1347=VERTEX_POINT('',#4472);
+#1348=VERTEX_POINT('',#4474);
+#1349=VERTEX_POINT('',#4475);
+#1350=VERTEX_POINT('',#4477);
+#1351=VERTEX_POINT('',#4479);
+#1352=VERTEX_POINT('',#4482);
+#1353=VERTEX_POINT('',#4484);
+#1354=VERTEX_POINT('',#4486);
+#1355=VERTEX_POINT('',#4489);
+#1356=VERTEX_POINT('',#4493);
+#1357=VERTEX_POINT('',#4497);
+#1358=VERTEX_POINT('',#4501);
+#1359=VERTEX_POINT('',#4505);
+#1360=VERTEX_POINT('',#4509);
+#1361=VERTEX_POINT('',#4513);
+#1362=VERTEX_POINT('',#4517);
+#1363=VERTEX_POINT('',#4521);
+#1364=VERTEX_POINT('',#4523);
+#1365=VERTEX_POINT('',#4527);
+#1366=VERTEX_POINT('',#4531);
+#1367=VERTEX_POINT('',#4537);
+#1368=EDGE_CURVE('',#1110,#1111,#990,.T.);
+#1369=EDGE_CURVE('',#1111,#1112,#456,.T.);
+#1370=EDGE_CURVE('',#1112,#1113,#991,.T.);
+#1371=EDGE_CURVE('',#1113,#1110,#457,.T.);
+#1372=EDGE_CURVE('',#1114,#1110,#458,.T.);
+#1373=EDGE_CURVE('',#1115,#1114,#992,.T.);
+#1374=EDGE_CURVE('',#1116,#1115,#459,.T.);
+#1375=EDGE_CURVE('',#1117,#1116,#993,.T.);
+#1376=EDGE_CURVE('',#1118,#1117,#460,.T.);
+#1377=EDGE_CURVE('',#1119,#1118,#994,.T.);
+#1378=EDGE_CURVE('',#1120,#1119,#461,.T.);
+#1379=EDGE_CURVE('',#1121,#1120,#462,.T.);
+#1380=EDGE_CURVE('',#1121,#1122,#463,.T.);
+#1381=EDGE_CURVE('',#1122,#1123,#464,.T.);
+#1382=EDGE_CURVE('',#1123,#1124,#465,.T.);
+#1383=EDGE_CURVE('',#1124,#1125,#466,.T.);
+#1384=EDGE_CURVE('',#1125,#1126,#467,.T.);
+#1385=EDGE_CURVE('',#1126,#1127,#468,.T.);
+#1386=EDGE_CURVE('',#1128,#1127,#469,.T.);
+#1387=EDGE_CURVE('',#1111,#1128,#470,.T.);
+#1388=EDGE_CURVE('',#1129,#1129,#995,.T.);
+#1389=EDGE_CURVE('',#1130,#1130,#996,.T.);
+#1390=EDGE_CURVE('',#1131,#1131,#997,.T.);
+#1391=EDGE_CURVE('',#1132,#1132,#998,.T.);
+#1392=EDGE_CURVE('',#1113,#1133,#471,.T.);
+#1393=EDGE_CURVE('',#1114,#1133,#472,.T.);
+#1394=EDGE_CURVE('',#1133,#1134,#999,.T.);
+#1395=EDGE_CURVE('',#1134,#1115,#473,.T.);
+#1396=EDGE_CURVE('',#1116,#1135,#474,.T.);
+#1397=EDGE_CURVE('',#1135,#1136,#1000,.T.);
+#1398=EDGE_CURVE('',#1136,#1117,#475,.T.);
+#1399=EDGE_CURVE('',#1136,#1137,#476,.T.);
+#1400=EDGE_CURVE('',#1118,#1137,#477,.T.);
+#1401=EDGE_CURVE('',#1137,#1138,#1001,.T.);
+#1402=EDGE_CURVE('',#1138,#1119,#478,.T.);
+#1403=EDGE_CURVE('',#1128,#1139,#479,.T.);
+#1404=EDGE_CURVE('',#1140,#1139,#480,.T.);
+#1405=EDGE_CURVE('',#1120,#1140,#481,.T.);
+#1406=EDGE_CURVE('',#1138,#1112,#482,.T.);
+#1407=EDGE_CURVE('',#1141,#1127,#483,.T.);
+#1408=EDGE_CURVE('',#1141,#1139,#484,.T.);
+#1409=EDGE_CURVE('',#1142,#1140,#485,.T.);
+#1410=EDGE_CURVE('',#1142,#1121,#486,.T.);
+#1411=EDGE_CURVE('',#1134,#1135,#487,.T.);
+#1412=EDGE_CURVE('',#1122,#1143,#488,.T.);
+#1413=EDGE_CURVE('',#1143,#1142,#489,.T.);
+#1414=EDGE_CURVE('',#1143,#1141,#490,.T.);
+#1415=EDGE_CURVE('',#1144,#1145,#491,.T.);
+#1416=EDGE_CURVE('',#1144,#1124,#492,.T.);
+#1417=EDGE_CURVE('',#1145,#1123,#493,.T.);
+#1418=EDGE_CURVE('',#1146,#1144,#494,.T.);
+#1419=EDGE_CURVE('',#1146,#1125,#495,.T.);
+#1420=EDGE_CURVE('',#1147,#1126,#496,.T.);
+#1421=EDGE_CURVE('',#1145,#1147,#497,.T.);
+#1422=EDGE_CURVE('',#1147,#1146,#498,.T.);
+#1423=EDGE_CURVE('',#1129,#1148,#499,.T.);
+#1424=EDGE_CURVE('',#1148,#1148,#1002,.T.);
+#1425=EDGE_CURVE('',#1130,#1149,#500,.T.);
+#1426=EDGE_CURVE('',#1149,#1149,#1003,.T.);
+#1427=EDGE_CURVE('',#1131,#1150,#501,.T.);
+#1428=EDGE_CURVE('',#1150,#1150,#1004,.T.);
+#1429=EDGE_CURVE('',#1132,#1151,#502,.T.);
+#1430=EDGE_CURVE('',#1151,#1151,#1005,.T.);
+#1431=EDGE_CURVE('',#1152,#1153,#1006,.T.);
+#1432=EDGE_CURVE('',#1153,#1154,#503,.T.);
+#1433=EDGE_CURVE('',#1154,#1155,#1007,.T.);
+#1434=EDGE_CURVE('',#1155,#1152,#504,.T.);
+#1435=EDGE_CURVE('',#1156,#1155,#505,.T.);
+#1436=EDGE_CURVE('',#1156,#1157,#506,.T.);
+#1437=EDGE_CURVE('',#1152,#1157,#507,.T.);
+#1438=EDGE_CURVE('',#1154,#1158,#508,.T.);
+#1439=EDGE_CURVE('',#1159,#1158,#1008,.T.);
+#1440=EDGE_CURVE('',#1159,#1160,#509,.T.);
+#1441=EDGE_CURVE('',#1161,#1160,#1009,.T.);
+#1442=EDGE_CURVE('',#1161,#1162,#510,.T.);
+#1443=EDGE_CURVE('',#1163,#1162,#1010,.T.);
+#1444=EDGE_CURVE('',#1163,#1164,#511,.T.);
+#1445=EDGE_CURVE('',#1164,#1165,#512,.T.);
+#1446=EDGE_CURVE('',#1165,#1166,#513,.T.);
+#1447=EDGE_CURVE('',#1166,#1156,#514,.T.);
+#1448=EDGE_CURVE('',#1167,#1168,#515,.T.);
+#1449=EDGE_CURVE('',#1168,#1169,#516,.T.);
+#1450=EDGE_CURVE('',#1169,#1170,#517,.T.);
+#1451=EDGE_CURVE('',#1170,#1167,#518,.T.);
+#1452=EDGE_CURVE('',#1171,#1172,#519,.T.);
+#1453=EDGE_CURVE('',#1172,#1173,#1011,.T.);
+#1454=EDGE_CURVE('',#1173,#1174,#520,.T.);
+#1455=EDGE_CURVE('',#1174,#1175,#1012,.T.);
+#1456=EDGE_CURVE('',#1175,#1176,#521,.T.);
+#1457=EDGE_CURVE('',#1176,#1177,#1013,.T.);
+#1458=EDGE_CURVE('',#1177,#1178,#522,.T.);
+#1459=EDGE_CURVE('',#1178,#1171,#1014,.T.);
+#1460=EDGE_CURVE('',#1179,#1180,#523,.T.);
+#1461=EDGE_CURVE('',#1180,#1181,#1015,.T.);
+#1462=EDGE_CURVE('',#1181,#1182,#524,.T.);
+#1463=EDGE_CURVE('',#1182,#1183,#1016,.T.);
+#1464=EDGE_CURVE('',#1183,#1184,#525,.T.);
+#1465=EDGE_CURVE('',#1184,#1185,#1017,.T.);
+#1466=EDGE_CURVE('',#1185,#1186,#526,.T.);
+#1467=EDGE_CURVE('',#1186,#1179,#1018,.T.);
+#1468=EDGE_CURVE('',#1187,#1188,#527,.T.);
+#1469=EDGE_CURVE('',#1188,#1189,#1019,.T.);
+#1470=EDGE_CURVE('',#1189,#1190,#528,.T.);
+#1471=EDGE_CURVE('',#1190,#1191,#1020,.T.);
+#1472=EDGE_CURVE('',#1191,#1192,#529,.T.);
+#1473=EDGE_CURVE('',#1192,#1193,#1021,.T.);
+#1474=EDGE_CURVE('',#1193,#1194,#530,.T.);
+#1475=EDGE_CURVE('',#1194,#1187,#1022,.T.);
+#1476=EDGE_CURVE('',#1195,#1196,#531,.T.);
+#1477=EDGE_CURVE('',#1196,#1197,#1023,.T.);
+#1478=EDGE_CURVE('',#1197,#1198,#532,.T.);
+#1479=EDGE_CURVE('',#1198,#1199,#1024,.T.);
+#1480=EDGE_CURVE('',#1199,#1200,#533,.T.);
+#1481=EDGE_CURVE('',#1200,#1201,#1025,.T.);
+#1482=EDGE_CURVE('',#1201,#1202,#534,.T.);
+#1483=EDGE_CURVE('',#1202,#1195,#1026,.T.);
+#1484=EDGE_CURVE('',#1203,#1204,#535,.T.);
+#1485=EDGE_CURVE('',#1204,#1205,#1027,.T.);
+#1486=EDGE_CURVE('',#1205,#1206,#536,.T.);
+#1487=EDGE_CURVE('',#1206,#1207,#1028,.T.);
+#1488=EDGE_CURVE('',#1207,#1208,#537,.T.);
+#1489=EDGE_CURVE('',#1208,#1209,#1029,.T.);
+#1490=EDGE_CURVE('',#1209,#1210,#538,.T.);
+#1491=EDGE_CURVE('',#1210,#1203,#1030,.T.);
+#1492=EDGE_CURVE('',#1211,#1212,#539,.T.);
+#1493=EDGE_CURVE('',#1212,#1213,#1031,.T.);
+#1494=EDGE_CURVE('',#1213,#1214,#540,.T.);
+#1495=EDGE_CURVE('',#1214,#1215,#1032,.T.);
+#1496=EDGE_CURVE('',#1215,#1216,#541,.T.);
+#1497=EDGE_CURVE('',#1216,#1217,#1033,.T.);
+#1498=EDGE_CURVE('',#1217,#1218,#542,.T.);
+#1499=EDGE_CURVE('',#1218,#1211,#1034,.T.);
+#1500=EDGE_CURVE('',#1219,#1220,#543,.T.);
+#1501=EDGE_CURVE('',#1220,#1221,#1035,.T.);
+#1502=EDGE_CURVE('',#1221,#1222,#544,.T.);
+#1503=EDGE_CURVE('',#1222,#1223,#1036,.T.);
+#1504=EDGE_CURVE('',#1223,#1224,#545,.T.);
+#1505=EDGE_CURVE('',#1224,#1225,#1037,.T.);
+#1506=EDGE_CURVE('',#1225,#1226,#546,.T.);
+#1507=EDGE_CURVE('',#1226,#1219,#1038,.T.);
+#1508=EDGE_CURVE('',#1227,#1228,#547,.T.);
+#1509=EDGE_CURVE('',#1228,#1229,#1039,.T.);
+#1510=EDGE_CURVE('',#1229,#1230,#548,.T.);
+#1511=EDGE_CURVE('',#1230,#1231,#1040,.T.);
+#1512=EDGE_CURVE('',#1231,#1232,#549,.T.);
+#1513=EDGE_CURVE('',#1232,#1233,#1041,.T.);
+#1514=EDGE_CURVE('',#1233,#1234,#550,.T.);
+#1515=EDGE_CURVE('',#1234,#1227,#1042,.T.);
+#1516=EDGE_CURVE('',#1235,#1236,#551,.T.);
+#1517=EDGE_CURVE('',#1236,#1237,#1043,.T.);
+#1518=EDGE_CURVE('',#1237,#1238,#552,.T.);
+#1519=EDGE_CURVE('',#1238,#1239,#1044,.T.);
+#1520=EDGE_CURVE('',#1239,#1240,#553,.T.);
+#1521=EDGE_CURVE('',#1240,#1241,#1045,.T.);
+#1522=EDGE_CURVE('',#1241,#1242,#554,.T.);
+#1523=EDGE_CURVE('',#1242,#1235,#1046,.T.);
+#1524=EDGE_CURVE('',#1243,#1243,#1047,.T.);
+#1525=EDGE_CURVE('',#1244,#1244,#1048,.T.);
+#1526=EDGE_CURVE('',#1245,#1245,#1049,.T.);
+#1527=EDGE_CURVE('',#1246,#1246,#1050,.T.);
+#1528=EDGE_CURVE('',#1247,#1248,#1051,.T.);
+#1529=EDGE_CURVE('',#1248,#1159,#555,.T.);
+#1530=EDGE_CURVE('',#1158,#1247,#556,.T.);
+#1531=EDGE_CURVE('',#1249,#1248,#557,.T.);
+#1532=EDGE_CURVE('',#1160,#1249,#558,.T.);
+#1533=EDGE_CURVE('',#1249,#1250,#1052,.T.);
+#1534=EDGE_CURVE('',#1250,#1161,#559,.T.);
+#1535=EDGE_CURVE('',#1251,#1252,#1053,.T.);
+#1536=EDGE_CURVE('',#1252,#1163,#560,.T.);
+#1537=EDGE_CURVE('',#1162,#1251,#561,.T.);
+#1538=EDGE_CURVE('',#1253,#1252,#562,.T.);
+#1539=EDGE_CURVE('',#1164,#1253,#563,.T.);
+#1540=EDGE_CURVE('',#1254,#1254,#1054,.T.);
+#1541=EDGE_CURVE('',#1254,#1246,#564,.T.);
+#1542=EDGE_CURVE('',#1255,#1255,#1055,.T.);
+#1543=EDGE_CURVE('',#1255,#1245,#565,.T.);
+#1544=EDGE_CURVE('',#1256,#1256,#1056,.T.);
+#1545=EDGE_CURVE('',#1256,#1244,#566,.T.);
+#1546=EDGE_CURVE('',#1257,#1257,#1057,.T.);
+#1547=EDGE_CURVE('',#1257,#1243,#567,.T.);
+#1548=EDGE_CURVE('',#1236,#1258,#568,.T.);
+#1549=EDGE_CURVE('',#1259,#1258,#1058,.T.);
+#1550=EDGE_CURVE('',#1237,#1259,#569,.T.);
+#1551=EDGE_CURVE('',#1260,#1259,#570,.T.);
+#1552=EDGE_CURVE('',#1238,#1260,#571,.T.);
+#1553=EDGE_CURVE('',#1261,#1260,#1059,.T.);
+#1554=EDGE_CURVE('',#1239,#1261,#572,.T.);
+#1555=EDGE_CURVE('',#1262,#1261,#573,.T.);
+#1556=EDGE_CURVE('',#1240,#1262,#574,.T.);
+#1557=EDGE_CURVE('',#1263,#1262,#1060,.T.);
+#1558=EDGE_CURVE('',#1241,#1263,#575,.T.);
+#1559=EDGE_CURVE('',#1264,#1263,#576,.T.);
+#1560=EDGE_CURVE('',#1242,#1264,#577,.T.);
+#1561=EDGE_CURVE('',#1265,#1264,#1061,.T.);
+#1562=EDGE_CURVE('',#1235,#1265,#578,.T.);
+#1563=EDGE_CURVE('',#1258,#1265,#579,.T.);
+#1564=EDGE_CURVE('',#1228,#1266,#580,.T.);
+#1565=EDGE_CURVE('',#1267,#1266,#1062,.T.);
+#1566=EDGE_CURVE('',#1229,#1267,#581,.T.);
+#1567=EDGE_CURVE('',#1268,#1267,#582,.T.);
+#1568=EDGE_CURVE('',#1230,#1268,#583,.T.);
+#1569=EDGE_CURVE('',#1269,#1268,#1063,.T.);
+#1570=EDGE_CURVE('',#1231,#1269,#584,.T.);
+#1571=EDGE_CURVE('',#1270,#1269,#585,.T.);
+#1572=EDGE_CURVE('',#1232,#1270,#586,.T.);
+#1573=EDGE_CURVE('',#1271,#1270,#1064,.T.);
+#1574=EDGE_CURVE('',#1233,#1271,#587,.T.);
+#1575=EDGE_CURVE('',#1272,#1271,#588,.T.);
+#1576=EDGE_CURVE('',#1234,#1272,#589,.T.);
+#1577=EDGE_CURVE('',#1273,#1272,#1065,.T.);
+#1578=EDGE_CURVE('',#1227,#1273,#590,.T.);
+#1579=EDGE_CURVE('',#1266,#1273,#591,.T.);
+#1580=EDGE_CURVE('',#1220,#1274,#592,.T.);
+#1581=EDGE_CURVE('',#1275,#1274,#1066,.T.);
+#1582=EDGE_CURVE('',#1221,#1275,#593,.T.);
+#1583=EDGE_CURVE('',#1276,#1275,#594,.T.);
+#1584=EDGE_CURVE('',#1222,#1276,#595,.T.);
+#1585=EDGE_CURVE('',#1277,#1276,#1067,.T.);
+#1586=EDGE_CURVE('',#1223,#1277,#596,.T.);
+#1587=EDGE_CURVE('',#1278,#1277,#597,.T.);
+#1588=EDGE_CURVE('',#1224,#1278,#598,.T.);
+#1589=EDGE_CURVE('',#1279,#1278,#1068,.T.);
+#1590=EDGE_CURVE('',#1225,#1279,#599,.T.);
+#1591=EDGE_CURVE('',#1280,#1279,#600,.T.);
+#1592=EDGE_CURVE('',#1226,#1280,#601,.T.);
+#1593=EDGE_CURVE('',#1281,#1280,#1069,.T.);
+#1594=EDGE_CURVE('',#1219,#1281,#602,.T.);
+#1595=EDGE_CURVE('',#1274,#1281,#603,.T.);
+#1596=EDGE_CURVE('',#1212,#1282,#604,.T.);
+#1597=EDGE_CURVE('',#1283,#1282,#1070,.T.);
+#1598=EDGE_CURVE('',#1213,#1283,#605,.T.);
+#1599=EDGE_CURVE('',#1284,#1283,#606,.T.);
+#1600=EDGE_CURVE('',#1214,#1284,#607,.T.);
+#1601=EDGE_CURVE('',#1285,#1284,#1071,.T.);
+#1602=EDGE_CURVE('',#1215,#1285,#608,.T.);
+#1603=EDGE_CURVE('',#1286,#1285,#609,.T.);
+#1604=EDGE_CURVE('',#1216,#1286,#610,.T.);
+#1605=EDGE_CURVE('',#1287,#1286,#1072,.T.);
+#1606=EDGE_CURVE('',#1217,#1287,#611,.T.);
+#1607=EDGE_CURVE('',#1288,#1287,#612,.T.);
+#1608=EDGE_CURVE('',#1218,#1288,#613,.T.);
+#1609=EDGE_CURVE('',#1289,#1288,#1073,.T.);
+#1610=EDGE_CURVE('',#1211,#1289,#614,.T.);
+#1611=EDGE_CURVE('',#1282,#1289,#615,.T.);
+#1612=EDGE_CURVE('',#1204,#1290,#616,.T.);
+#1613=EDGE_CURVE('',#1291,#1290,#1074,.T.);
+#1614=EDGE_CURVE('',#1205,#1291,#617,.T.);
+#1615=EDGE_CURVE('',#1292,#1291,#618,.T.);
+#1616=EDGE_CURVE('',#1206,#1292,#619,.T.);
+#1617=EDGE_CURVE('',#1293,#1292,#1075,.T.);
+#1618=EDGE_CURVE('',#1207,#1293,#620,.T.);
+#1619=EDGE_CURVE('',#1294,#1293,#621,.T.);
+#1620=EDGE_CURVE('',#1208,#1294,#622,.T.);
+#1621=EDGE_CURVE('',#1295,#1294,#1076,.T.);
+#1622=EDGE_CURVE('',#1209,#1295,#623,.T.);
+#1623=EDGE_CURVE('',#1296,#1295,#624,.T.);
+#1624=EDGE_CURVE('',#1210,#1296,#625,.T.);
+#1625=EDGE_CURVE('',#1297,#1296,#1077,.T.);
+#1626=EDGE_CURVE('',#1203,#1297,#626,.T.);
+#1627=EDGE_CURVE('',#1290,#1297,#627,.T.);
+#1628=EDGE_CURVE('',#1196,#1298,#628,.T.);
+#1629=EDGE_CURVE('',#1299,#1298,#1078,.T.);
+#1630=EDGE_CURVE('',#1197,#1299,#629,.T.);
+#1631=EDGE_CURVE('',#1300,#1299,#630,.T.);
+#1632=EDGE_CURVE('',#1198,#1300,#631,.T.);
+#1633=EDGE_CURVE('',#1301,#1300,#1079,.T.);
+#1634=EDGE_CURVE('',#1199,#1301,#632,.T.);
+#1635=EDGE_CURVE('',#1302,#1301,#633,.T.);
+#1636=EDGE_CURVE('',#1200,#1302,#634,.T.);
+#1637=EDGE_CURVE('',#1303,#1302,#1080,.T.);
+#1638=EDGE_CURVE('',#1201,#1303,#635,.T.);
+#1639=EDGE_CURVE('',#1304,#1303,#636,.T.);
+#1640=EDGE_CURVE('',#1202,#1304,#637,.T.);
+#1641=EDGE_CURVE('',#1305,#1304,#1081,.T.);
+#1642=EDGE_CURVE('',#1195,#1305,#638,.T.);
+#1643=EDGE_CURVE('',#1298,#1305,#639,.T.);
+#1644=EDGE_CURVE('',#1188,#1306,#640,.T.);
+#1645=EDGE_CURVE('',#1307,#1306,#1082,.T.);
+#1646=EDGE_CURVE('',#1189,#1307,#641,.T.);
+#1647=EDGE_CURVE('',#1308,#1307,#642,.T.);
+#1648=EDGE_CURVE('',#1190,#1308,#643,.T.);
+#1649=EDGE_CURVE('',#1309,#1308,#1083,.T.);
+#1650=EDGE_CURVE('',#1191,#1309,#644,.T.);
+#1651=EDGE_CURVE('',#1310,#1309,#645,.T.);
+#1652=EDGE_CURVE('',#1192,#1310,#646,.T.);
+#1653=EDGE_CURVE('',#1311,#1310,#1084,.T.);
+#1654=EDGE_CURVE('',#1193,#1311,#647,.T.);
+#1655=EDGE_CURVE('',#1312,#1311,#648,.T.);
+#1656=EDGE_CURVE('',#1194,#1312,#649,.T.);
+#1657=EDGE_CURVE('',#1313,#1312,#1085,.T.);
+#1658=EDGE_CURVE('',#1187,#1313,#650,.T.);
+#1659=EDGE_CURVE('',#1306,#1313,#651,.T.);
+#1660=EDGE_CURVE('',#1180,#1314,#652,.T.);
+#1661=EDGE_CURVE('',#1315,#1314,#1086,.T.);
+#1662=EDGE_CURVE('',#1181,#1315,#653,.T.);
+#1663=EDGE_CURVE('',#1316,#1315,#654,.T.);
+#1664=EDGE_CURVE('',#1182,#1316,#655,.T.);
+#1665=EDGE_CURVE('',#1317,#1316,#1087,.T.);
+#1666=EDGE_CURVE('',#1183,#1317,#656,.T.);
+#1667=EDGE_CURVE('',#1318,#1317,#657,.T.);
+#1668=EDGE_CURVE('',#1184,#1318,#658,.T.);
+#1669=EDGE_CURVE('',#1319,#1318,#1088,.T.);
+#1670=EDGE_CURVE('',#1185,#1319,#659,.T.);
+#1671=EDGE_CURVE('',#1320,#1319,#660,.T.);
+#1672=EDGE_CURVE('',#1186,#1320,#661,.T.);
+#1673=EDGE_CURVE('',#1321,#1320,#1089,.T.);
+#1674=EDGE_CURVE('',#1179,#1321,#662,.T.);
+#1675=EDGE_CURVE('',#1314,#1321,#663,.T.);
+#1676=EDGE_CURVE('',#1172,#1322,#664,.T.);
+#1677=EDGE_CURVE('',#1323,#1322,#1090,.T.);
+#1678=EDGE_CURVE('',#1173,#1323,#665,.T.);
+#1679=EDGE_CURVE('',#1324,#1323,#666,.T.);
+#1680=EDGE_CURVE('',#1174,#1324,#667,.T.);
+#1681=EDGE_CURVE('',#1325,#1324,#1091,.T.);
+#1682=EDGE_CURVE('',#1175,#1325,#668,.T.);
+#1683=EDGE_CURVE('',#1326,#1325,#669,.T.);
+#1684=EDGE_CURVE('',#1176,#1326,#670,.T.);
+#1685=EDGE_CURVE('',#1327,#1326,#1092,.T.);
+#1686=EDGE_CURVE('',#1177,#1327,#671,.T.);
+#1687=EDGE_CURVE('',#1328,#1327,#672,.T.);
+#1688=EDGE_CURVE('',#1178,#1328,#673,.T.);
+#1689=EDGE_CURVE('',#1329,#1328,#1093,.T.);
+#1690=EDGE_CURVE('',#1171,#1329,#674,.T.);
+#1691=EDGE_CURVE('',#1322,#1329,#675,.T.);
+#1692=EDGE_CURVE('',#1168,#1330,#676,.T.);
+#1693=EDGE_CURVE('',#1331,#1330,#677,.T.);
+#1694=EDGE_CURVE('',#1169,#1331,#678,.T.);
+#1695=EDGE_CURVE('',#1332,#1331,#679,.T.);
+#1696=EDGE_CURVE('',#1170,#1332,#680,.T.);
+#1697=EDGE_CURVE('',#1333,#1332,#681,.T.);
+#1698=EDGE_CURVE('',#1167,#1333,#682,.T.);
+#1699=EDGE_CURVE('',#1330,#1333,#683,.T.);
+#1700=EDGE_CURVE('',#1165,#1334,#684,.T.);
+#1701=EDGE_CURVE('',#1335,#1334,#685,.T.);
+#1702=EDGE_CURVE('',#1166,#1335,#686,.T.);
+#1703=EDGE_CURVE('',#1157,#1335,#687,.T.);
+#1704=EDGE_CURVE('',#1247,#1153,#688,.T.);
+#1705=EDGE_CURVE('',#1251,#1250,#689,.T.);
+#1706=EDGE_CURVE('',#1334,#1253,#690,.T.);
+#1707=EDGE_CURVE('',#1336,#1337,#1094,.T.);
+#1708=EDGE_CURVE('',#1337,#1338,#691,.T.);
+#1709=EDGE_CURVE('',#1338,#1339,#1095,.T.);
+#1710=EDGE_CURVE('',#1339,#1336,#692,.T.);
+#1711=EDGE_CURVE('',#1340,#1339,#693,.T.);
+#1712=EDGE_CURVE('',#1341,#1340,#694,.T.);
+#1713=EDGE_CURVE('',#1336,#1341,#695,.T.);
+#1714=EDGE_CURVE('',#1338,#1342,#696,.T.);
+#1715=EDGE_CURVE('',#1343,#1342,#1096,.T.);
+#1716=EDGE_CURVE('',#1343,#1344,#697,.T.);
+#1717=EDGE_CURVE('',#1345,#1344,#1097,.T.);
+#1718=EDGE_CURVE('',#1345,#1346,#698,.T.);
+#1719=EDGE_CURVE('',#1340,#1346,#1098,.T.);
+#1720=EDGE_CURVE('',#1347,#1347,#1099,.T.);
+#1721=EDGE_CURVE('',#1348,#1349,#699,.T.);
+#1722=EDGE_CURVE('',#1349,#1350,#700,.T.);
+#1723=EDGE_CURVE('',#1350,#1351,#701,.T.);
+#1724=EDGE_CURVE('',#1351,#1348,#702,.T.);
+#1725=EDGE_CURVE('',#1352,#1352,#1100,.T.);
+#1726=EDGE_CURVE('',#1353,#1353,#1101,.T.);
+#1727=EDGE_CURVE('',#1354,#1354,#1102,.T.);
+#1728=EDGE_CURVE('',#1355,#1341,#1103,.T.);
+#1729=EDGE_CURVE('',#1346,#1355,#703,.T.);
+#1730=EDGE_CURVE('',#1356,#1345,#704,.T.);
+#1731=EDGE_CURVE('',#1355,#1356,#705,.T.);
+#1732=EDGE_CURVE('',#1357,#1356,#1104,.T.);
+#1733=EDGE_CURVE('',#1344,#1357,#706,.T.);
+#1734=EDGE_CURVE('',#1358,#1343,#707,.T.);
+#1735=EDGE_CURVE('',#1357,#1358,#708,.T.);
+#1736=EDGE_CURVE('',#1359,#1358,#1105,.T.);
+#1737=EDGE_CURVE('',#1342,#1359,#709,.T.);
+#1738=EDGE_CURVE('',#1360,#1360,#1106,.T.);
+#1739=EDGE_CURVE('',#1360,#1354,#710,.T.);
+#1740=EDGE_CURVE('',#1361,#1361,#1107,.T.);
+#1741=EDGE_CURVE('',#1361,#1353,#711,.T.);
+#1742=EDGE_CURVE('',#1362,#1362,#1108,.T.);
+#1743=EDGE_CURVE('',#1362,#1352,#712,.T.);
+#1744=EDGE_CURVE('',#1349,#1363,#713,.T.);
+#1745=EDGE_CURVE('',#1364,#1363,#714,.T.);
+#1746=EDGE_CURVE('',#1350,#1364,#715,.T.);
+#1747=EDGE_CURVE('',#1365,#1364,#716,.T.);
+#1748=EDGE_CURVE('',#1351,#1365,#717,.T.);
+#1749=EDGE_CURVE('',#1366,#1365,#718,.T.);
+#1750=EDGE_CURVE('',#1348,#1366,#719,.T.);
+#1751=EDGE_CURVE('',#1363,#1366,#720,.T.);
+#1752=EDGE_CURVE('',#1367,#1367,#1109,.T.);
+#1753=EDGE_CURVE('',#1367,#1347,#721,.T.);
+#1754=EDGE_CURVE('',#1359,#1337,#722,.T.);
+#1755=ORIENTED_EDGE('',*,*,#1368,.T.);
+#1756=ORIENTED_EDGE('',*,*,#1369,.T.);
+#1757=ORIENTED_EDGE('',*,*,#1370,.T.);
+#1758=ORIENTED_EDGE('',*,*,#1371,.T.);
+#1759=ORIENTED_EDGE('',*,*,#1368,.F.);
+#1760=ORIENTED_EDGE('',*,*,#1372,.F.);
+#1761=ORIENTED_EDGE('',*,*,#1373,.F.);
+#1762=ORIENTED_EDGE('',*,*,#1374,.F.);
+#1763=ORIENTED_EDGE('',*,*,#1375,.F.);
+#1764=ORIENTED_EDGE('',*,*,#1376,.F.);
+#1765=ORIENTED_EDGE('',*,*,#1377,.F.);
+#1766=ORIENTED_EDGE('',*,*,#1378,.F.);
+#1767=ORIENTED_EDGE('',*,*,#1379,.F.);
+#1768=ORIENTED_EDGE('',*,*,#1380,.T.);
+#1769=ORIENTED_EDGE('',*,*,#1381,.T.);
+#1770=ORIENTED_EDGE('',*,*,#1382,.T.);
+#1771=ORIENTED_EDGE('',*,*,#1383,.T.);
+#1772=ORIENTED_EDGE('',*,*,#1384,.T.);
+#1773=ORIENTED_EDGE('',*,*,#1385,.T.);
+#1774=ORIENTED_EDGE('',*,*,#1386,.F.);
+#1775=ORIENTED_EDGE('',*,*,#1387,.F.);
+#1776=ORIENTED_EDGE('',*,*,#1388,.F.);
+#1777=ORIENTED_EDGE('',*,*,#1389,.F.);
+#1778=ORIENTED_EDGE('',*,*,#1390,.F.);
+#1779=ORIENTED_EDGE('',*,*,#1391,.F.);
+#1780=ORIENTED_EDGE('',*,*,#1371,.F.);
+#1781=ORIENTED_EDGE('',*,*,#1392,.T.);
+#1782=ORIENTED_EDGE('',*,*,#1393,.F.);
+#1783=ORIENTED_EDGE('',*,*,#1372,.T.);
+#1784=ORIENTED_EDGE('',*,*,#1373,.T.);
+#1785=ORIENTED_EDGE('',*,*,#1393,.T.);
+#1786=ORIENTED_EDGE('',*,*,#1394,.T.);
+#1787=ORIENTED_EDGE('',*,*,#1395,.T.);
+#1788=ORIENTED_EDGE('',*,*,#1375,.T.);
+#1789=ORIENTED_EDGE('',*,*,#1396,.T.);
+#1790=ORIENTED_EDGE('',*,*,#1397,.T.);
+#1791=ORIENTED_EDGE('',*,*,#1398,.T.);
+#1792=ORIENTED_EDGE('',*,*,#1398,.F.);
+#1793=ORIENTED_EDGE('',*,*,#1399,.T.);
+#1794=ORIENTED_EDGE('',*,*,#1400,.F.);
+#1795=ORIENTED_EDGE('',*,*,#1376,.T.);
+#1796=ORIENTED_EDGE('',*,*,#1377,.T.);
+#1797=ORIENTED_EDGE('',*,*,#1400,.T.);
+#1798=ORIENTED_EDGE('',*,*,#1401,.T.);
+#1799=ORIENTED_EDGE('',*,*,#1402,.T.);
+#1800=ORIENTED_EDGE('',*,*,#1369,.F.);
+#1801=ORIENTED_EDGE('',*,*,#1387,.T.);
+#1802=ORIENTED_EDGE('',*,*,#1403,.T.);
+#1803=ORIENTED_EDGE('',*,*,#1404,.F.);
+#1804=ORIENTED_EDGE('',*,*,#1405,.F.);
+#1805=ORIENTED_EDGE('',*,*,#1378,.T.);
+#1806=ORIENTED_EDGE('',*,*,#1402,.F.);
+#1807=ORIENTED_EDGE('',*,*,#1406,.T.);
+#1808=ORIENTED_EDGE('',*,*,#1386,.T.);
+#1809=ORIENTED_EDGE('',*,*,#1407,.F.);
+#1810=ORIENTED_EDGE('',*,*,#1408,.T.);
+#1811=ORIENTED_EDGE('',*,*,#1403,.F.);
+#1812=ORIENTED_EDGE('',*,*,#1379,.T.);
+#1813=ORIENTED_EDGE('',*,*,#1405,.T.);
+#1814=ORIENTED_EDGE('',*,*,#1409,.F.);
+#1815=ORIENTED_EDGE('',*,*,#1410,.T.);
+#1816=ORIENTED_EDGE('',*,*,#1395,.F.);
+#1817=ORIENTED_EDGE('',*,*,#1411,.T.);
+#1818=ORIENTED_EDGE('',*,*,#1396,.F.);
+#1819=ORIENTED_EDGE('',*,*,#1374,.T.);
+#1820=ORIENTED_EDGE('',*,*,#1412,.F.);
+#1821=ORIENTED_EDGE('',*,*,#1380,.F.);
+#1822=ORIENTED_EDGE('',*,*,#1410,.F.);
+#1823=ORIENTED_EDGE('',*,*,#1413,.F.);
+#1824=ORIENTED_EDGE('',*,*,#1409,.T.);
+#1825=ORIENTED_EDGE('',*,*,#1404,.T.);
+#1826=ORIENTED_EDGE('',*,*,#1408,.F.);
+#1827=ORIENTED_EDGE('',*,*,#1414,.F.);
+#1828=ORIENTED_EDGE('',*,*,#1413,.T.);
+#1829=ORIENTED_EDGE('',*,*,#1415,.F.);
+#1830=ORIENTED_EDGE('',*,*,#1416,.T.);
+#1831=ORIENTED_EDGE('',*,*,#1382,.F.);
+#1832=ORIENTED_EDGE('',*,*,#1417,.F.);
+#1833=ORIENTED_EDGE('',*,*,#1418,.F.);
+#1834=ORIENTED_EDGE('',*,*,#1419,.T.);
+#1835=ORIENTED_EDGE('',*,*,#1383,.F.);
+#1836=ORIENTED_EDGE('',*,*,#1416,.F.);
+#1837=ORIENTED_EDGE('',*,*,#1407,.T.);
+#1838=ORIENTED_EDGE('',*,*,#1385,.F.);
+#1839=ORIENTED_EDGE('',*,*,#1420,.F.);
+#1840=ORIENTED_EDGE('',*,*,#1421,.F.);
+#1841=ORIENTED_EDGE('',*,*,#1417,.T.);
+#1842=ORIENTED_EDGE('',*,*,#1381,.F.);
+#1843=ORIENTED_EDGE('',*,*,#1412,.T.);
+#1844=ORIENTED_EDGE('',*,*,#1414,.T.);
+#1845=ORIENTED_EDGE('',*,*,#1422,.F.);
+#1846=ORIENTED_EDGE('',*,*,#1420,.T.);
+#1847=ORIENTED_EDGE('',*,*,#1384,.F.);
+#1848=ORIENTED_EDGE('',*,*,#1419,.F.);
+#1849=ORIENTED_EDGE('',*,*,#1388,.T.);
+#1850=ORIENTED_EDGE('',*,*,#1423,.T.);
+#1851=ORIENTED_EDGE('',*,*,#1424,.T.);
+#1852=ORIENTED_EDGE('',*,*,#1423,.F.);
+#1853=ORIENTED_EDGE('',*,*,#1389,.T.);
+#1854=ORIENTED_EDGE('',*,*,#1425,.T.);
+#1855=ORIENTED_EDGE('',*,*,#1426,.T.);
+#1856=ORIENTED_EDGE('',*,*,#1425,.F.);
+#1857=ORIENTED_EDGE('',*,*,#1390,.T.);
+#1858=ORIENTED_EDGE('',*,*,#1427,.T.);
+#1859=ORIENTED_EDGE('',*,*,#1428,.T.);
+#1860=ORIENTED_EDGE('',*,*,#1427,.F.);
+#1861=ORIENTED_EDGE('',*,*,#1391,.T.);
+#1862=ORIENTED_EDGE('',*,*,#1429,.T.);
+#1863=ORIENTED_EDGE('',*,*,#1430,.T.);
+#1864=ORIENTED_EDGE('',*,*,#1429,.F.);
+#1865=ORIENTED_EDGE('',*,*,#1418,.T.);
+#1866=ORIENTED_EDGE('',*,*,#1415,.T.);
+#1867=ORIENTED_EDGE('',*,*,#1421,.T.);
+#1868=ORIENTED_EDGE('',*,*,#1422,.T.);
+#1869=ORIENTED_EDGE('',*,*,#1370,.F.);
+#1870=ORIENTED_EDGE('',*,*,#1406,.F.);
+#1871=ORIENTED_EDGE('',*,*,#1401,.F.);
+#1872=ORIENTED_EDGE('',*,*,#1399,.F.);
+#1873=ORIENTED_EDGE('',*,*,#1397,.F.);
+#1874=ORIENTED_EDGE('',*,*,#1411,.F.);
+#1875=ORIENTED_EDGE('',*,*,#1394,.F.);
+#1876=ORIENTED_EDGE('',*,*,#1392,.F.);
+#1877=ORIENTED_EDGE('',*,*,#1430,.F.);
+#1878=ORIENTED_EDGE('',*,*,#1428,.F.);
+#1879=ORIENTED_EDGE('',*,*,#1426,.F.);
+#1880=ORIENTED_EDGE('',*,*,#1424,.F.);
+#1881=ORIENTED_EDGE('',*,*,#1431,.T.);
+#1882=ORIENTED_EDGE('',*,*,#1432,.T.);
+#1883=ORIENTED_EDGE('',*,*,#1433,.T.);
+#1884=ORIENTED_EDGE('',*,*,#1434,.T.);
+#1885=ORIENTED_EDGE('',*,*,#1434,.F.);
+#1886=ORIENTED_EDGE('',*,*,#1435,.F.);
+#1887=ORIENTED_EDGE('',*,*,#1436,.T.);
+#1888=ORIENTED_EDGE('',*,*,#1437,.F.);
+#1889=ORIENTED_EDGE('',*,*,#1433,.F.);
+#1890=ORIENTED_EDGE('',*,*,#1438,.T.);
+#1891=ORIENTED_EDGE('',*,*,#1439,.F.);
+#1892=ORIENTED_EDGE('',*,*,#1440,.T.);
+#1893=ORIENTED_EDGE('',*,*,#1441,.F.);
+#1894=ORIENTED_EDGE('',*,*,#1442,.T.);
+#1895=ORIENTED_EDGE('',*,*,#1443,.F.);
+#1896=ORIENTED_EDGE('',*,*,#1444,.T.);
+#1897=ORIENTED_EDGE('',*,*,#1445,.T.);
+#1898=ORIENTED_EDGE('',*,*,#1446,.T.);
+#1899=ORIENTED_EDGE('',*,*,#1447,.T.);
+#1900=ORIENTED_EDGE('',*,*,#1435,.T.);
+#1901=ORIENTED_EDGE('',*,*,#1448,.T.);
+#1902=ORIENTED_EDGE('',*,*,#1449,.T.);
+#1903=ORIENTED_EDGE('',*,*,#1450,.T.);
+#1904=ORIENTED_EDGE('',*,*,#1451,.T.);
+#1905=ORIENTED_EDGE('',*,*,#1452,.T.);
+#1906=ORIENTED_EDGE('',*,*,#1453,.T.);
+#1907=ORIENTED_EDGE('',*,*,#1454,.T.);
+#1908=ORIENTED_EDGE('',*,*,#1455,.T.);
+#1909=ORIENTED_EDGE('',*,*,#1456,.T.);
+#1910=ORIENTED_EDGE('',*,*,#1457,.T.);
+#1911=ORIENTED_EDGE('',*,*,#1458,.T.);
+#1912=ORIENTED_EDGE('',*,*,#1459,.T.);
+#1913=ORIENTED_EDGE('',*,*,#1460,.T.);
+#1914=ORIENTED_EDGE('',*,*,#1461,.T.);
+#1915=ORIENTED_EDGE('',*,*,#1462,.T.);
+#1916=ORIENTED_EDGE('',*,*,#1463,.T.);
+#1917=ORIENTED_EDGE('',*,*,#1464,.T.);
+#1918=ORIENTED_EDGE('',*,*,#1465,.T.);
+#1919=ORIENTED_EDGE('',*,*,#1466,.T.);
+#1920=ORIENTED_EDGE('',*,*,#1467,.T.);
+#1921=ORIENTED_EDGE('',*,*,#1468,.T.);
+#1922=ORIENTED_EDGE('',*,*,#1469,.T.);
+#1923=ORIENTED_EDGE('',*,*,#1470,.T.);
+#1924=ORIENTED_EDGE('',*,*,#1471,.T.);
+#1925=ORIENTED_EDGE('',*,*,#1472,.T.);
+#1926=ORIENTED_EDGE('',*,*,#1473,.T.);
+#1927=ORIENTED_EDGE('',*,*,#1474,.T.);
+#1928=ORIENTED_EDGE('',*,*,#1475,.T.);
+#1929=ORIENTED_EDGE('',*,*,#1476,.T.);
+#1930=ORIENTED_EDGE('',*,*,#1477,.T.);
+#1931=ORIENTED_EDGE('',*,*,#1478,.T.);
+#1932=ORIENTED_EDGE('',*,*,#1479,.T.);
+#1933=ORIENTED_EDGE('',*,*,#1480,.T.);
+#1934=ORIENTED_EDGE('',*,*,#1481,.T.);
+#1935=ORIENTED_EDGE('',*,*,#1482,.T.);
+#1936=ORIENTED_EDGE('',*,*,#1483,.T.);
+#1937=ORIENTED_EDGE('',*,*,#1484,.T.);
+#1938=ORIENTED_EDGE('',*,*,#1485,.T.);
+#1939=ORIENTED_EDGE('',*,*,#1486,.T.);
+#1940=ORIENTED_EDGE('',*,*,#1487,.T.);
+#1941=ORIENTED_EDGE('',*,*,#1488,.T.);
+#1942=ORIENTED_EDGE('',*,*,#1489,.T.);
+#1943=ORIENTED_EDGE('',*,*,#1490,.T.);
+#1944=ORIENTED_EDGE('',*,*,#1491,.T.);
+#1945=ORIENTED_EDGE('',*,*,#1492,.T.);
+#1946=ORIENTED_EDGE('',*,*,#1493,.T.);
+#1947=ORIENTED_EDGE('',*,*,#1494,.T.);
+#1948=ORIENTED_EDGE('',*,*,#1495,.T.);
+#1949=ORIENTED_EDGE('',*,*,#1496,.T.);
+#1950=ORIENTED_EDGE('',*,*,#1497,.T.);
+#1951=ORIENTED_EDGE('',*,*,#1498,.T.);
+#1952=ORIENTED_EDGE('',*,*,#1499,.T.);
+#1953=ORIENTED_EDGE('',*,*,#1500,.T.);
+#1954=ORIENTED_EDGE('',*,*,#1501,.T.);
+#1955=ORIENTED_EDGE('',*,*,#1502,.T.);
+#1956=ORIENTED_EDGE('',*,*,#1503,.T.);
+#1957=ORIENTED_EDGE('',*,*,#1504,.T.);
+#1958=ORIENTED_EDGE('',*,*,#1505,.T.);
+#1959=ORIENTED_EDGE('',*,*,#1506,.T.);
+#1960=ORIENTED_EDGE('',*,*,#1507,.T.);
+#1961=ORIENTED_EDGE('',*,*,#1508,.T.);
+#1962=ORIENTED_EDGE('',*,*,#1509,.T.);
+#1963=ORIENTED_EDGE('',*,*,#1510,.T.);
+#1964=ORIENTED_EDGE('',*,*,#1511,.T.);
+#1965=ORIENTED_EDGE('',*,*,#1512,.T.);
+#1966=ORIENTED_EDGE('',*,*,#1513,.T.);
+#1967=ORIENTED_EDGE('',*,*,#1514,.T.);
+#1968=ORIENTED_EDGE('',*,*,#1515,.T.);
+#1969=ORIENTED_EDGE('',*,*,#1516,.T.);
+#1970=ORIENTED_EDGE('',*,*,#1517,.T.);
+#1971=ORIENTED_EDGE('',*,*,#1518,.T.);
+#1972=ORIENTED_EDGE('',*,*,#1519,.T.);
+#1973=ORIENTED_EDGE('',*,*,#1520,.T.);
+#1974=ORIENTED_EDGE('',*,*,#1521,.T.);
+#1975=ORIENTED_EDGE('',*,*,#1522,.T.);
+#1976=ORIENTED_EDGE('',*,*,#1523,.T.);
+#1977=ORIENTED_EDGE('',*,*,#1524,.T.);
+#1978=ORIENTED_EDGE('',*,*,#1525,.T.);
+#1979=ORIENTED_EDGE('',*,*,#1526,.T.);
+#1980=ORIENTED_EDGE('',*,*,#1527,.T.);
+#1981=ORIENTED_EDGE('',*,*,#1528,.T.);
+#1982=ORIENTED_EDGE('',*,*,#1529,.T.);
+#1983=ORIENTED_EDGE('',*,*,#1439,.T.);
+#1984=ORIENTED_EDGE('',*,*,#1530,.T.);
+#1985=ORIENTED_EDGE('',*,*,#1529,.F.);
+#1986=ORIENTED_EDGE('',*,*,#1531,.F.);
+#1987=ORIENTED_EDGE('',*,*,#1532,.F.);
+#1988=ORIENTED_EDGE('',*,*,#1440,.F.);
+#1989=ORIENTED_EDGE('',*,*,#1533,.T.);
+#1990=ORIENTED_EDGE('',*,*,#1534,.T.);
+#1991=ORIENTED_EDGE('',*,*,#1441,.T.);
+#1992=ORIENTED_EDGE('',*,*,#1532,.T.);
+#1993=ORIENTED_EDGE('',*,*,#1535,.T.);
+#1994=ORIENTED_EDGE('',*,*,#1536,.T.);
+#1995=ORIENTED_EDGE('',*,*,#1443,.T.);
+#1996=ORIENTED_EDGE('',*,*,#1537,.T.);
+#1997=ORIENTED_EDGE('',*,*,#1536,.F.);
+#1998=ORIENTED_EDGE('',*,*,#1538,.F.);
+#1999=ORIENTED_EDGE('',*,*,#1539,.F.);
+#2000=ORIENTED_EDGE('',*,*,#1444,.F.);
+#2001=ORIENTED_EDGE('',*,*,#1540,.F.);
+#2002=ORIENTED_EDGE('',*,*,#1541,.T.);
+#2003=ORIENTED_EDGE('',*,*,#1527,.F.);
+#2004=ORIENTED_EDGE('',*,*,#1541,.F.);
+#2005=ORIENTED_EDGE('',*,*,#1542,.F.);
+#2006=ORIENTED_EDGE('',*,*,#1543,.T.);
+#2007=ORIENTED_EDGE('',*,*,#1526,.F.);
+#2008=ORIENTED_EDGE('',*,*,#1543,.F.);
+#2009=ORIENTED_EDGE('',*,*,#1544,.F.);
+#2010=ORIENTED_EDGE('',*,*,#1545,.T.);
+#2011=ORIENTED_EDGE('',*,*,#1525,.F.);
+#2012=ORIENTED_EDGE('',*,*,#1545,.F.);
+#2013=ORIENTED_EDGE('',*,*,#1546,.F.);
+#2014=ORIENTED_EDGE('',*,*,#1547,.T.);
+#2015=ORIENTED_EDGE('',*,*,#1524,.F.);
+#2016=ORIENTED_EDGE('',*,*,#1547,.F.);
+#2017=ORIENTED_EDGE('',*,*,#1517,.F.);
+#2018=ORIENTED_EDGE('',*,*,#1548,.T.);
+#2019=ORIENTED_EDGE('',*,*,#1549,.F.);
+#2020=ORIENTED_EDGE('',*,*,#1550,.F.);
+#2021=ORIENTED_EDGE('',*,*,#1518,.F.);
+#2022=ORIENTED_EDGE('',*,*,#1550,.T.);
+#2023=ORIENTED_EDGE('',*,*,#1551,.F.);
+#2024=ORIENTED_EDGE('',*,*,#1552,.F.);
+#2025=ORIENTED_EDGE('',*,*,#1519,.F.);
+#2026=ORIENTED_EDGE('',*,*,#1552,.T.);
+#2027=ORIENTED_EDGE('',*,*,#1553,.F.);
+#2028=ORIENTED_EDGE('',*,*,#1554,.F.);
+#2029=ORIENTED_EDGE('',*,*,#1520,.F.);
+#2030=ORIENTED_EDGE('',*,*,#1554,.T.);
+#2031=ORIENTED_EDGE('',*,*,#1555,.F.);
+#2032=ORIENTED_EDGE('',*,*,#1556,.F.);
+#2033=ORIENTED_EDGE('',*,*,#1521,.F.);
+#2034=ORIENTED_EDGE('',*,*,#1556,.T.);
+#2035=ORIENTED_EDGE('',*,*,#1557,.F.);
+#2036=ORIENTED_EDGE('',*,*,#1558,.F.);
+#2037=ORIENTED_EDGE('',*,*,#1522,.F.);
+#2038=ORIENTED_EDGE('',*,*,#1558,.T.);
+#2039=ORIENTED_EDGE('',*,*,#1559,.F.);
+#2040=ORIENTED_EDGE('',*,*,#1560,.F.);
+#2041=ORIENTED_EDGE('',*,*,#1523,.F.);
+#2042=ORIENTED_EDGE('',*,*,#1560,.T.);
+#2043=ORIENTED_EDGE('',*,*,#1561,.F.);
+#2044=ORIENTED_EDGE('',*,*,#1562,.F.);
+#2045=ORIENTED_EDGE('',*,*,#1516,.F.);
+#2046=ORIENTED_EDGE('',*,*,#1562,.T.);
+#2047=ORIENTED_EDGE('',*,*,#1563,.F.);
+#2048=ORIENTED_EDGE('',*,*,#1548,.F.);
+#2049=ORIENTED_EDGE('',*,*,#1509,.F.);
+#2050=ORIENTED_EDGE('',*,*,#1564,.T.);
+#2051=ORIENTED_EDGE('',*,*,#1565,.F.);
+#2052=ORIENTED_EDGE('',*,*,#1566,.F.);
+#2053=ORIENTED_EDGE('',*,*,#1510,.F.);
+#2054=ORIENTED_EDGE('',*,*,#1566,.T.);
+#2055=ORIENTED_EDGE('',*,*,#1567,.F.);
+#2056=ORIENTED_EDGE('',*,*,#1568,.F.);
+#2057=ORIENTED_EDGE('',*,*,#1511,.F.);
+#2058=ORIENTED_EDGE('',*,*,#1568,.T.);
+#2059=ORIENTED_EDGE('',*,*,#1569,.F.);
+#2060=ORIENTED_EDGE('',*,*,#1570,.F.);
+#2061=ORIENTED_EDGE('',*,*,#1512,.F.);
+#2062=ORIENTED_EDGE('',*,*,#1570,.T.);
+#2063=ORIENTED_EDGE('',*,*,#1571,.F.);
+#2064=ORIENTED_EDGE('',*,*,#1572,.F.);
+#2065=ORIENTED_EDGE('',*,*,#1513,.F.);
+#2066=ORIENTED_EDGE('',*,*,#1572,.T.);
+#2067=ORIENTED_EDGE('',*,*,#1573,.F.);
+#2068=ORIENTED_EDGE('',*,*,#1574,.F.);
+#2069=ORIENTED_EDGE('',*,*,#1514,.F.);
+#2070=ORIENTED_EDGE('',*,*,#1574,.T.);
+#2071=ORIENTED_EDGE('',*,*,#1575,.F.);
+#2072=ORIENTED_EDGE('',*,*,#1576,.F.);
+#2073=ORIENTED_EDGE('',*,*,#1515,.F.);
+#2074=ORIENTED_EDGE('',*,*,#1576,.T.);
+#2075=ORIENTED_EDGE('',*,*,#1577,.F.);
+#2076=ORIENTED_EDGE('',*,*,#1578,.F.);
+#2077=ORIENTED_EDGE('',*,*,#1508,.F.);
+#2078=ORIENTED_EDGE('',*,*,#1578,.T.);
+#2079=ORIENTED_EDGE('',*,*,#1579,.F.);
+#2080=ORIENTED_EDGE('',*,*,#1564,.F.);
+#2081=ORIENTED_EDGE('',*,*,#1501,.F.);
+#2082=ORIENTED_EDGE('',*,*,#1580,.T.);
+#2083=ORIENTED_EDGE('',*,*,#1581,.F.);
+#2084=ORIENTED_EDGE('',*,*,#1582,.F.);
+#2085=ORIENTED_EDGE('',*,*,#1502,.F.);
+#2086=ORIENTED_EDGE('',*,*,#1582,.T.);
+#2087=ORIENTED_EDGE('',*,*,#1583,.F.);
+#2088=ORIENTED_EDGE('',*,*,#1584,.F.);
+#2089=ORIENTED_EDGE('',*,*,#1503,.F.);
+#2090=ORIENTED_EDGE('',*,*,#1584,.T.);
+#2091=ORIENTED_EDGE('',*,*,#1585,.F.);
+#2092=ORIENTED_EDGE('',*,*,#1586,.F.);
+#2093=ORIENTED_EDGE('',*,*,#1504,.F.);
+#2094=ORIENTED_EDGE('',*,*,#1586,.T.);
+#2095=ORIENTED_EDGE('',*,*,#1587,.F.);
+#2096=ORIENTED_EDGE('',*,*,#1588,.F.);
+#2097=ORIENTED_EDGE('',*,*,#1505,.F.);
+#2098=ORIENTED_EDGE('',*,*,#1588,.T.);
+#2099=ORIENTED_EDGE('',*,*,#1589,.F.);
+#2100=ORIENTED_EDGE('',*,*,#1590,.F.);
+#2101=ORIENTED_EDGE('',*,*,#1506,.F.);
+#2102=ORIENTED_EDGE('',*,*,#1590,.T.);
+#2103=ORIENTED_EDGE('',*,*,#1591,.F.);
+#2104=ORIENTED_EDGE('',*,*,#1592,.F.);
+#2105=ORIENTED_EDGE('',*,*,#1507,.F.);
+#2106=ORIENTED_EDGE('',*,*,#1592,.T.);
+#2107=ORIENTED_EDGE('',*,*,#1593,.F.);
+#2108=ORIENTED_EDGE('',*,*,#1594,.F.);
+#2109=ORIENTED_EDGE('',*,*,#1500,.F.);
+#2110=ORIENTED_EDGE('',*,*,#1594,.T.);
+#2111=ORIENTED_EDGE('',*,*,#1595,.F.);
+#2112=ORIENTED_EDGE('',*,*,#1580,.F.);
+#2113=ORIENTED_EDGE('',*,*,#1493,.F.);
+#2114=ORIENTED_EDGE('',*,*,#1596,.T.);
+#2115=ORIENTED_EDGE('',*,*,#1597,.F.);
+#2116=ORIENTED_EDGE('',*,*,#1598,.F.);
+#2117=ORIENTED_EDGE('',*,*,#1494,.F.);
+#2118=ORIENTED_EDGE('',*,*,#1598,.T.);
+#2119=ORIENTED_EDGE('',*,*,#1599,.F.);
+#2120=ORIENTED_EDGE('',*,*,#1600,.F.);
+#2121=ORIENTED_EDGE('',*,*,#1495,.F.);
+#2122=ORIENTED_EDGE('',*,*,#1600,.T.);
+#2123=ORIENTED_EDGE('',*,*,#1601,.F.);
+#2124=ORIENTED_EDGE('',*,*,#1602,.F.);
+#2125=ORIENTED_EDGE('',*,*,#1496,.F.);
+#2126=ORIENTED_EDGE('',*,*,#1602,.T.);
+#2127=ORIENTED_EDGE('',*,*,#1603,.F.);
+#2128=ORIENTED_EDGE('',*,*,#1604,.F.);
+#2129=ORIENTED_EDGE('',*,*,#1497,.F.);
+#2130=ORIENTED_EDGE('',*,*,#1604,.T.);
+#2131=ORIENTED_EDGE('',*,*,#1605,.F.);
+#2132=ORIENTED_EDGE('',*,*,#1606,.F.);
+#2133=ORIENTED_EDGE('',*,*,#1498,.F.);
+#2134=ORIENTED_EDGE('',*,*,#1606,.T.);
+#2135=ORIENTED_EDGE('',*,*,#1607,.F.);
+#2136=ORIENTED_EDGE('',*,*,#1608,.F.);
+#2137=ORIENTED_EDGE('',*,*,#1499,.F.);
+#2138=ORIENTED_EDGE('',*,*,#1608,.T.);
+#2139=ORIENTED_EDGE('',*,*,#1609,.F.);
+#2140=ORIENTED_EDGE('',*,*,#1610,.F.);
+#2141=ORIENTED_EDGE('',*,*,#1492,.F.);
+#2142=ORIENTED_EDGE('',*,*,#1610,.T.);
+#2143=ORIENTED_EDGE('',*,*,#1611,.F.);
+#2144=ORIENTED_EDGE('',*,*,#1596,.F.);
+#2145=ORIENTED_EDGE('',*,*,#1485,.F.);
+#2146=ORIENTED_EDGE('',*,*,#1612,.T.);
+#2147=ORIENTED_EDGE('',*,*,#1613,.F.);
+#2148=ORIENTED_EDGE('',*,*,#1614,.F.);
+#2149=ORIENTED_EDGE('',*,*,#1486,.F.);
+#2150=ORIENTED_EDGE('',*,*,#1614,.T.);
+#2151=ORIENTED_EDGE('',*,*,#1615,.F.);
+#2152=ORIENTED_EDGE('',*,*,#1616,.F.);
+#2153=ORIENTED_EDGE('',*,*,#1487,.F.);
+#2154=ORIENTED_EDGE('',*,*,#1616,.T.);
+#2155=ORIENTED_EDGE('',*,*,#1617,.F.);
+#2156=ORIENTED_EDGE('',*,*,#1618,.F.);
+#2157=ORIENTED_EDGE('',*,*,#1488,.F.);
+#2158=ORIENTED_EDGE('',*,*,#1618,.T.);
+#2159=ORIENTED_EDGE('',*,*,#1619,.F.);
+#2160=ORIENTED_EDGE('',*,*,#1620,.F.);
+#2161=ORIENTED_EDGE('',*,*,#1489,.F.);
+#2162=ORIENTED_EDGE('',*,*,#1620,.T.);
+#2163=ORIENTED_EDGE('',*,*,#1621,.F.);
+#2164=ORIENTED_EDGE('',*,*,#1622,.F.);
+#2165=ORIENTED_EDGE('',*,*,#1490,.F.);
+#2166=ORIENTED_EDGE('',*,*,#1622,.T.);
+#2167=ORIENTED_EDGE('',*,*,#1623,.F.);
+#2168=ORIENTED_EDGE('',*,*,#1624,.F.);
+#2169=ORIENTED_EDGE('',*,*,#1491,.F.);
+#2170=ORIENTED_EDGE('',*,*,#1624,.T.);
+#2171=ORIENTED_EDGE('',*,*,#1625,.F.);
+#2172=ORIENTED_EDGE('',*,*,#1626,.F.);
+#2173=ORIENTED_EDGE('',*,*,#1484,.F.);
+#2174=ORIENTED_EDGE('',*,*,#1626,.T.);
+#2175=ORIENTED_EDGE('',*,*,#1627,.F.);
+#2176=ORIENTED_EDGE('',*,*,#1612,.F.);
+#2177=ORIENTED_EDGE('',*,*,#1477,.F.);
+#2178=ORIENTED_EDGE('',*,*,#1628,.T.);
+#2179=ORIENTED_EDGE('',*,*,#1629,.F.);
+#2180=ORIENTED_EDGE('',*,*,#1630,.F.);
+#2181=ORIENTED_EDGE('',*,*,#1478,.F.);
+#2182=ORIENTED_EDGE('',*,*,#1630,.T.);
+#2183=ORIENTED_EDGE('',*,*,#1631,.F.);
+#2184=ORIENTED_EDGE('',*,*,#1632,.F.);
+#2185=ORIENTED_EDGE('',*,*,#1479,.F.);
+#2186=ORIENTED_EDGE('',*,*,#1632,.T.);
+#2187=ORIENTED_EDGE('',*,*,#1633,.F.);
+#2188=ORIENTED_EDGE('',*,*,#1634,.F.);
+#2189=ORIENTED_EDGE('',*,*,#1480,.F.);
+#2190=ORIENTED_EDGE('',*,*,#1634,.T.);
+#2191=ORIENTED_EDGE('',*,*,#1635,.F.);
+#2192=ORIENTED_EDGE('',*,*,#1636,.F.);
+#2193=ORIENTED_EDGE('',*,*,#1481,.F.);
+#2194=ORIENTED_EDGE('',*,*,#1636,.T.);
+#2195=ORIENTED_EDGE('',*,*,#1637,.F.);
+#2196=ORIENTED_EDGE('',*,*,#1638,.F.);
+#2197=ORIENTED_EDGE('',*,*,#1482,.F.);
+#2198=ORIENTED_EDGE('',*,*,#1638,.T.);
+#2199=ORIENTED_EDGE('',*,*,#1639,.F.);
+#2200=ORIENTED_EDGE('',*,*,#1640,.F.);
+#2201=ORIENTED_EDGE('',*,*,#1483,.F.);
+#2202=ORIENTED_EDGE('',*,*,#1640,.T.);
+#2203=ORIENTED_EDGE('',*,*,#1641,.F.);
+#2204=ORIENTED_EDGE('',*,*,#1642,.F.);
+#2205=ORIENTED_EDGE('',*,*,#1476,.F.);
+#2206=ORIENTED_EDGE('',*,*,#1642,.T.);
+#2207=ORIENTED_EDGE('',*,*,#1643,.F.);
+#2208=ORIENTED_EDGE('',*,*,#1628,.F.);
+#2209=ORIENTED_EDGE('',*,*,#1469,.F.);
+#2210=ORIENTED_EDGE('',*,*,#1644,.T.);
+#2211=ORIENTED_EDGE('',*,*,#1645,.F.);
+#2212=ORIENTED_EDGE('',*,*,#1646,.F.);
+#2213=ORIENTED_EDGE('',*,*,#1470,.F.);
+#2214=ORIENTED_EDGE('',*,*,#1646,.T.);
+#2215=ORIENTED_EDGE('',*,*,#1647,.F.);
+#2216=ORIENTED_EDGE('',*,*,#1648,.F.);
+#2217=ORIENTED_EDGE('',*,*,#1471,.F.);
+#2218=ORIENTED_EDGE('',*,*,#1648,.T.);
+#2219=ORIENTED_EDGE('',*,*,#1649,.F.);
+#2220=ORIENTED_EDGE('',*,*,#1650,.F.);
+#2221=ORIENTED_EDGE('',*,*,#1472,.F.);
+#2222=ORIENTED_EDGE('',*,*,#1650,.T.);
+#2223=ORIENTED_EDGE('',*,*,#1651,.F.);
+#2224=ORIENTED_EDGE('',*,*,#1652,.F.);
+#2225=ORIENTED_EDGE('',*,*,#1473,.F.);
+#2226=ORIENTED_EDGE('',*,*,#1652,.T.);
+#2227=ORIENTED_EDGE('',*,*,#1653,.F.);
+#2228=ORIENTED_EDGE('',*,*,#1654,.F.);
+#2229=ORIENTED_EDGE('',*,*,#1474,.F.);
+#2230=ORIENTED_EDGE('',*,*,#1654,.T.);
+#2231=ORIENTED_EDGE('',*,*,#1655,.F.);
+#2232=ORIENTED_EDGE('',*,*,#1656,.F.);
+#2233=ORIENTED_EDGE('',*,*,#1475,.F.);
+#2234=ORIENTED_EDGE('',*,*,#1656,.T.);
+#2235=ORIENTED_EDGE('',*,*,#1657,.F.);
+#2236=ORIENTED_EDGE('',*,*,#1658,.F.);
+#2237=ORIENTED_EDGE('',*,*,#1468,.F.);
+#2238=ORIENTED_EDGE('',*,*,#1658,.T.);
+#2239=ORIENTED_EDGE('',*,*,#1659,.F.);
+#2240=ORIENTED_EDGE('',*,*,#1644,.F.);
+#2241=ORIENTED_EDGE('',*,*,#1461,.F.);
+#2242=ORIENTED_EDGE('',*,*,#1660,.T.);
+#2243=ORIENTED_EDGE('',*,*,#1661,.F.);
+#2244=ORIENTED_EDGE('',*,*,#1662,.F.);
+#2245=ORIENTED_EDGE('',*,*,#1462,.F.);
+#2246=ORIENTED_EDGE('',*,*,#1662,.T.);
+#2247=ORIENTED_EDGE('',*,*,#1663,.F.);
+#2248=ORIENTED_EDGE('',*,*,#1664,.F.);
+#2249=ORIENTED_EDGE('',*,*,#1463,.F.);
+#2250=ORIENTED_EDGE('',*,*,#1664,.T.);
+#2251=ORIENTED_EDGE('',*,*,#1665,.F.);
+#2252=ORIENTED_EDGE('',*,*,#1666,.F.);
+#2253=ORIENTED_EDGE('',*,*,#1464,.F.);
+#2254=ORIENTED_EDGE('',*,*,#1666,.T.);
+#2255=ORIENTED_EDGE('',*,*,#1667,.F.);
+#2256=ORIENTED_EDGE('',*,*,#1668,.F.);
+#2257=ORIENTED_EDGE('',*,*,#1465,.F.);
+#2258=ORIENTED_EDGE('',*,*,#1668,.T.);
+#2259=ORIENTED_EDGE('',*,*,#1669,.F.);
+#2260=ORIENTED_EDGE('',*,*,#1670,.F.);
+#2261=ORIENTED_EDGE('',*,*,#1466,.F.);
+#2262=ORIENTED_EDGE('',*,*,#1670,.T.);
+#2263=ORIENTED_EDGE('',*,*,#1671,.F.);
+#2264=ORIENTED_EDGE('',*,*,#1672,.F.);
+#2265=ORIENTED_EDGE('',*,*,#1467,.F.);
+#2266=ORIENTED_EDGE('',*,*,#1672,.T.);
+#2267=ORIENTED_EDGE('',*,*,#1673,.F.);
+#2268=ORIENTED_EDGE('',*,*,#1674,.F.);
+#2269=ORIENTED_EDGE('',*,*,#1460,.F.);
+#2270=ORIENTED_EDGE('',*,*,#1674,.T.);
+#2271=ORIENTED_EDGE('',*,*,#1675,.F.);
+#2272=ORIENTED_EDGE('',*,*,#1660,.F.);
+#2273=ORIENTED_EDGE('',*,*,#1453,.F.);
+#2274=ORIENTED_EDGE('',*,*,#1676,.T.);
+#2275=ORIENTED_EDGE('',*,*,#1677,.F.);
+#2276=ORIENTED_EDGE('',*,*,#1678,.F.);
+#2277=ORIENTED_EDGE('',*,*,#1454,.F.);
+#2278=ORIENTED_EDGE('',*,*,#1678,.T.);
+#2279=ORIENTED_EDGE('',*,*,#1679,.F.);
+#2280=ORIENTED_EDGE('',*,*,#1680,.F.);
+#2281=ORIENTED_EDGE('',*,*,#1455,.F.);
+#2282=ORIENTED_EDGE('',*,*,#1680,.T.);
+#2283=ORIENTED_EDGE('',*,*,#1681,.F.);
+#2284=ORIENTED_EDGE('',*,*,#1682,.F.);
+#2285=ORIENTED_EDGE('',*,*,#1456,.F.);
+#2286=ORIENTED_EDGE('',*,*,#1682,.T.);
+#2287=ORIENTED_EDGE('',*,*,#1683,.F.);
+#2288=ORIENTED_EDGE('',*,*,#1684,.F.);
+#2289=ORIENTED_EDGE('',*,*,#1457,.F.);
+#2290=ORIENTED_EDGE('',*,*,#1684,.T.);
+#2291=ORIENTED_EDGE('',*,*,#1685,.F.);
+#2292=ORIENTED_EDGE('',*,*,#1686,.F.);
+#2293=ORIENTED_EDGE('',*,*,#1458,.F.);
+#2294=ORIENTED_EDGE('',*,*,#1686,.T.);
+#2295=ORIENTED_EDGE('',*,*,#1687,.F.);
+#2296=ORIENTED_EDGE('',*,*,#1688,.F.);
+#2297=ORIENTED_EDGE('',*,*,#1459,.F.);
+#2298=ORIENTED_EDGE('',*,*,#1688,.T.);
+#2299=ORIENTED_EDGE('',*,*,#1689,.F.);
+#2300=ORIENTED_EDGE('',*,*,#1690,.F.);
+#2301=ORIENTED_EDGE('',*,*,#1452,.F.);
+#2302=ORIENTED_EDGE('',*,*,#1690,.T.);
+#2303=ORIENTED_EDGE('',*,*,#1691,.F.);
+#2304=ORIENTED_EDGE('',*,*,#1676,.F.);
+#2305=ORIENTED_EDGE('',*,*,#1449,.F.);
+#2306=ORIENTED_EDGE('',*,*,#1692,.T.);
+#2307=ORIENTED_EDGE('',*,*,#1693,.F.);
+#2308=ORIENTED_EDGE('',*,*,#1694,.F.);
+#2309=ORIENTED_EDGE('',*,*,#1450,.F.);
+#2310=ORIENTED_EDGE('',*,*,#1694,.T.);
+#2311=ORIENTED_EDGE('',*,*,#1695,.F.);
+#2312=ORIENTED_EDGE('',*,*,#1696,.F.);
+#2313=ORIENTED_EDGE('',*,*,#1451,.F.);
+#2314=ORIENTED_EDGE('',*,*,#1696,.T.);
+#2315=ORIENTED_EDGE('',*,*,#1697,.F.);
+#2316=ORIENTED_EDGE('',*,*,#1698,.F.);
+#2317=ORIENTED_EDGE('',*,*,#1448,.F.);
+#2318=ORIENTED_EDGE('',*,*,#1698,.T.);
+#2319=ORIENTED_EDGE('',*,*,#1699,.F.);
+#2320=ORIENTED_EDGE('',*,*,#1692,.F.);
+#2321=ORIENTED_EDGE('',*,*,#1446,.F.);
+#2322=ORIENTED_EDGE('',*,*,#1700,.T.);
+#2323=ORIENTED_EDGE('',*,*,#1701,.F.);
+#2324=ORIENTED_EDGE('',*,*,#1702,.F.);
+#2325=ORIENTED_EDGE('',*,*,#1447,.F.);
+#2326=ORIENTED_EDGE('',*,*,#1702,.T.);
+#2327=ORIENTED_EDGE('',*,*,#1703,.F.);
+#2328=ORIENTED_EDGE('',*,*,#1436,.F.);
+#2329=ORIENTED_EDGE('',*,*,#1432,.F.);
+#2330=ORIENTED_EDGE('',*,*,#1704,.F.);
+#2331=ORIENTED_EDGE('',*,*,#1530,.F.);
+#2332=ORIENTED_EDGE('',*,*,#1438,.F.);
+#2333=ORIENTED_EDGE('',*,*,#1534,.F.);
+#2334=ORIENTED_EDGE('',*,*,#1705,.F.);
+#2335=ORIENTED_EDGE('',*,*,#1537,.F.);
+#2336=ORIENTED_EDGE('',*,*,#1442,.F.);
+#2337=ORIENTED_EDGE('',*,*,#1445,.F.);
+#2338=ORIENTED_EDGE('',*,*,#1539,.T.);
+#2339=ORIENTED_EDGE('',*,*,#1706,.F.);
+#2340=ORIENTED_EDGE('',*,*,#1700,.F.);
+#2341=ORIENTED_EDGE('',*,*,#1431,.F.);
+#2342=ORIENTED_EDGE('',*,*,#1437,.T.);
+#2343=ORIENTED_EDGE('',*,*,#1703,.T.);
+#2344=ORIENTED_EDGE('',*,*,#1701,.T.);
+#2345=ORIENTED_EDGE('',*,*,#1706,.T.);
+#2346=ORIENTED_EDGE('',*,*,#1538,.T.);
+#2347=ORIENTED_EDGE('',*,*,#1535,.F.);
+#2348=ORIENTED_EDGE('',*,*,#1705,.T.);
+#2349=ORIENTED_EDGE('',*,*,#1533,.F.);
+#2350=ORIENTED_EDGE('',*,*,#1531,.T.);
+#2351=ORIENTED_EDGE('',*,*,#1528,.F.);
+#2352=ORIENTED_EDGE('',*,*,#1704,.T.);
+#2353=ORIENTED_EDGE('',*,*,#1699,.T.);
+#2354=ORIENTED_EDGE('',*,*,#1697,.T.);
+#2355=ORIENTED_EDGE('',*,*,#1695,.T.);
+#2356=ORIENTED_EDGE('',*,*,#1693,.T.);
+#2357=ORIENTED_EDGE('',*,*,#1691,.T.);
+#2358=ORIENTED_EDGE('',*,*,#1689,.T.);
+#2359=ORIENTED_EDGE('',*,*,#1687,.T.);
+#2360=ORIENTED_EDGE('',*,*,#1685,.T.);
+#2361=ORIENTED_EDGE('',*,*,#1683,.T.);
+#2362=ORIENTED_EDGE('',*,*,#1681,.T.);
+#2363=ORIENTED_EDGE('',*,*,#1679,.T.);
+#2364=ORIENTED_EDGE('',*,*,#1677,.T.);
+#2365=ORIENTED_EDGE('',*,*,#1675,.T.);
+#2366=ORIENTED_EDGE('',*,*,#1673,.T.);
+#2367=ORIENTED_EDGE('',*,*,#1671,.T.);
+#2368=ORIENTED_EDGE('',*,*,#1669,.T.);
+#2369=ORIENTED_EDGE('',*,*,#1667,.T.);
+#2370=ORIENTED_EDGE('',*,*,#1665,.T.);
+#2371=ORIENTED_EDGE('',*,*,#1663,.T.);
+#2372=ORIENTED_EDGE('',*,*,#1661,.T.);
+#2373=ORIENTED_EDGE('',*,*,#1659,.T.);
+#2374=ORIENTED_EDGE('',*,*,#1657,.T.);
+#2375=ORIENTED_EDGE('',*,*,#1655,.T.);
+#2376=ORIENTED_EDGE('',*,*,#1653,.T.);
+#2377=ORIENTED_EDGE('',*,*,#1651,.T.);
+#2378=ORIENTED_EDGE('',*,*,#1649,.T.);
+#2379=ORIENTED_EDGE('',*,*,#1647,.T.);
+#2380=ORIENTED_EDGE('',*,*,#1645,.T.);
+#2381=ORIENTED_EDGE('',*,*,#1643,.T.);
+#2382=ORIENTED_EDGE('',*,*,#1641,.T.);
+#2383=ORIENTED_EDGE('',*,*,#1639,.T.);
+#2384=ORIENTED_EDGE('',*,*,#1637,.T.);
+#2385=ORIENTED_EDGE('',*,*,#1635,.T.);
+#2386=ORIENTED_EDGE('',*,*,#1633,.T.);
+#2387=ORIENTED_EDGE('',*,*,#1631,.T.);
+#2388=ORIENTED_EDGE('',*,*,#1629,.T.);
+#2389=ORIENTED_EDGE('',*,*,#1627,.T.);
+#2390=ORIENTED_EDGE('',*,*,#1625,.T.);
+#2391=ORIENTED_EDGE('',*,*,#1623,.T.);
+#2392=ORIENTED_EDGE('',*,*,#1621,.T.);
+#2393=ORIENTED_EDGE('',*,*,#1619,.T.);
+#2394=ORIENTED_EDGE('',*,*,#1617,.T.);
+#2395=ORIENTED_EDGE('',*,*,#1615,.T.);
+#2396=ORIENTED_EDGE('',*,*,#1613,.T.);
+#2397=ORIENTED_EDGE('',*,*,#1611,.T.);
+#2398=ORIENTED_EDGE('',*,*,#1609,.T.);
+#2399=ORIENTED_EDGE('',*,*,#1607,.T.);
+#2400=ORIENTED_EDGE('',*,*,#1605,.T.);
+#2401=ORIENTED_EDGE('',*,*,#1603,.T.);
+#2402=ORIENTED_EDGE('',*,*,#1601,.T.);
+#2403=ORIENTED_EDGE('',*,*,#1599,.T.);
+#2404=ORIENTED_EDGE('',*,*,#1597,.T.);
+#2405=ORIENTED_EDGE('',*,*,#1595,.T.);
+#2406=ORIENTED_EDGE('',*,*,#1593,.T.);
+#2407=ORIENTED_EDGE('',*,*,#1591,.T.);
+#2408=ORIENTED_EDGE('',*,*,#1589,.T.);
+#2409=ORIENTED_EDGE('',*,*,#1587,.T.);
+#2410=ORIENTED_EDGE('',*,*,#1585,.T.);
+#2411=ORIENTED_EDGE('',*,*,#1583,.T.);
+#2412=ORIENTED_EDGE('',*,*,#1581,.T.);
+#2413=ORIENTED_EDGE('',*,*,#1579,.T.);
+#2414=ORIENTED_EDGE('',*,*,#1577,.T.);
+#2415=ORIENTED_EDGE('',*,*,#1575,.T.);
+#2416=ORIENTED_EDGE('',*,*,#1573,.T.);
+#2417=ORIENTED_EDGE('',*,*,#1571,.T.);
+#2418=ORIENTED_EDGE('',*,*,#1569,.T.);
+#2419=ORIENTED_EDGE('',*,*,#1567,.T.);
+#2420=ORIENTED_EDGE('',*,*,#1565,.T.);
+#2421=ORIENTED_EDGE('',*,*,#1563,.T.);
+#2422=ORIENTED_EDGE('',*,*,#1561,.T.);
+#2423=ORIENTED_EDGE('',*,*,#1559,.T.);
+#2424=ORIENTED_EDGE('',*,*,#1557,.T.);
+#2425=ORIENTED_EDGE('',*,*,#1555,.T.);
+#2426=ORIENTED_EDGE('',*,*,#1553,.T.);
+#2427=ORIENTED_EDGE('',*,*,#1551,.T.);
+#2428=ORIENTED_EDGE('',*,*,#1549,.T.);
+#2429=ORIENTED_EDGE('',*,*,#1546,.T.);
+#2430=ORIENTED_EDGE('',*,*,#1544,.T.);
+#2431=ORIENTED_EDGE('',*,*,#1542,.T.);
+#2432=ORIENTED_EDGE('',*,*,#1540,.T.);
+#2433=ORIENTED_EDGE('',*,*,#1707,.T.);
+#2434=ORIENTED_EDGE('',*,*,#1708,.T.);
+#2435=ORIENTED_EDGE('',*,*,#1709,.T.);
+#2436=ORIENTED_EDGE('',*,*,#1710,.T.);
+#2437=ORIENTED_EDGE('',*,*,#1710,.F.);
+#2438=ORIENTED_EDGE('',*,*,#1711,.F.);
+#2439=ORIENTED_EDGE('',*,*,#1712,.F.);
+#2440=ORIENTED_EDGE('',*,*,#1713,.F.);
+#2441=ORIENTED_EDGE('',*,*,#1709,.F.);
+#2442=ORIENTED_EDGE('',*,*,#1714,.T.);
+#2443=ORIENTED_EDGE('',*,*,#1715,.F.);
+#2444=ORIENTED_EDGE('',*,*,#1716,.T.);
+#2445=ORIENTED_EDGE('',*,*,#1717,.F.);
+#2446=ORIENTED_EDGE('',*,*,#1718,.T.);
+#2447=ORIENTED_EDGE('',*,*,#1719,.F.);
+#2448=ORIENTED_EDGE('',*,*,#1711,.T.);
+#2449=ORIENTED_EDGE('',*,*,#1720,.T.);
+#2450=ORIENTED_EDGE('',*,*,#1721,.T.);
+#2451=ORIENTED_EDGE('',*,*,#1722,.T.);
+#2452=ORIENTED_EDGE('',*,*,#1723,.T.);
+#2453=ORIENTED_EDGE('',*,*,#1724,.T.);
+#2454=ORIENTED_EDGE('',*,*,#1725,.T.);
+#2455=ORIENTED_EDGE('',*,*,#1726,.T.);
+#2456=ORIENTED_EDGE('',*,*,#1727,.T.);
+#2457=ORIENTED_EDGE('',*,*,#1728,.T.);
+#2458=ORIENTED_EDGE('',*,*,#1712,.T.);
+#2459=ORIENTED_EDGE('',*,*,#1719,.T.);
+#2460=ORIENTED_EDGE('',*,*,#1729,.T.);
+#2461=ORIENTED_EDGE('',*,*,#1729,.F.);
+#2462=ORIENTED_EDGE('',*,*,#1718,.F.);
+#2463=ORIENTED_EDGE('',*,*,#1730,.F.);
+#2464=ORIENTED_EDGE('',*,*,#1731,.F.);
+#2465=ORIENTED_EDGE('',*,*,#1732,.T.);
+#2466=ORIENTED_EDGE('',*,*,#1730,.T.);
+#2467=ORIENTED_EDGE('',*,*,#1717,.T.);
+#2468=ORIENTED_EDGE('',*,*,#1733,.T.);
+#2469=ORIENTED_EDGE('',*,*,#1733,.F.);
+#2470=ORIENTED_EDGE('',*,*,#1716,.F.);
+#2471=ORIENTED_EDGE('',*,*,#1734,.F.);
+#2472=ORIENTED_EDGE('',*,*,#1735,.F.);
+#2473=ORIENTED_EDGE('',*,*,#1736,.T.);
+#2474=ORIENTED_EDGE('',*,*,#1734,.T.);
+#2475=ORIENTED_EDGE('',*,*,#1715,.T.);
+#2476=ORIENTED_EDGE('',*,*,#1737,.T.);
+#2477=ORIENTED_EDGE('',*,*,#1738,.F.);
+#2478=ORIENTED_EDGE('',*,*,#1739,.T.);
+#2479=ORIENTED_EDGE('',*,*,#1727,.F.);
+#2480=ORIENTED_EDGE('',*,*,#1739,.F.);
+#2481=ORIENTED_EDGE('',*,*,#1740,.F.);
+#2482=ORIENTED_EDGE('',*,*,#1741,.T.);
+#2483=ORIENTED_EDGE('',*,*,#1726,.F.);
+#2484=ORIENTED_EDGE('',*,*,#1741,.F.);
+#2485=ORIENTED_EDGE('',*,*,#1742,.F.);
+#2486=ORIENTED_EDGE('',*,*,#1743,.T.);
+#2487=ORIENTED_EDGE('',*,*,#1725,.F.);
+#2488=ORIENTED_EDGE('',*,*,#1743,.F.);
+#2489=ORIENTED_EDGE('',*,*,#1722,.F.);
+#2490=ORIENTED_EDGE('',*,*,#1744,.T.);
+#2491=ORIENTED_EDGE('',*,*,#1745,.F.);
+#2492=ORIENTED_EDGE('',*,*,#1746,.F.);
+#2493=ORIENTED_EDGE('',*,*,#1723,.F.);
+#2494=ORIENTED_EDGE('',*,*,#1746,.T.);
+#2495=ORIENTED_EDGE('',*,*,#1747,.F.);
+#2496=ORIENTED_EDGE('',*,*,#1748,.F.);
+#2497=ORIENTED_EDGE('',*,*,#1724,.F.);
+#2498=ORIENTED_EDGE('',*,*,#1748,.T.);
+#2499=ORIENTED_EDGE('',*,*,#1749,.F.);
+#2500=ORIENTED_EDGE('',*,*,#1750,.F.);
+#2501=ORIENTED_EDGE('',*,*,#1721,.F.);
+#2502=ORIENTED_EDGE('',*,*,#1750,.T.);
+#2503=ORIENTED_EDGE('',*,*,#1751,.F.);
+#2504=ORIENTED_EDGE('',*,*,#1744,.F.);
+#2505=ORIENTED_EDGE('',*,*,#1752,.F.);
+#2506=ORIENTED_EDGE('',*,*,#1753,.T.);
+#2507=ORIENTED_EDGE('',*,*,#1720,.F.);
+#2508=ORIENTED_EDGE('',*,*,#1753,.F.);
+#2509=ORIENTED_EDGE('',*,*,#1708,.F.);
+#2510=ORIENTED_EDGE('',*,*,#1754,.F.);
+#2511=ORIENTED_EDGE('',*,*,#1737,.F.);
+#2512=ORIENTED_EDGE('',*,*,#1714,.F.);
+#2513=ORIENTED_EDGE('',*,*,#1707,.F.);
+#2514=ORIENTED_EDGE('',*,*,#1713,.T.);
+#2515=ORIENTED_EDGE('',*,*,#1728,.F.);
+#2516=ORIENTED_EDGE('',*,*,#1731,.T.);
+#2517=ORIENTED_EDGE('',*,*,#1732,.F.);
+#2518=ORIENTED_EDGE('',*,*,#1735,.T.);
+#2519=ORIENTED_EDGE('',*,*,#1736,.F.);
+#2520=ORIENTED_EDGE('',*,*,#1754,.T.);
+#2521=ORIENTED_EDGE('',*,*,#1752,.T.);
+#2522=ORIENTED_EDGE('',*,*,#1751,.T.);
+#2523=ORIENTED_EDGE('',*,*,#1749,.T.);
+#2524=ORIENTED_EDGE('',*,*,#1747,.T.);
+#2525=ORIENTED_EDGE('',*,*,#1745,.T.);
+#2526=ORIENTED_EDGE('',*,*,#1742,.T.);
+#2527=ORIENTED_EDGE('',*,*,#1740,.T.);
+#2528=ORIENTED_EDGE('',*,*,#1738,.T.);
+#2529=CYLINDRICAL_SURFACE('',#2728,5.);
+#2530=CYLINDRICAL_SURFACE('',#2740,5.);
+#2531=CYLINDRICAL_SURFACE('',#2742,5.);
+#2532=CYLINDRICAL_SURFACE('',#2745,5.);
+#2533=CYLINDRICAL_SURFACE('',#2757,1.45);
+#2534=CYLINDRICAL_SURFACE('',#2759,1.45);
+#2535=CYLINDRICAL_SURFACE('',#2761,1.45);
+#2536=CYLINDRICAL_SURFACE('',#2763,1.45);
+#2537=CYLINDRICAL_SURFACE('',#2767,5.);
+#2538=CYLINDRICAL_SURFACE('',#2815,5.);
+#2539=CYLINDRICAL_SURFACE('',#2818,5.);
+#2540=CYLINDRICAL_SURFACE('',#2820,5.);
+#2541=CYLINDRICAL_SURFACE('',#2823,1.45);
+#2542=CYLINDRICAL_SURFACE('',#2825,1.45);
+#2543=CYLINDRICAL_SURFACE('',#2827,1.45);
+#2544=CYLINDRICAL_SURFACE('',#2829,1.45);
+#2545=CYLINDRICAL_SURFACE('',#2831,0.499999999999998);
+#2546=CYLINDRICAL_SURFACE('',#2834,0.499999999999998);
+#2547=CYLINDRICAL_SURFACE('',#2837,0.499999999999998);
+#2548=CYLINDRICAL_SURFACE('',#2840,0.499999999999989);
+#2549=CYLINDRICAL_SURFACE('',#2843,0.500000000000003);
+#2550=CYLINDRICAL_SURFACE('',#2846,0.499999999999998);
+#2551=CYLINDRICAL_SURFACE('',#2849,0.499999999999998);
+#2552=CYLINDRICAL_SURFACE('',#2852,0.499999999999998);
+#2553=CYLINDRICAL_SURFACE('',#2855,0.499999999999998);
+#2554=CYLINDRICAL_SURFACE('',#2858,0.5);
+#2555=CYLINDRICAL_SURFACE('',#2861,0.499999999999998);
+#2556=CYLINDRICAL_SURFACE('',#2864,0.499999999999998);
+#2557=CYLINDRICAL_SURFACE('',#2867,0.500000000000003);
+#2558=CYLINDRICAL_SURFACE('',#2870,0.499999999999998);
+#2559=CYLINDRICAL_SURFACE('',#2873,0.499999999999998);
+#2560=CYLINDRICAL_SURFACE('',#2876,0.499999999999998);
+#2561=CYLINDRICAL_SURFACE('',#2879,0.500000000000003);
+#2562=CYLINDRICAL_SURFACE('',#2882,0.499999999999998);
+#2563=CYLINDRICAL_SURFACE('',#2885,0.499999999999998);
+#2564=CYLINDRICAL_SURFACE('',#2888,0.499999999999989);
+#2565=CYLINDRICAL_SURFACE('',#2891,0.500000000000003);
+#2566=CYLINDRICAL_SURFACE('',#2894,0.5);
+#2567=CYLINDRICAL_SURFACE('',#2897,0.499999999999998);
+#2568=CYLINDRICAL_SURFACE('',#2900,0.499999999999998);
+#2569=CYLINDRICAL_SURFACE('',#2903,0.499999999999998);
+#2570=CYLINDRICAL_SURFACE('',#2906,0.499999999999998);
+#2571=CYLINDRICAL_SURFACE('',#2909,0.499999999999998);
+#2572=CYLINDRICAL_SURFACE('',#2912,0.499999999999998);
+#2573=CYLINDRICAL_SURFACE('',#2915,0.499999999999998);
+#2574=CYLINDRICAL_SURFACE('',#2918,0.499999999999998);
+#2575=CYLINDRICAL_SURFACE('',#2921,0.499999999999998);
+#2576=CYLINDRICAL_SURFACE('',#2924,0.499999999999998);
+#2577=CYLINDRICAL_SURFACE('',#2927,0.499999999999998);
+#2578=CYLINDRICAL_SURFACE('',#2930,0.499999999999998);
+#2579=CYLINDRICAL_SURFACE('',#2933,0.499999999999998);
+#2580=CYLINDRICAL_SURFACE('',#2936,0.499999999999989);
+#2581=CYLINDRICAL_SURFACE('',#2949,5.);
+#2582=CYLINDRICAL_SURFACE('',#2961,5.);
+#2583=CYLINDRICAL_SURFACE('',#2964,5.);
+#2584=CYLINDRICAL_SURFACE('',#2967,5.);
+#2585=CYLINDRICAL_SURFACE('',#2969,1.45);
+#2586=CYLINDRICAL_SURFACE('',#2971,1.45);
+#2587=CYLINDRICAL_SURFACE('',#2973,1.45);
+#2588=CYLINDRICAL_SURFACE('',#2979,1.45);
+#2589=ADVANCED_FACE('',(#140),#2529,.T.);
+#2590=ADVANCED_FACE('',(#141,#19,#20,#21,#22),#65,.T.);
+#2591=ADVANCED_FACE('',(#142),#66,.T.);
+#2592=ADVANCED_FACE('',(#143),#2530,.T.);
+#2593=ADVANCED_FACE('',(#144),#2531,.T.);
+#2594=ADVANCED_FACE('',(#145),#67,.T.);
+#2595=ADVANCED_FACE('',(#146),#2532,.T.);
+#2596=ADVANCED_FACE('',(#147),#68,.T.);
+#2597=ADVANCED_FACE('',(#148),#69,.F.);
+#2598=ADVANCED_FACE('',(#149),#70,.T.);
+#2599=ADVANCED_FACE('',(#150),#71,.T.);
+#2600=ADVANCED_FACE('',(#151),#72,.T.);
+#2601=ADVANCED_FACE('',(#152),#73,.F.);
+#2602=ADVANCED_FACE('',(#153),#74,.T.);
+#2603=ADVANCED_FACE('',(#154),#75,.T.);
+#2604=ADVANCED_FACE('',(#155),#76,.T.);
+#2605=ADVANCED_FACE('',(#156),#77,.T.);
+#2606=ADVANCED_FACE('',(#157),#2533,.F.);
+#2607=ADVANCED_FACE('',(#158),#2534,.F.);
+#2608=ADVANCED_FACE('',(#159),#2535,.F.);
+#2609=ADVANCED_FACE('',(#160),#2536,.F.);
+#2610=ADVANCED_FACE('',(#161),#78,.T.);
+#2611=ADVANCED_FACE('',(#162,#23,#24,#25,#26),#79,.F.);
+#2612=ADVANCED_FACE('',(#163),#2537,.T.);
+#2613=ADVANCED_FACE('',(#164),#80,.T.);
+#2614=ADVANCED_FACE('',(#165,#27,#28,#29,#30,#31,#32,#33,#34,#35,#36,#37,
+#38,#39,#40),#81,.T.);
+#2615=ADVANCED_FACE('',(#166),#2538,.T.);
+#2616=ADVANCED_FACE('',(#167),#82,.T.);
+#2617=ADVANCED_FACE('',(#168),#2539,.T.);
+#2618=ADVANCED_FACE('',(#169),#2540,.T.);
+#2619=ADVANCED_FACE('',(#170),#83,.T.);
+#2620=ADVANCED_FACE('',(#171),#2541,.F.);
+#2621=ADVANCED_FACE('',(#172),#2542,.F.);
+#2622=ADVANCED_FACE('',(#173),#2543,.F.);
+#2623=ADVANCED_FACE('',(#174),#2544,.F.);
+#2624=ADVANCED_FACE('',(#175),#2545,.F.);
+#2625=ADVANCED_FACE('',(#176),#84,.T.);
+#2626=ADVANCED_FACE('',(#177),#2546,.F.);
+#2627=ADVANCED_FACE('',(#178),#85,.T.);
+#2628=ADVANCED_FACE('',(#179),#2547,.F.);
+#2629=ADVANCED_FACE('',(#180),#86,.T.);
+#2630=ADVANCED_FACE('',(#181),#2548,.F.);
+#2631=ADVANCED_FACE('',(#182),#87,.T.);
+#2632=ADVANCED_FACE('',(#183),#2549,.F.);
+#2633=ADVANCED_FACE('',(#184),#88,.T.);
+#2634=ADVANCED_FACE('',(#185),#2550,.F.);
+#2635=ADVANCED_FACE('',(#186),#89,.T.);
+#2636=ADVANCED_FACE('',(#187),#2551,.F.);
+#2637=ADVANCED_FACE('',(#188),#90,.T.);
+#2638=ADVANCED_FACE('',(#189),#2552,.F.);
+#2639=ADVANCED_FACE('',(#190),#91,.T.);
+#2640=ADVANCED_FACE('',(#191),#2553,.F.);
+#2641=ADVANCED_FACE('',(#192),#92,.T.);
+#2642=ADVANCED_FACE('',(#193),#2554,.F.);
+#2643=ADVANCED_FACE('',(#194),#93,.T.);
+#2644=ADVANCED_FACE('',(#195),#2555,.F.);
+#2645=ADVANCED_FACE('',(#196),#94,.T.);
+#2646=ADVANCED_FACE('',(#197),#2556,.F.);
+#2647=ADVANCED_FACE('',(#198),#95,.T.);
+#2648=ADVANCED_FACE('',(#199),#2557,.F.);
+#2649=ADVANCED_FACE('',(#200),#96,.T.);
+#2650=ADVANCED_FACE('',(#201),#2558,.F.);
+#2651=ADVANCED_FACE('',(#202),#97,.T.);
+#2652=ADVANCED_FACE('',(#203),#2559,.F.);
+#2653=ADVANCED_FACE('',(#204),#98,.T.);
+#2654=ADVANCED_FACE('',(#205),#2560,.F.);
+#2655=ADVANCED_FACE('',(#206),#99,.T.);
+#2656=ADVANCED_FACE('',(#207),#2561,.F.);
+#2657=ADVANCED_FACE('',(#208),#100,.T.);
+#2658=ADVANCED_FACE('',(#209),#2562,.F.);
+#2659=ADVANCED_FACE('',(#210),#101,.T.);
+#2660=ADVANCED_FACE('',(#211),#2563,.F.);
+#2661=ADVANCED_FACE('',(#212),#102,.T.);
+#2662=ADVANCED_FACE('',(#213),#2564,.F.);
+#2663=ADVANCED_FACE('',(#214),#103,.T.);
+#2664=ADVANCED_FACE('',(#215),#2565,.F.);
+#2665=ADVANCED_FACE('',(#216),#104,.T.);
+#2666=ADVANCED_FACE('',(#217),#2566,.F.);
+#2667=ADVANCED_FACE('',(#218),#105,.T.);
+#2668=ADVANCED_FACE('',(#219),#2567,.F.);
+#2669=ADVANCED_FACE('',(#220),#106,.T.);
+#2670=ADVANCED_FACE('',(#221),#2568,.F.);
+#2671=ADVANCED_FACE('',(#222),#107,.T.);
+#2672=ADVANCED_FACE('',(#223),#2569,.F.);
+#2673=ADVANCED_FACE('',(#224),#108,.T.);
+#2674=ADVANCED_FACE('',(#225),#2570,.F.);
+#2675=ADVANCED_FACE('',(#226),#109,.T.);
+#2676=ADVANCED_FACE('',(#227),#2571,.F.);
+#2677=ADVANCED_FACE('',(#228),#110,.T.);
+#2678=ADVANCED_FACE('',(#229),#2572,.F.);
+#2679=ADVANCED_FACE('',(#230),#111,.T.);
+#2680=ADVANCED_FACE('',(#231),#2573,.F.);
+#2681=ADVANCED_FACE('',(#232),#112,.T.);
+#2682=ADVANCED_FACE('',(#233),#2574,.F.);
+#2683=ADVANCED_FACE('',(#234),#113,.T.);
+#2684=ADVANCED_FACE('',(#235),#2575,.F.);
+#2685=ADVANCED_FACE('',(#236),#114,.T.);
+#2686=ADVANCED_FACE('',(#237),#2576,.F.);
+#2687=ADVANCED_FACE('',(#238),#115,.T.);
+#2688=ADVANCED_FACE('',(#239),#2577,.F.);
+#2689=ADVANCED_FACE('',(#240),#116,.T.);
+#2690=ADVANCED_FACE('',(#241),#2578,.F.);
+#2691=ADVANCED_FACE('',(#242),#117,.T.);
+#2692=ADVANCED_FACE('',(#243),#2579,.F.);
+#2693=ADVANCED_FACE('',(#244),#118,.T.);
+#2694=ADVANCED_FACE('',(#245),#2580,.F.);
+#2695=ADVANCED_FACE('',(#246),#119,.T.);
+#2696=ADVANCED_FACE('',(#247),#120,.T.);
+#2697=ADVANCED_FACE('',(#248),#121,.T.);
+#2698=ADVANCED_FACE('',(#249),#122,.T.);
+#2699=ADVANCED_FACE('',(#250),#123,.T.);
+#2700=ADVANCED_FACE('',(#251),#124,.T.);
+#2701=ADVANCED_FACE('',(#252),#125,.T.);
+#2702=ADVANCED_FACE('',(#253),#126,.T.);
+#2703=ADVANCED_FACE('',(#254),#127,.T.);
+#2704=ADVANCED_FACE('',(#255),#128,.T.);
+#2705=ADVANCED_FACE('',(#256,#41,#42,#43,#44,#45,#46,#47,#48,#49,#50,#51,
+#52,#53,#54),#129,.F.);
+#2706=ADVANCED_FACE('',(#257),#2581,.T.);
+#2707=ADVANCED_FACE('',(#258),#130,.T.);
+#2708=ADVANCED_FACE('',(#259,#55,#56,#57,#58,#59),#131,.F.);
+#2709=ADVANCED_FACE('',(#260),#2582,.T.);
+#2710=ADVANCED_FACE('',(#261),#132,.T.);
+#2711=ADVANCED_FACE('',(#262),#2583,.T.);
+#2712=ADVANCED_FACE('',(#263),#133,.T.);
+#2713=ADVANCED_FACE('',(#264),#2584,.T.);
+#2714=ADVANCED_FACE('',(#265),#2585,.F.);
+#2715=ADVANCED_FACE('',(#266),#2586,.F.);
+#2716=ADVANCED_FACE('',(#267),#2587,.F.);
+#2717=ADVANCED_FACE('',(#268),#134,.T.);
+#2718=ADVANCED_FACE('',(#269),#135,.T.);
+#2719=ADVANCED_FACE('',(#270),#136,.T.);
+#2720=ADVANCED_FACE('',(#271),#137,.T.);
+#2721=ADVANCED_FACE('',(#272),#2588,.F.);
+#2722=ADVANCED_FACE('',(#273),#138,.T.);
+#2723=ADVANCED_FACE('',(#274,#60,#61,#62,#63,#64),#139,.T.);
+#2724=CLOSED_SHELL('',(#2589,#2590,#2591,#2592,#2593,#2594,#2595,#2596,
+#2597,#2598,#2599,#2600,#2601,#2602,#2603,#2604,#2605,#2606,#2607,#2608,
+#2609,#2610,#2611));
+#2725=CLOSED_SHELL('',(#2612,#2613,#2614,#2615,#2616,#2617,#2618,#2619,
+#2620,#2621,#2622,#2623,#2624,#2625,#2626,#2627,#2628,#2629,#2630,#2631,
+#2632,#2633,#2634,#2635,#2636,#2637,#2638,#2639,#2640,#2641,#2642,#2643,
+#2644,#2645,#2646,#2647,#2648,#2649,#2650,#2651,#2652,#2653,#2654,#2655,
+#2656,#2657,#2658,#2659,#2660,#2661,#2662,#2663,#2664,#2665,#2666,#2667,
+#2668,#2669,#2670,#2671,#2672,#2673,#2674,#2675,#2676,#2677,#2678,#2679,
+#2680,#2681,#2682,#2683,#2684,#2685,#2686,#2687,#2688,#2689,#2690,#2691,
+#2692,#2693,#2694,#2695,#2696,#2697,#2698,#2699,#2700,#2701,#2702,#2703,
+#2704,#2705));
+#2726=CLOSED_SHELL('',(#2706,#2707,#2708,#2709,#2710,#2711,#2712,#2713,
+#2714,#2715,#2716,#2717,#2718,#2719,#2720,#2721,#2722,#2723));
+#2727=AXIS2_PLACEMENT_3D('',#3762,#2983,#2984);
+#2728=AXIS2_PLACEMENT_3D('',#3763,#2985,#2986);
+#2729=AXIS2_PLACEMENT_3D('',#3766,#2987,#2988);
+#2730=AXIS2_PLACEMENT_3D('',#3770,#2990,#2991);
+#2731=AXIS2_PLACEMENT_3D('',#3772,#2993,#2994);
+#2732=AXIS2_PLACEMENT_3D('',#3776,#2996,#2997);
+#2733=AXIS2_PLACEMENT_3D('',#3780,#2999,#3000);
+#2734=AXIS2_PLACEMENT_3D('',#3784,#3002,#3003);
+#2735=AXIS2_PLACEMENT_3D('',#3805,#3014,#3015);
+#2736=AXIS2_PLACEMENT_3D('',#3807,#3016,#3017);
+#2737=AXIS2_PLACEMENT_3D('',#3809,#3018,#3019);
+#2738=AXIS2_PLACEMENT_3D('',#3811,#3020,#3021);
+#2739=AXIS2_PLACEMENT_3D('',#3812,#3022,#3023);
+#2740=AXIS2_PLACEMENT_3D('',#3816,#3026,#3027);
+#2741=AXIS2_PLACEMENT_3D('',#3818,#3028,#3029);
+#2742=AXIS2_PLACEMENT_3D('',#3820,#3031,#3032);
+#2743=AXIS2_PLACEMENT_3D('',#3824,#3034,#3035);
+#2744=AXIS2_PLACEMENT_3D('',#3826,#3037,#3038);
+#2745=AXIS2_PLACEMENT_3D('',#3830,#3041,#3042);
+#2746=AXIS2_PLACEMENT_3D('',#3832,#3043,#3044);
+#2747=AXIS2_PLACEMENT_3D('',#3834,#3046,#3047);
+#2748=AXIS2_PLACEMENT_3D('',#3841,#3052,#3053);
+#2749=AXIS2_PLACEMENT_3D('',#3845,#3056,#3057);
+#2750=AXIS2_PLACEMENT_3D('',#3849,#3060,#3061);
+#2751=AXIS2_PLACEMENT_3D('',#3851,#3063,#3064);
+#2752=AXIS2_PLACEMENT_3D('',#3855,#3067,#3068);
+#2753=AXIS2_PLACEMENT_3D('',#3857,#3070,#3071);
+#2754=AXIS2_PLACEMENT_3D('',#3863,#3075,#3076);
+#2755=AXIS2_PLACEMENT_3D('',#3867,#3079,#3080);
+#2756=AXIS2_PLACEMENT_3D('',#3871,#3083,#3084);
+#2757=AXIS2_PLACEMENT_3D('',#3873,#3086,#3087);
+#2758=AXIS2_PLACEMENT_3D('',#3876,#3089,#3090);
+#2759=AXIS2_PLACEMENT_3D('',#3877,#3091,#3092);
+#2760=AXIS2_PLACEMENT_3D('',#3880,#3094,#3095);
+#2761=AXIS2_PLACEMENT_3D('',#3881,#3096,#3097);
+#2762=AXIS2_PLACEMENT_3D('',#3884,#3099,#3100);
+#2763=AXIS2_PLACEMENT_3D('',#3885,#3101,#3102);
+#2764=AXIS2_PLACEMENT_3D('',#3888,#3104,#3105);
+#2765=AXIS2_PLACEMENT_3D('',#3889,#3106,#3107);
+#2766=AXIS2_PLACEMENT_3D('',#3890,#3108,#3109);
+#2767=AXIS2_PLACEMENT_3D('',#3891,#3110,#3111);
+#2768=AXIS2_PLACEMENT_3D('',#3894,#3112,#3113);
+#2769=AXIS2_PLACEMENT_3D('',#3898,#3115,#3116);
+#2770=AXIS2_PLACEMENT_3D('',#3900,#3118,#3119);
+#2771=AXIS2_PLACEMENT_3D('',#3906,#3123,#3124);
+#2772=AXIS2_PLACEMENT_3D('',#3910,#3126,#3127);
+#2773=AXIS2_PLACEMENT_3D('',#3914,#3129,#3130);
+#2774=AXIS2_PLACEMENT_3D('',#3918,#3132,#3133);
+#2775=AXIS2_PLACEMENT_3D('',#3938,#3143,#3144);
+#2776=AXIS2_PLACEMENT_3D('',#3942,#3146,#3147);
+#2777=AXIS2_PLACEMENT_3D('',#3946,#3149,#3150);
+#2778=AXIS2_PLACEMENT_3D('',#3949,#3152,#3153);
+#2779=AXIS2_PLACEMENT_3D('',#3954,#3155,#3156);
+#2780=AXIS2_PLACEMENT_3D('',#3958,#3158,#3159);
+#2781=AXIS2_PLACEMENT_3D('',#3962,#3161,#3162);
+#2782=AXIS2_PLACEMENT_3D('',#3965,#3164,#3165);
+#2783=AXIS2_PLACEMENT_3D('',#3970,#3167,#3168);
+#2784=AXIS2_PLACEMENT_3D('',#3974,#3170,#3171);
+#2785=AXIS2_PLACEMENT_3D('',#3978,#3173,#3174);
+#2786=AXIS2_PLACEMENT_3D('',#3981,#3176,#3177);
+#2787=AXIS2_PLACEMENT_3D('',#3986,#3179,#3180);
+#2788=AXIS2_PLACEMENT_3D('',#3990,#3182,#3183);
+#2789=AXIS2_PLACEMENT_3D('',#3994,#3185,#3186);
+#2790=AXIS2_PLACEMENT_3D('',#3997,#3188,#3189);
+#2791=AXIS2_PLACEMENT_3D('',#4002,#3191,#3192);
+#2792=AXIS2_PLACEMENT_3D('',#4006,#3194,#3195);
+#2793=AXIS2_PLACEMENT_3D('',#4010,#3197,#3198);
+#2794=AXIS2_PLACEMENT_3D('',#4013,#3200,#3201);
+#2795=AXIS2_PLACEMENT_3D('',#4018,#3203,#3204);
+#2796=AXIS2_PLACEMENT_3D('',#4022,#3206,#3207);
+#2797=AXIS2_PLACEMENT_3D('',#4026,#3209,#3210);
+#2798=AXIS2_PLACEMENT_3D('',#4029,#3212,#3213);
+#2799=AXIS2_PLACEMENT_3D('',#4034,#3215,#3216);
+#2800=AXIS2_PLACEMENT_3D('',#4038,#3218,#3219);
+#2801=AXIS2_PLACEMENT_3D('',#4042,#3221,#3222);
+#2802=AXIS2_PLACEMENT_3D('',#4045,#3224,#3225);
+#2803=AXIS2_PLACEMENT_3D('',#4050,#3227,#3228);
+#2804=AXIS2_PLACEMENT_3D('',#4054,#3230,#3231);
+#2805=AXIS2_PLACEMENT_3D('',#4058,#3233,#3234);
+#2806=AXIS2_PLACEMENT_3D('',#4061,#3236,#3237);
+#2807=AXIS2_PLACEMENT_3D('',#4066,#3239,#3240);
+#2808=AXIS2_PLACEMENT_3D('',#4070,#3242,#3243);
+#2809=AXIS2_PLACEMENT_3D('',#4074,#3245,#3246);
+#2810=AXIS2_PLACEMENT_3D('',#4077,#3248,#3249);
+#2811=AXIS2_PLACEMENT_3D('',#4079,#3250,#3251);
+#2812=AXIS2_PLACEMENT_3D('',#4081,#3252,#3253);
+#2813=AXIS2_PLACEMENT_3D('',#4083,#3254,#3255);
+#2814=AXIS2_PLACEMENT_3D('',#4085,#3256,#3257);
+#2815=AXIS2_PLACEMENT_3D('',#4086,#3258,#3259);
+#2816=AXIS2_PLACEMENT_3D('',#4089,#3260,#3261);
+#2817=AXIS2_PLACEMENT_3D('',#4092,#3264,#3265);
+#2818=AXIS2_PLACEMENT_3D('',#4096,#3268,#3269);
+#2819=AXIS2_PLACEMENT_3D('',#4098,#3270,#3271);
+#2820=AXIS2_PLACEMENT_3D('',#4100,#3273,#3274);
+#2821=AXIS2_PLACEMENT_3D('',#4103,#3275,#3276);
+#2822=AXIS2_PLACEMENT_3D('',#4106,#3279,#3280);
+#2823=AXIS2_PLACEMENT_3D('',#4110,#3283,#3284);
+#2824=AXIS2_PLACEMENT_3D('',#4112,#3285,#3286);
+#2825=AXIS2_PLACEMENT_3D('',#4114,#3288,#3289);
+#2826=AXIS2_PLACEMENT_3D('',#4116,#3290,#3291);
+#2827=AXIS2_PLACEMENT_3D('',#4118,#3293,#3294);
+#2828=AXIS2_PLACEMENT_3D('',#4120,#3295,#3296);
+#2829=AXIS2_PLACEMENT_3D('',#4122,#3298,#3299);
+#2830=AXIS2_PLACEMENT_3D('',#4124,#3300,#3301);
+#2831=AXIS2_PLACEMENT_3D('',#4126,#3303,#3304);
+#2832=AXIS2_PLACEMENT_3D('',#4130,#3306,#3307);
+#2833=AXIS2_PLACEMENT_3D('',#4132,#3309,#3310);
+#2834=AXIS2_PLACEMENT_3D('',#4136,#3313,#3314);
+#2835=AXIS2_PLACEMENT_3D('',#4138,#3315,#3316);
+#2836=AXIS2_PLACEMENT_3D('',#4140,#3318,#3319);
+#2837=AXIS2_PLACEMENT_3D('',#4144,#3322,#3323);
+#2838=AXIS2_PLACEMENT_3D('',#4146,#3324,#3325);
+#2839=AXIS2_PLACEMENT_3D('',#4148,#3327,#3328);
+#2840=AXIS2_PLACEMENT_3D('',#4152,#3331,#3332);
+#2841=AXIS2_PLACEMENT_3D('',#4154,#3333,#3334);
+#2842=AXIS2_PLACEMENT_3D('',#4156,#3336,#3337);
+#2843=AXIS2_PLACEMENT_3D('',#4158,#3339,#3340);
+#2844=AXIS2_PLACEMENT_3D('',#4162,#3342,#3343);
+#2845=AXIS2_PLACEMENT_3D('',#4164,#3345,#3346);
+#2846=AXIS2_PLACEMENT_3D('',#4168,#3349,#3350);
+#2847=AXIS2_PLACEMENT_3D('',#4170,#3351,#3352);
+#2848=AXIS2_PLACEMENT_3D('',#4172,#3354,#3355);
+#2849=AXIS2_PLACEMENT_3D('',#4176,#3358,#3359);
+#2850=AXIS2_PLACEMENT_3D('',#4178,#3360,#3361);
+#2851=AXIS2_PLACEMENT_3D('',#4180,#3363,#3364);
+#2852=AXIS2_PLACEMENT_3D('',#4184,#3367,#3368);
+#2853=AXIS2_PLACEMENT_3D('',#4186,#3369,#3370);
+#2854=AXIS2_PLACEMENT_3D('',#4188,#3372,#3373);
+#2855=AXIS2_PLACEMENT_3D('',#4190,#3375,#3376);
+#2856=AXIS2_PLACEMENT_3D('',#4194,#3378,#3379);
+#2857=AXIS2_PLACEMENT_3D('',#4196,#3381,#3382);
+#2858=AXIS2_PLACEMENT_3D('',#4200,#3385,#3386);
+#2859=AXIS2_PLACEMENT_3D('',#4202,#3387,#3388);
+#2860=AXIS2_PLACEMENT_3D('',#4204,#3390,#3391);
+#2861=AXIS2_PLACEMENT_3D('',#4208,#3394,#3395);
+#2862=AXIS2_PLACEMENT_3D('',#4210,#3396,#3397);
+#2863=AXIS2_PLACEMENT_3D('',#4212,#3399,#3400);
+#2864=AXIS2_PLACEMENT_3D('',#4216,#3403,#3404);
+#2865=AXIS2_PLACEMENT_3D('',#4218,#3405,#3406);
+#2866=AXIS2_PLACEMENT_3D('',#4220,#3408,#3409);
+#2867=AXIS2_PLACEMENT_3D('',#4222,#3411,#3412);
+#2868=AXIS2_PLACEMENT_3D('',#4226,#3414,#3415);
+#2869=AXIS2_PLACEMENT_3D('',#4228,#3417,#3418);
+#2870=AXIS2_PLACEMENT_3D('',#4232,#3421,#3422);
+#2871=AXIS2_PLACEMENT_3D('',#4234,#3423,#3424);
+#2872=AXIS2_PLACEMENT_3D('',#4236,#3426,#3427);
+#2873=AXIS2_PLACEMENT_3D('',#4240,#3430,#3431);
+#2874=AXIS2_PLACEMENT_3D('',#4242,#3432,#3433);
+#2875=AXIS2_PLACEMENT_3D('',#4244,#3435,#3436);
+#2876=AXIS2_PLACEMENT_3D('',#4248,#3439,#3440);
+#2877=AXIS2_PLACEMENT_3D('',#4250,#3441,#3442);
+#2878=AXIS2_PLACEMENT_3D('',#4252,#3444,#3445);
+#2879=AXIS2_PLACEMENT_3D('',#4254,#3447,#3448);
+#2880=AXIS2_PLACEMENT_3D('',#4258,#3450,#3451);
+#2881=AXIS2_PLACEMENT_3D('',#4260,#3453,#3454);
+#2882=AXIS2_PLACEMENT_3D('',#4264,#3457,#3458);
+#2883=AXIS2_PLACEMENT_3D('',#4266,#3459,#3460);
+#2884=AXIS2_PLACEMENT_3D('',#4268,#3462,#3463);
+#2885=AXIS2_PLACEMENT_3D('',#4272,#3466,#3467);
+#2886=AXIS2_PLACEMENT_3D('',#4274,#3468,#3469);
+#2887=AXIS2_PLACEMENT_3D('',#4276,#3471,#3472);
+#2888=AXIS2_PLACEMENT_3D('',#4280,#3475,#3476);
+#2889=AXIS2_PLACEMENT_3D('',#4282,#3477,#3478);
+#2890=AXIS2_PLACEMENT_3D('',#4284,#3480,#3481);
+#2891=AXIS2_PLACEMENT_3D('',#4286,#3483,#3484);
+#2892=AXIS2_PLACEMENT_3D('',#4290,#3486,#3487);
+#2893=AXIS2_PLACEMENT_3D('',#4292,#3489,#3490);
+#2894=AXIS2_PLACEMENT_3D('',#4296,#3493,#3494);
+#2895=AXIS2_PLACEMENT_3D('',#4298,#3495,#3496);
+#2896=AXIS2_PLACEMENT_3D('',#4300,#3498,#3499);
+#2897=AXIS2_PLACEMENT_3D('',#4304,#3502,#3503);
+#2898=AXIS2_PLACEMENT_3D('',#4306,#3504,#3505);
+#2899=AXIS2_PLACEMENT_3D('',#4308,#3507,#3508);
+#2900=AXIS2_PLACEMENT_3D('',#4312,#3511,#3512);
+#2901=AXIS2_PLACEMENT_3D('',#4314,#3513,#3514);
+#2902=AXIS2_PLACEMENT_3D('',#4316,#3516,#3517);
+#2903=AXIS2_PLACEMENT_3D('',#4318,#3519,#3520);
+#2904=AXIS2_PLACEMENT_3D('',#4322,#3522,#3523);
+#2905=AXIS2_PLACEMENT_3D('',#4324,#3525,#3526);
+#2906=AXIS2_PLACEMENT_3D('',#4328,#3529,#3530);
+#2907=AXIS2_PLACEMENT_3D('',#4330,#3531,#3532);
+#2908=AXIS2_PLACEMENT_3D('',#4332,#3534,#3535);
+#2909=AXIS2_PLACEMENT_3D('',#4336,#3538,#3539);
+#2910=AXIS2_PLACEMENT_3D('',#4338,#3540,#3541);
+#2911=AXIS2_PLACEMENT_3D('',#4340,#3543,#3544);
+#2912=AXIS2_PLACEMENT_3D('',#4344,#3547,#3548);
+#2913=AXIS2_PLACEMENT_3D('',#4346,#3549,#3550);
+#2914=AXIS2_PLACEMENT_3D('',#4348,#3552,#3553);
+#2915=AXIS2_PLACEMENT_3D('',#4350,#3555,#3556);
+#2916=AXIS2_PLACEMENT_3D('',#4354,#3558,#3559);
+#2917=AXIS2_PLACEMENT_3D('',#4356,#3561,#3562);
+#2918=AXIS2_PLACEMENT_3D('',#4360,#3565,#3566);
+#2919=AXIS2_PLACEMENT_3D('',#4362,#3567,#3568);
+#2920=AXIS2_PLACEMENT_3D('',#4364,#3570,#3571);
+#2921=AXIS2_PLACEMENT_3D('',#4368,#3574,#3575);
+#2922=AXIS2_PLACEMENT_3D('',#4370,#3576,#3577);
+#2923=AXIS2_PLACEMENT_3D('',#4372,#3579,#3580);
+#2924=AXIS2_PLACEMENT_3D('',#4376,#3583,#3584);
+#2925=AXIS2_PLACEMENT_3D('',#4378,#3585,#3586);
+#2926=AXIS2_PLACEMENT_3D('',#4380,#3588,#3589);
+#2927=AXIS2_PLACEMENT_3D('',#4382,#3591,#3592);
+#2928=AXIS2_PLACEMENT_3D('',#4386,#3594,#3595);
+#2929=AXIS2_PLACEMENT_3D('',#4388,#3597,#3598);
+#2930=AXIS2_PLACEMENT_3D('',#4392,#3601,#3602);
+#2931=AXIS2_PLACEMENT_3D('',#4394,#3603,#3604);
+#2932=AXIS2_PLACEMENT_3D('',#4396,#3606,#3607);
+#2933=AXIS2_PLACEMENT_3D('',#4400,#3610,#3611);
+#2934=AXIS2_PLACEMENT_3D('',#4402,#3612,#3613);
+#2935=AXIS2_PLACEMENT_3D('',#4404,#3615,#3616);
+#2936=AXIS2_PLACEMENT_3D('',#4408,#3619,#3620);
+#2937=AXIS2_PLACEMENT_3D('',#4410,#3621,#3622);
+#2938=AXIS2_PLACEMENT_3D('',#4412,#3624,#3625);
+#2939=AXIS2_PLACEMENT_3D('',#4414,#3627,#3628);
+#2940=AXIS2_PLACEMENT_3D('',#4420,#3632,#3633);
+#2941=AXIS2_PLACEMENT_3D('',#4424,#3636,#3637);
+#2942=AXIS2_PLACEMENT_3D('',#4428,#3640,#3641);
+#2943=AXIS2_PLACEMENT_3D('',#4430,#3643,#3644);
+#2944=AXIS2_PLACEMENT_3D('',#4436,#3648,#3649);
+#2945=AXIS2_PLACEMENT_3D('',#4438,#3651,#3652);
+#2946=AXIS2_PLACEMENT_3D('',#4440,#3654,#3655);
+#2947=AXIS2_PLACEMENT_3D('',#4442,#3657,#3658);
+#2948=AXIS2_PLACEMENT_3D('',#4444,#3660,#3661);
+#2949=AXIS2_PLACEMENT_3D('',#4445,#3662,#3663);
+#2950=AXIS2_PLACEMENT_3D('',#4448,#3664,#3665);
+#2951=AXIS2_PLACEMENT_3D('',#4452,#3667,#3668);
+#2952=AXIS2_PLACEMENT_3D('',#4454,#3670,#3671);
+#2953=AXIS2_PLACEMENT_3D('',#4460,#3675,#3676);
+#2954=AXIS2_PLACEMENT_3D('',#4464,#3678,#3679);
+#2955=AXIS2_PLACEMENT_3D('',#4468,#3681,#3682);
+#2956=AXIS2_PLACEMENT_3D('',#4471,#3684,#3685);
+#2957=AXIS2_PLACEMENT_3D('',#4473,#3686,#3687);
+#2958=AXIS2_PLACEMENT_3D('',#4483,#3692,#3693);
+#2959=AXIS2_PLACEMENT_3D('',#4485,#3694,#3695);
+#2960=AXIS2_PLACEMENT_3D('',#4487,#3696,#3697);
+#2961=AXIS2_PLACEMENT_3D('',#4488,#3698,#3699);
+#2962=AXIS2_PLACEMENT_3D('',#4490,#3700,#3701);
+#2963=AXIS2_PLACEMENT_3D('',#4492,#3703,#3704);
+#2964=AXIS2_PLACEMENT_3D('',#4496,#3707,#3708);
+#2965=AXIS2_PLACEMENT_3D('',#4498,#3709,#3710);
+#2966=AXIS2_PLACEMENT_3D('',#4500,#3712,#3713);
+#2967=AXIS2_PLACEMENT_3D('',#4504,#3716,#3717);
+#2968=AXIS2_PLACEMENT_3D('',#4506,#3718,#3719);
+#2969=AXIS2_PLACEMENT_3D('',#4508,#3721,#3722);
+#2970=AXIS2_PLACEMENT_3D('',#4510,#3723,#3724);
+#2971=AXIS2_PLACEMENT_3D('',#4512,#3726,#3727);
+#2972=AXIS2_PLACEMENT_3D('',#4514,#3728,#3729);
+#2973=AXIS2_PLACEMENT_3D('',#4516,#3731,#3732);
+#2974=AXIS2_PLACEMENT_3D('',#4518,#3733,#3734);
+#2975=AXIS2_PLACEMENT_3D('',#4520,#3736,#3737);
+#2976=AXIS2_PLACEMENT_3D('',#4526,#3741,#3742);
+#2977=AXIS2_PLACEMENT_3D('',#4530,#3745,#3746);
+#2978=AXIS2_PLACEMENT_3D('',#4534,#3749,#3750);
+#2979=AXIS2_PLACEMENT_3D('',#4536,#3752,#3753);
+#2980=AXIS2_PLACEMENT_3D('',#4538,#3754,#3755);
+#2981=AXIS2_PLACEMENT_3D('',#4540,#3757,#3758);
+#2982=AXIS2_PLACEMENT_3D('',#4542,#3760,#3761);
+#2983=DIRECTION('axis',(0.,0.,1.));
+#2984=DIRECTION('refdir',(1.,0.,0.));
+#2985=DIRECTION('center_axis',(0.,0.,1.));
+#2986=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#2987=DIRECTION('center_axis',(0.,0.,-1.));
+#2988=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#2989=DIRECTION('',(0.,0.,-1.));
+#2990=DIRECTION('center_axis',(0.,0.,1.));
+#2991=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#2992=DIRECTION('',(0.,0.,1.));
+#2993=DIRECTION('center_axis',(0.,0.,1.));
+#2994=DIRECTION('ref_axis',(1.,0.,0.));
+#2995=DIRECTION('',(0.,1.,0.));
+#2996=DIRECTION('center_axis',(0.,0.,-1.));
+#2997=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#2998=DIRECTION('',(-1.,-4.8472887907141E-17,0.));
+#2999=DIRECTION('center_axis',(0.,0.,-1.));
+#3000=DIRECTION('ref_axis',(0.707106781186548,-0.707106781186547,0.));
+#3001=DIRECTION('',(0.,-1.,0.));
+#3002=DIRECTION('center_axis',(0.,0.,-1.));
+#3003=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3004=DIRECTION('',(1.,0.,0.));
+#3005=DIRECTION('',(0.00211883867751913,0.99999775525881,0.));
+#3006=DIRECTION('',(0.99999775525881,-0.00211883867752468,0.));
+#3007=DIRECTION('',(1.,0.,0.));
+#3008=DIRECTION('',(0.,-1.,0.));
+#3009=DIRECTION('',(-1.,-2.89337761429314E-33,0.));
+#3010=DIRECTION('',(1.72904223214608E-33,1.,0.));
+#3011=DIRECTION('',(1.,0.,0.));
+#3012=DIRECTION('',(-0.00211883867752538,-0.99999775525881,0.));
+#3013=DIRECTION('',(1.,0.,0.));
+#3014=DIRECTION('center_axis',(0.,0.,1.));
+#3015=DIRECTION('ref_axis',(1.,0.,0.));
+#3016=DIRECTION('center_axis',(0.,0.,1.));
+#3017=DIRECTION('ref_axis',(1.,0.,0.));
+#3018=DIRECTION('center_axis',(0.,0.,1.));
+#3019=DIRECTION('ref_axis',(1.,0.,0.));
+#3020=DIRECTION('center_axis',(0.,0.,1.));
+#3021=DIRECTION('ref_axis',(1.,0.,0.));
+#3022=DIRECTION('center_axis',(-1.,0.,0.));
+#3023=DIRECTION('ref_axis',(0.,-1.,0.));
+#3024=DIRECTION('',(0.,-1.,0.));
+#3025=DIRECTION('',(0.,0.,-1.));
+#3026=DIRECTION('center_axis',(0.,0.,1.));
+#3027=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#3028=DIRECTION('center_axis',(0.,0.,1.));
+#3029=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#3030=DIRECTION('',(0.,0.,1.));
+#3031=DIRECTION('center_axis',(0.,0.,1.));
+#3032=DIRECTION('ref_axis',(0.707106781186548,-0.707106781186547,0.));
+#3033=DIRECTION('',(0.,0.,-1.));
+#3034=DIRECTION('center_axis',(0.,0.,1.));
+#3035=DIRECTION('ref_axis',(0.707106781186548,-0.707106781186547,0.));
+#3036=DIRECTION('',(0.,0.,1.));
+#3037=DIRECTION('center_axis',(1.,0.,0.));
+#3038=DIRECTION('ref_axis',(0.,1.,0.));
+#3039=DIRECTION('',(0.,1.,0.));
+#3040=DIRECTION('',(0.,0.,-1.));
+#3041=DIRECTION('center_axis',(0.,0.,1.));
+#3042=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3043=DIRECTION('center_axis',(0.,0.,1.));
+#3044=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3045=DIRECTION('',(0.,0.,1.));
+#3046=DIRECTION('center_axis',(0.,1.,0.));
+#3047=DIRECTION('ref_axis',(-1.,0.,0.));
+#3048=DIRECTION('',(0.,0.,-1.));
+#3049=DIRECTION('',(-1.,0.,0.));
+#3050=DIRECTION('',(0.,0.,-1.));
+#3051=DIRECTION('',(-1.,0.,0.));
+#3052=DIRECTION('center_axis',(-0.99999775525881,0.00211883867752538,0.));
+#3053=DIRECTION('ref_axis',(0.00211883867752538,0.99999775525881,0.));
+#3054=DIRECTION('',(0.,0.,1.));
+#3055=DIRECTION('',(0.00211883867752538,0.99999775525881,0.));
+#3056=DIRECTION('center_axis',(-0.99999775525881,0.00211883867751913,0.));
+#3057=DIRECTION('ref_axis',(0.,0.,1.));
+#3058=DIRECTION('',(0.00211883867752468,0.99999775525881,0.));
+#3059=DIRECTION('',(0.,0.,1.));
+#3060=DIRECTION('center_axis',(4.8472887907141E-17,-1.,0.));
+#3061=DIRECTION('ref_axis',(1.,4.8472887907141E-17,0.));
+#3062=DIRECTION('',(1.,4.8472887907141E-17,0.));
+#3063=DIRECTION('center_axis',(-0.00211883867752468,-0.99999775525881,0.));
+#3064=DIRECTION('ref_axis',(0.,0.,1.));
+#3065=DIRECTION('',(0.,0.,-1.));
+#3066=DIRECTION('',(-0.99999775525881,0.00211883867752468,0.));
+#3067=DIRECTION('center_axis',(0.,0.,-1.));
+#3068=DIRECTION('ref_axis',(-1.,0.,0.));
+#3069=DIRECTION('',(-1.,0.,0.));
+#3070=DIRECTION('center_axis',(-1.,0.,0.));
+#3071=DIRECTION('ref_axis',(0.,-1.,0.));
+#3072=DIRECTION('',(0.,1.,0.));
+#3073=DIRECTION('',(0.,0.,1.));
+#3074=DIRECTION('',(0.,0.,1.));
+#3075=DIRECTION('center_axis',(-2.89337761429314E-33,1.,0.));
+#3076=DIRECTION('ref_axis',(-1.,-2.89337761429314E-33,0.));
+#3077=DIRECTION('',(1.,2.89337761429314E-33,0.));
+#3078=DIRECTION('',(0.,0.,1.));
+#3079=DIRECTION('center_axis',(0.,-1.,0.));
+#3080=DIRECTION('ref_axis',(1.,0.,0.));
+#3081=DIRECTION('',(0.,0.,1.));
+#3082=DIRECTION('',(-1.,0.,0.));
+#3083=DIRECTION('center_axis',(1.,-1.72904223214608E-33,0.));
+#3084=DIRECTION('ref_axis',(1.72904223214608E-33,1.,0.));
+#3085=DIRECTION('',(-1.72904223214608E-33,-1.,0.));
+#3086=DIRECTION('center_axis',(0.,0.,1.));
+#3087=DIRECTION('ref_axis',(1.,0.,0.));
+#3088=DIRECTION('',(0.,0.,-1.));
+#3089=DIRECTION('center_axis',(0.,0.,-1.));
+#3090=DIRECTION('ref_axis',(1.,0.,0.));
+#3091=DIRECTION('center_axis',(0.,0.,1.));
+#3092=DIRECTION('ref_axis',(1.,0.,0.));
+#3093=DIRECTION('',(0.,0.,-1.));
+#3094=DIRECTION('center_axis',(0.,0.,-1.));
+#3095=DIRECTION('ref_axis',(1.,0.,0.));
+#3096=DIRECTION('center_axis',(0.,0.,1.));
+#3097=DIRECTION('ref_axis',(1.,0.,0.));
+#3098=DIRECTION('',(0.,0.,-1.));
+#3099=DIRECTION('center_axis',(0.,0.,-1.));
+#3100=DIRECTION('ref_axis',(1.,0.,0.));
+#3101=DIRECTION('center_axis',(0.,0.,1.));
+#3102=DIRECTION('ref_axis',(1.,0.,0.));
+#3103=DIRECTION('',(0.,0.,-1.));
+#3104=DIRECTION('center_axis',(0.,0.,-1.));
+#3105=DIRECTION('ref_axis',(1.,0.,0.));
+#3106=DIRECTION('center_axis',(0.,0.,1.));
+#3107=DIRECTION('ref_axis',(1.,0.,0.));
+#3108=DIRECTION('center_axis',(0.,0.,1.));
+#3109=DIRECTION('ref_axis',(1.,0.,0.));
+#3110=DIRECTION('center_axis',(0.,0.,-1.));
+#3111=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#3112=DIRECTION('center_axis',(0.,0.,1.));
+#3113=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#3114=DIRECTION('',(0.,0.,1.));
+#3115=DIRECTION('center_axis',(0.,0.,-1.));
+#3116=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#3117=DIRECTION('',(0.,0.,-1.));
+#3118=DIRECTION('center_axis',(0.,1.,0.));
+#3119=DIRECTION('ref_axis',(1.,0.,0.));
+#3120=DIRECTION('',(-1.,0.,0.));
+#3121=DIRECTION('',(0.,0.,-1.));
+#3122=DIRECTION('',(1.,0.,0.));
+#3123=DIRECTION('center_axis',(0.,0.,1.));
+#3124=DIRECTION('ref_axis',(1.,0.,0.));
+#3125=DIRECTION('',(0.,-1.,0.));
+#3126=DIRECTION('center_axis',(0.,0.,-1.));
+#3127=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
+#3128=DIRECTION('',(1.,4.8472887907141E-17,0.));
+#3129=DIRECTION('center_axis',(0.,0.,-1.));
+#3130=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#3131=DIRECTION('',(0.,1.,0.));
+#3132=DIRECTION('center_axis',(0.,0.,-1.));
+#3133=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3134=DIRECTION('',(-1.,0.,0.));
+#3135=DIRECTION('',(-0.00211883867751913,-0.99999775525881,0.));
+#3136=DIRECTION('',(-0.99999775525881,0.00211883867752521,0.));
+#3137=DIRECTION('',(0.00211883867752538,0.99999775525881,0.));
+#3138=DIRECTION('',(0.,-1.,0.));
+#3139=DIRECTION('',(-1.,0.,0.));
+#3140=DIRECTION('',(0.,1.,0.));
+#3141=DIRECTION('',(1.,0.,0.));
+#3142=DIRECTION('',(0.,-1.,0.));
+#3143=DIRECTION('center_axis',(0.,0.,-1.));
+#3144=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#3145=DIRECTION('',(-1.,0.,0.));
+#3146=DIRECTION('center_axis',(0.,0.,-1.));
+#3147=DIRECTION('ref_axis',(-1.,0.,0.));
+#3148=DIRECTION('',(0.,1.,0.));
+#3149=DIRECTION('center_axis',(0.,0.,-1.));
+#3150=DIRECTION('ref_axis',(0.,1.,0.));
+#3151=DIRECTION('',(1.,0.,0.));
+#3152=DIRECTION('center_axis',(0.,0.,-1.));
+#3153=DIRECTION('ref_axis',(1.,0.,0.));
+#3154=DIRECTION('',(0.,-1.,0.));
+#3155=DIRECTION('center_axis',(0.,0.,-1.));
+#3156=DIRECTION('ref_axis',(0.,-1.,0.));
+#3157=DIRECTION('',(-1.,0.,0.));
+#3158=DIRECTION('center_axis',(0.,0.,-1.));
+#3159=DIRECTION('ref_axis',(-1.,0.,0.));
+#3160=DIRECTION('',(0.,1.,0.));
+#3161=DIRECTION('center_axis',(0.,0.,-1.));
+#3162=DIRECTION('ref_axis',(0.,1.,0.));
+#3163=DIRECTION('',(1.,0.,0.));
+#3164=DIRECTION('center_axis',(0.,0.,-1.));
+#3165=DIRECTION('ref_axis',(1.,0.,0.));
+#3166=DIRECTION('',(0.,-1.,0.));
+#3167=DIRECTION('center_axis',(0.,0.,-1.));
+#3168=DIRECTION('ref_axis',(-8.88178419700128E-15,-1.,0.));
+#3169=DIRECTION('',(-1.,0.,0.));
+#3170=DIRECTION('center_axis',(0.,0.,-1.));
+#3171=DIRECTION('ref_axis',(-1.,0.,0.));
+#3172=DIRECTION('',(0.,1.,0.));
+#3173=DIRECTION('center_axis',(0.,0.,-1.));
+#3174=DIRECTION('ref_axis',(0.,1.,0.));
+#3175=DIRECTION('',(1.,0.,0.));
+#3176=DIRECTION('center_axis',(0.,0.,-1.));
+#3177=DIRECTION('ref_axis',(1.,0.,0.));
+#3178=DIRECTION('',(0.,-1.,0.));
+#3179=DIRECTION('center_axis',(0.,0.,-1.));
+#3180=DIRECTION('ref_axis',(0.,-1.,0.));
+#3181=DIRECTION('',(-1.,0.,0.));
+#3182=DIRECTION('center_axis',(0.,0.,-1.));
+#3183=DIRECTION('ref_axis',(-1.,0.,0.));
+#3184=DIRECTION('',(0.,1.,0.));
+#3185=DIRECTION('center_axis',(0.,0.,-1.));
+#3186=DIRECTION('ref_axis',(0.,1.,0.));
+#3187=DIRECTION('',(1.,0.,0.));
+#3188=DIRECTION('center_axis',(0.,0.,-1.));
+#3189=DIRECTION('ref_axis',(1.,0.,0.));
+#3190=DIRECTION('',(0.,-1.,0.));
+#3191=DIRECTION('center_axis',(0.,0.,-1.));
+#3192=DIRECTION('ref_axis',(3.55271367880048E-14,-1.,0.));
+#3193=DIRECTION('',(-1.,0.,0.));
+#3194=DIRECTION('center_axis',(0.,0.,-1.));
+#3195=DIRECTION('ref_axis',(-1.,0.,0.));
+#3196=DIRECTION('',(0.,1.,0.));
+#3197=DIRECTION('center_axis',(0.,0.,-1.));
+#3198=DIRECTION('ref_axis',(0.,1.,0.));
+#3199=DIRECTION('',(1.,0.,0.));
+#3200=DIRECTION('center_axis',(0.,0.,-1.));
+#3201=DIRECTION('ref_axis',(1.,0.,0.));
+#3202=DIRECTION('',(0.,-1.,0.));
+#3203=DIRECTION('center_axis',(0.,0.,-1.));
+#3204=DIRECTION('ref_axis',(0.,-1.,0.));
+#3205=DIRECTION('',(-1.,0.,0.));
+#3206=DIRECTION('center_axis',(0.,0.,-1.));
+#3207=DIRECTION('ref_axis',(-1.,0.,0.));
+#3208=DIRECTION('',(0.,1.,0.));
+#3209=DIRECTION('center_axis',(0.,0.,-1.));
+#3210=DIRECTION('ref_axis',(0.,1.,0.));
+#3211=DIRECTION('',(1.,0.,0.));
+#3212=DIRECTION('center_axis',(0.,0.,-1.));
+#3213=DIRECTION('ref_axis',(1.,0.,0.));
+#3214=DIRECTION('',(0.,-1.,0.));
+#3215=DIRECTION('center_axis',(0.,0.,-1.));
+#3216=DIRECTION('ref_axis',(0.,-1.,0.));
+#3217=DIRECTION('',(-1.,0.,0.));
+#3218=DIRECTION('center_axis',(0.,0.,-1.));
+#3219=DIRECTION('ref_axis',(-1.,0.,0.));
+#3220=DIRECTION('',(0.,1.,0.));
+#3221=DIRECTION('center_axis',(0.,0.,-1.));
+#3222=DIRECTION('ref_axis',(0.,1.,0.));
+#3223=DIRECTION('',(1.,0.,0.));
+#3224=DIRECTION('center_axis',(0.,0.,-1.));
+#3225=DIRECTION('ref_axis',(1.,0.,0.));
+#3226=DIRECTION('',(0.,-1.,0.));
+#3227=DIRECTION('center_axis',(0.,0.,-1.));
+#3228=DIRECTION('ref_axis',(-8.8817841970012E-15,-1.,0.));
+#3229=DIRECTION('',(-1.,0.,0.));
+#3230=DIRECTION('center_axis',(0.,0.,-1.));
+#3231=DIRECTION('ref_axis',(-1.,0.,0.));
+#3232=DIRECTION('',(0.,1.,0.));
+#3233=DIRECTION('center_axis',(0.,0.,-1.));
+#3234=DIRECTION('ref_axis',(0.,1.,0.));
+#3235=DIRECTION('',(1.,0.,0.));
+#3236=DIRECTION('center_axis',(0.,0.,-1.));
+#3237=DIRECTION('ref_axis',(1.,0.,0.));
+#3238=DIRECTION('',(0.,-1.,0.));
+#3239=DIRECTION('center_axis',(0.,0.,-1.));
+#3240=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#3241=DIRECTION('',(-1.,0.,0.));
+#3242=DIRECTION('center_axis',(0.,0.,-1.));
+#3243=DIRECTION('ref_axis',(-1.,0.,0.));
+#3244=DIRECTION('',(0.,1.,0.));
+#3245=DIRECTION('center_axis',(0.,0.,-1.));
+#3246=DIRECTION('ref_axis',(0.,1.,0.));
+#3247=DIRECTION('',(1.,0.,0.));
+#3248=DIRECTION('center_axis',(0.,0.,-1.));
+#3249=DIRECTION('ref_axis',(1.,0.,0.));
+#3250=DIRECTION('center_axis',(0.,0.,-1.));
+#3251=DIRECTION('ref_axis',(1.,0.,0.));
+#3252=DIRECTION('center_axis',(0.,0.,-1.));
+#3253=DIRECTION('ref_axis',(1.,0.,0.));
+#3254=DIRECTION('center_axis',(0.,0.,-1.));
+#3255=DIRECTION('ref_axis',(1.,0.,0.));
+#3256=DIRECTION('center_axis',(0.,0.,-1.));
+#3257=DIRECTION('ref_axis',(1.,0.,0.));
+#3258=DIRECTION('center_axis',(0.,0.,-1.));
+#3259=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
+#3260=DIRECTION('center_axis',(0.,0.,1.));
+#3261=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
+#3262=DIRECTION('',(0.,0.,1.));
+#3263=DIRECTION('',(0.,0.,-1.));
+#3264=DIRECTION('center_axis',(4.8472887907141E-17,-1.,0.));
+#3265=DIRECTION('ref_axis',(-1.,-4.8472887907141E-17,0.));
+#3266=DIRECTION('',(-1.,-4.8472887907141E-17,0.));
+#3267=DIRECTION('',(0.,0.,-1.));
+#3268=DIRECTION('center_axis',(0.,0.,-1.));
+#3269=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#3270=DIRECTION('center_axis',(0.,0.,1.));
+#3271=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#3272=DIRECTION('',(0.,0.,1.));
+#3273=DIRECTION('center_axis',(0.,0.,-1.));
+#3274=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3275=DIRECTION('center_axis',(0.,0.,1.));
+#3276=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3277=DIRECTION('',(0.,0.,1.));
+#3278=DIRECTION('',(0.,0.,-1.));
+#3279=DIRECTION('center_axis',(0.,1.,0.));
+#3280=DIRECTION('ref_axis',(1.,0.,0.));
+#3281=DIRECTION('',(1.,0.,0.));
+#3282=DIRECTION('',(0.,0.,-1.));
+#3283=DIRECTION('center_axis',(0.,0.,-1.));
+#3284=DIRECTION('ref_axis',(1.,0.,0.));
+#3285=DIRECTION('center_axis',(0.,0.,1.));
+#3286=DIRECTION('ref_axis',(1.,0.,0.));
+#3287=DIRECTION('',(0.,0.,1.));
+#3288=DIRECTION('center_axis',(0.,0.,-1.));
+#3289=DIRECTION('ref_axis',(1.,0.,0.));
+#3290=DIRECTION('center_axis',(0.,0.,1.));
+#3291=DIRECTION('ref_axis',(1.,0.,0.));
+#3292=DIRECTION('',(0.,0.,1.));
+#3293=DIRECTION('center_axis',(0.,0.,-1.));
+#3294=DIRECTION('ref_axis',(1.,0.,0.));
+#3295=DIRECTION('center_axis',(0.,0.,1.));
+#3296=DIRECTION('ref_axis',(1.,0.,0.));
+#3297=DIRECTION('',(0.,0.,1.));
+#3298=DIRECTION('center_axis',(0.,0.,-1.));
+#3299=DIRECTION('ref_axis',(1.,0.,0.));
+#3300=DIRECTION('center_axis',(0.,0.,1.));
+#3301=DIRECTION('ref_axis',(1.,0.,0.));
+#3302=DIRECTION('',(0.,0.,1.));
+#3303=DIRECTION('center_axis',(0.,0.,-1.));
+#3304=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#3305=DIRECTION('',(0.,0.,-1.));
+#3306=DIRECTION('center_axis',(0.,0.,1.));
+#3307=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#3308=DIRECTION('',(0.,0.,-1.));
+#3309=DIRECTION('center_axis',(0.,1.,0.));
+#3310=DIRECTION('ref_axis',(1.,0.,0.));
+#3311=DIRECTION('',(1.,0.,0.));
+#3312=DIRECTION('',(0.,0.,-1.));
+#3313=DIRECTION('center_axis',(0.,0.,-1.));
+#3314=DIRECTION('ref_axis',(-1.,0.,0.));
+#3315=DIRECTION('center_axis',(0.,0.,1.));
+#3316=DIRECTION('ref_axis',(-1.,0.,0.));
+#3317=DIRECTION('',(0.,0.,-1.));
+#3318=DIRECTION('center_axis',(1.,0.,0.));
+#3319=DIRECTION('ref_axis',(0.,-1.,0.));
+#3320=DIRECTION('',(0.,-1.,0.));
+#3321=DIRECTION('',(0.,0.,-1.));
+#3322=DIRECTION('center_axis',(0.,0.,-1.));
+#3323=DIRECTION('ref_axis',(0.,1.,0.));
+#3324=DIRECTION('center_axis',(0.,0.,1.));
+#3325=DIRECTION('ref_axis',(0.,1.,0.));
+#3326=DIRECTION('',(0.,0.,-1.));
+#3327=DIRECTION('center_axis',(0.,-1.,0.));
+#3328=DIRECTION('ref_axis',(-1.,0.,0.));
+#3329=DIRECTION('',(-1.,0.,0.));
+#3330=DIRECTION('',(0.,0.,-1.));
+#3331=DIRECTION('center_axis',(0.,0.,-1.));
+#3332=DIRECTION('ref_axis',(1.,0.,0.));
+#3333=DIRECTION('center_axis',(0.,0.,1.));
+#3334=DIRECTION('ref_axis',(1.,0.,0.));
+#3335=DIRECTION('',(0.,0.,-1.));
+#3336=DIRECTION('center_axis',(-1.,0.,0.));
+#3337=DIRECTION('ref_axis',(0.,1.,0.));
+#3338=DIRECTION('',(0.,1.,0.));
+#3339=DIRECTION('center_axis',(0.,0.,-1.));
+#3340=DIRECTION('ref_axis',(-8.8817841970012E-15,-1.,0.));
+#3341=DIRECTION('',(0.,0.,-1.));
+#3342=DIRECTION('center_axis',(0.,0.,1.));
+#3343=DIRECTION('ref_axis',(-8.8817841970012E-15,-1.,0.));
+#3344=DIRECTION('',(0.,0.,-1.));
+#3345=DIRECTION('center_axis',(0.,1.,0.));
+#3346=DIRECTION('ref_axis',(1.,0.,0.));
+#3347=DIRECTION('',(1.,0.,0.));
+#3348=DIRECTION('',(0.,0.,-1.));
+#3349=DIRECTION('center_axis',(0.,0.,-1.));
+#3350=DIRECTION('ref_axis',(-1.,0.,0.));
+#3351=DIRECTION('center_axis',(0.,0.,1.));
+#3352=DIRECTION('ref_axis',(-1.,0.,0.));
+#3353=DIRECTION('',(0.,0.,-1.));
+#3354=DIRECTION('center_axis',(1.,0.,0.));
+#3355=DIRECTION('ref_axis',(0.,-1.,0.));
+#3356=DIRECTION('',(0.,-1.,0.));
+#3357=DIRECTION('',(0.,0.,-1.));
+#3358=DIRECTION('center_axis',(0.,0.,-1.));
+#3359=DIRECTION('ref_axis',(0.,1.,0.));
+#3360=DIRECTION('center_axis',(0.,0.,1.));
+#3361=DIRECTION('ref_axis',(0.,1.,0.));
+#3362=DIRECTION('',(0.,0.,-1.));
+#3363=DIRECTION('center_axis',(0.,-1.,0.));
+#3364=DIRECTION('ref_axis',(-1.,0.,0.));
+#3365=DIRECTION('',(-1.,0.,0.));
+#3366=DIRECTION('',(0.,0.,-1.));
+#3367=DIRECTION('center_axis',(0.,0.,-1.));
+#3368=DIRECTION('ref_axis',(1.,0.,0.));
+#3369=DIRECTION('center_axis',(0.,0.,1.));
+#3370=DIRECTION('ref_axis',(1.,0.,0.));
+#3371=DIRECTION('',(0.,0.,-1.));
+#3372=DIRECTION('center_axis',(-1.,0.,0.));
+#3373=DIRECTION('ref_axis',(0.,1.,0.));
+#3374=DIRECTION('',(0.,1.,0.));
+#3375=DIRECTION('center_axis',(0.,0.,-1.));
+#3376=DIRECTION('ref_axis',(0.,-1.,0.));
+#3377=DIRECTION('',(0.,0.,-1.));
+#3378=DIRECTION('center_axis',(0.,0.,1.));
+#3379=DIRECTION('ref_axis',(0.,-1.,0.));
+#3380=DIRECTION('',(0.,0.,-1.));
+#3381=DIRECTION('center_axis',(0.,1.,0.));
+#3382=DIRECTION('ref_axis',(1.,0.,0.));
+#3383=DIRECTION('',(1.,0.,0.));
+#3384=DIRECTION('',(0.,0.,-1.));
+#3385=DIRECTION('center_axis',(0.,0.,-1.));
+#3386=DIRECTION('ref_axis',(-1.,0.,0.));
+#3387=DIRECTION('center_axis',(0.,0.,1.));
+#3388=DIRECTION('ref_axis',(-1.,0.,0.));
+#3389=DIRECTION('',(0.,0.,-1.));
+#3390=DIRECTION('center_axis',(1.,0.,0.));
+#3391=DIRECTION('ref_axis',(0.,-1.,0.));
+#3392=DIRECTION('',(0.,-1.,0.));
+#3393=DIRECTION('',(0.,0.,-1.));
+#3394=DIRECTION('center_axis',(0.,0.,-1.));
+#3395=DIRECTION('ref_axis',(0.,1.,0.));
+#3396=DIRECTION('center_axis',(0.,0.,1.));
+#3397=DIRECTION('ref_axis',(0.,1.,0.));
+#3398=DIRECTION('',(0.,0.,-1.));
+#3399=DIRECTION('center_axis',(0.,-1.,0.));
+#3400=DIRECTION('ref_axis',(-1.,0.,0.));
+#3401=DIRECTION('',(-1.,0.,0.));
+#3402=DIRECTION('',(0.,0.,-1.));
+#3403=DIRECTION('center_axis',(0.,0.,-1.));
+#3404=DIRECTION('ref_axis',(1.,0.,0.));
+#3405=DIRECTION('center_axis',(0.,0.,1.));
+#3406=DIRECTION('ref_axis',(1.,0.,0.));
+#3407=DIRECTION('',(0.,0.,-1.));
+#3408=DIRECTION('center_axis',(-1.,0.,0.));
+#3409=DIRECTION('ref_axis',(0.,1.,0.));
+#3410=DIRECTION('',(0.,1.,0.));
+#3411=DIRECTION('center_axis',(0.,0.,-1.));
+#3412=DIRECTION('ref_axis',(0.,-1.,0.));
+#3413=DIRECTION('',(0.,0.,-1.));
+#3414=DIRECTION('center_axis',(0.,0.,1.));
+#3415=DIRECTION('ref_axis',(0.,-1.,0.));
+#3416=DIRECTION('',(0.,0.,-1.));
+#3417=DIRECTION('center_axis',(0.,1.,0.));
+#3418=DIRECTION('ref_axis',(1.,0.,0.));
+#3419=DIRECTION('',(1.,0.,0.));
+#3420=DIRECTION('',(0.,0.,-1.));
+#3421=DIRECTION('center_axis',(0.,0.,-1.));
+#3422=DIRECTION('ref_axis',(-1.,0.,0.));
+#3423=DIRECTION('center_axis',(0.,0.,1.));
+#3424=DIRECTION('ref_axis',(-1.,0.,0.));
+#3425=DIRECTION('',(0.,0.,-1.));
+#3426=DIRECTION('center_axis',(1.,0.,0.));
+#3427=DIRECTION('ref_axis',(0.,-1.,0.));
+#3428=DIRECTION('',(0.,-1.,0.));
+#3429=DIRECTION('',(0.,0.,-1.));
+#3430=DIRECTION('center_axis',(0.,0.,-1.));
+#3431=DIRECTION('ref_axis',(0.,1.,0.));
+#3432=DIRECTION('center_axis',(0.,0.,1.));
+#3433=DIRECTION('ref_axis',(0.,1.,0.));
+#3434=DIRECTION('',(0.,0.,-1.));
+#3435=DIRECTION('center_axis',(0.,-1.,0.));
+#3436=DIRECTION('ref_axis',(-1.,0.,0.));
+#3437=DIRECTION('',(-1.,0.,0.));
+#3438=DIRECTION('',(0.,0.,-1.));
+#3439=DIRECTION('center_axis',(0.,0.,-1.));
+#3440=DIRECTION('ref_axis',(1.,0.,0.));
+#3441=DIRECTION('center_axis',(0.,0.,1.));
+#3442=DIRECTION('ref_axis',(1.,0.,0.));
+#3443=DIRECTION('',(0.,0.,-1.));
+#3444=DIRECTION('center_axis',(-1.,0.,0.));
+#3445=DIRECTION('ref_axis',(0.,1.,0.));
+#3446=DIRECTION('',(0.,1.,0.));
+#3447=DIRECTION('center_axis',(0.,0.,-1.));
+#3448=DIRECTION('ref_axis',(3.55271367880048E-14,-1.,0.));
+#3449=DIRECTION('',(0.,0.,-1.));
+#3450=DIRECTION('center_axis',(0.,0.,1.));
+#3451=DIRECTION('ref_axis',(3.55271367880048E-14,-1.,0.));
+#3452=DIRECTION('',(0.,0.,-1.));
+#3453=DIRECTION('center_axis',(0.,1.,0.));
+#3454=DIRECTION('ref_axis',(1.,0.,0.));
+#3455=DIRECTION('',(1.,0.,0.));
+#3456=DIRECTION('',(0.,0.,-1.));
+#3457=DIRECTION('center_axis',(0.,0.,-1.));
+#3458=DIRECTION('ref_axis',(-1.,0.,0.));
+#3459=DIRECTION('center_axis',(0.,0.,1.));
+#3460=DIRECTION('ref_axis',(-1.,0.,0.));
+#3461=DIRECTION('',(0.,0.,-1.));
+#3462=DIRECTION('center_axis',(1.,0.,0.));
+#3463=DIRECTION('ref_axis',(0.,-1.,0.));
+#3464=DIRECTION('',(0.,-1.,0.));
+#3465=DIRECTION('',(0.,0.,-1.));
+#3466=DIRECTION('center_axis',(0.,0.,-1.));
+#3467=DIRECTION('ref_axis',(0.,1.,0.));
+#3468=DIRECTION('center_axis',(0.,0.,1.));
+#3469=DIRECTION('ref_axis',(0.,1.,0.));
+#3470=DIRECTION('',(0.,0.,-1.));
+#3471=DIRECTION('center_axis',(0.,-1.,0.));
+#3472=DIRECTION('ref_axis',(-1.,0.,0.));
+#3473=DIRECTION('',(-1.,0.,0.));
+#3474=DIRECTION('',(0.,0.,-1.));
+#3475=DIRECTION('center_axis',(0.,0.,-1.));
+#3476=DIRECTION('ref_axis',(1.,0.,0.));
+#3477=DIRECTION('center_axis',(0.,0.,1.));
+#3478=DIRECTION('ref_axis',(1.,0.,0.));
+#3479=DIRECTION('',(0.,0.,-1.));
+#3480=DIRECTION('center_axis',(-1.,0.,0.));
+#3481=DIRECTION('ref_axis',(0.,1.,0.));
+#3482=DIRECTION('',(0.,1.,0.));
+#3483=DIRECTION('center_axis',(0.,0.,-1.));
+#3484=DIRECTION('ref_axis',(0.,-1.,0.));
+#3485=DIRECTION('',(0.,0.,-1.));
+#3486=DIRECTION('center_axis',(0.,0.,1.));
+#3487=DIRECTION('ref_axis',(0.,-1.,0.));
+#3488=DIRECTION('',(0.,0.,-1.));
+#3489=DIRECTION('center_axis',(0.,1.,0.));
+#3490=DIRECTION('ref_axis',(1.,0.,0.));
+#3491=DIRECTION('',(1.,0.,0.));
+#3492=DIRECTION('',(0.,0.,-1.));
+#3493=DIRECTION('center_axis',(0.,0.,-1.));
+#3494=DIRECTION('ref_axis',(-1.,0.,0.));
+#3495=DIRECTION('center_axis',(0.,0.,1.));
+#3496=DIRECTION('ref_axis',(-1.,0.,0.));
+#3497=DIRECTION('',(0.,0.,-1.));
+#3498=DIRECTION('center_axis',(1.,0.,0.));
+#3499=DIRECTION('ref_axis',(0.,-1.,0.));
+#3500=DIRECTION('',(0.,-1.,0.));
+#3501=DIRECTION('',(0.,0.,-1.));
+#3502=DIRECTION('center_axis',(0.,0.,-1.));
+#3503=DIRECTION('ref_axis',(0.,1.,0.));
+#3504=DIRECTION('center_axis',(0.,0.,1.));
+#3505=DIRECTION('ref_axis',(0.,1.,0.));
+#3506=DIRECTION('',(0.,0.,-1.));
+#3507=DIRECTION('center_axis',(0.,-1.,0.));
+#3508=DIRECTION('ref_axis',(-1.,0.,0.));
+#3509=DIRECTION('',(-1.,0.,0.));
+#3510=DIRECTION('',(0.,0.,-1.));
+#3511=DIRECTION('center_axis',(0.,0.,-1.));
+#3512=DIRECTION('ref_axis',(1.,0.,0.));
+#3513=DIRECTION('center_axis',(0.,0.,1.));
+#3514=DIRECTION('ref_axis',(1.,0.,0.));
+#3515=DIRECTION('',(0.,0.,-1.));
+#3516=DIRECTION('center_axis',(-1.,0.,0.));
+#3517=DIRECTION('ref_axis',(0.,1.,0.));
+#3518=DIRECTION('',(0.,1.,0.));
+#3519=DIRECTION('center_axis',(0.,0.,-1.));
+#3520=DIRECTION('ref_axis',(-8.88178419700128E-15,-1.,0.));
+#3521=DIRECTION('',(0.,0.,-1.));
+#3522=DIRECTION('center_axis',(0.,0.,1.));
+#3523=DIRECTION('ref_axis',(-8.88178419700128E-15,-1.,0.));
+#3524=DIRECTION('',(0.,0.,-1.));
+#3525=DIRECTION('center_axis',(0.,1.,0.));
+#3526=DIRECTION('ref_axis',(1.,0.,0.));
+#3527=DIRECTION('',(1.,0.,0.));
+#3528=DIRECTION('',(0.,0.,-1.));
+#3529=DIRECTION('center_axis',(0.,0.,-1.));
+#3530=DIRECTION('ref_axis',(-1.,0.,0.));
+#3531=DIRECTION('center_axis',(0.,0.,1.));
+#3532=DIRECTION('ref_axis',(-1.,0.,0.));
+#3533=DIRECTION('',(0.,0.,-1.));
+#3534=DIRECTION('center_axis',(1.,0.,0.));
+#3535=DIRECTION('ref_axis',(0.,-1.,0.));
+#3536=DIRECTION('',(0.,-1.,0.));
+#3537=DIRECTION('',(0.,0.,-1.));
+#3538=DIRECTION('center_axis',(0.,0.,-1.));
+#3539=DIRECTION('ref_axis',(0.,1.,0.));
+#3540=DIRECTION('center_axis',(0.,0.,1.));
+#3541=DIRECTION('ref_axis',(0.,1.,0.));
+#3542=DIRECTION('',(0.,0.,-1.));
+#3543=DIRECTION('center_axis',(0.,-1.,0.));
+#3544=DIRECTION('ref_axis',(-1.,0.,0.));
+#3545=DIRECTION('',(-1.,0.,0.));
+#3546=DIRECTION('',(0.,0.,-1.));
+#3547=DIRECTION('center_axis',(0.,0.,-1.));
+#3548=DIRECTION('ref_axis',(1.,0.,0.));
+#3549=DIRECTION('center_axis',(0.,0.,1.));
+#3550=DIRECTION('ref_axis',(1.,0.,0.));
+#3551=DIRECTION('',(0.,0.,-1.));
+#3552=DIRECTION('center_axis',(-1.,0.,0.));
+#3553=DIRECTION('ref_axis',(0.,1.,0.));
+#3554=DIRECTION('',(0.,1.,0.));
+#3555=DIRECTION('center_axis',(0.,0.,-1.));
+#3556=DIRECTION('ref_axis',(0.,-1.,0.));
+#3557=DIRECTION('',(0.,0.,-1.));
+#3558=DIRECTION('center_axis',(0.,0.,1.));
+#3559=DIRECTION('ref_axis',(0.,-1.,0.));
+#3560=DIRECTION('',(0.,0.,-1.));
+#3561=DIRECTION('center_axis',(0.,1.,0.));
+#3562=DIRECTION('ref_axis',(1.,0.,0.));
+#3563=DIRECTION('',(1.,0.,0.));
+#3564=DIRECTION('',(0.,0.,-1.));
+#3565=DIRECTION('center_axis',(0.,0.,-1.));
+#3566=DIRECTION('ref_axis',(-1.,0.,0.));
+#3567=DIRECTION('center_axis',(0.,0.,1.));
+#3568=DIRECTION('ref_axis',(-1.,0.,0.));
+#3569=DIRECTION('',(0.,0.,-1.));
+#3570=DIRECTION('center_axis',(1.,0.,0.));
+#3571=DIRECTION('ref_axis',(0.,-1.,0.));
+#3572=DIRECTION('',(0.,-1.,0.));
+#3573=DIRECTION('',(0.,0.,-1.));
+#3574=DIRECTION('center_axis',(0.,0.,-1.));
+#3575=DIRECTION('ref_axis',(0.,1.,0.));
+#3576=DIRECTION('center_axis',(0.,0.,1.));
+#3577=DIRECTION('ref_axis',(0.,1.,0.));
+#3578=DIRECTION('',(0.,0.,-1.));
+#3579=DIRECTION('center_axis',(0.,-1.,0.));
+#3580=DIRECTION('ref_axis',(-1.,0.,0.));
+#3581=DIRECTION('',(-1.,0.,0.));
+#3582=DIRECTION('',(0.,0.,-1.));
+#3583=DIRECTION('center_axis',(0.,0.,-1.));
+#3584=DIRECTION('ref_axis',(1.,0.,0.));
+#3585=DIRECTION('center_axis',(0.,0.,1.));
+#3586=DIRECTION('ref_axis',(1.,0.,0.));
+#3587=DIRECTION('',(0.,0.,-1.));
+#3588=DIRECTION('center_axis',(-1.,0.,0.));
+#3589=DIRECTION('ref_axis',(0.,1.,0.));
+#3590=DIRECTION('',(0.,1.,0.));
+#3591=DIRECTION('center_axis',(0.,0.,-1.));
+#3592=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#3593=DIRECTION('',(0.,0.,-1.));
+#3594=DIRECTION('center_axis',(0.,0.,1.));
+#3595=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#3596=DIRECTION('',(0.,0.,-1.));
+#3597=DIRECTION('center_axis',(0.,1.,0.));
+#3598=DIRECTION('ref_axis',(1.,0.,0.));
+#3599=DIRECTION('',(1.,0.,0.));
+#3600=DIRECTION('',(0.,0.,-1.));
+#3601=DIRECTION('center_axis',(0.,0.,-1.));
+#3602=DIRECTION('ref_axis',(-1.,0.,0.));
+#3603=DIRECTION('center_axis',(0.,0.,1.));
+#3604=DIRECTION('ref_axis',(-1.,0.,0.));
+#3605=DIRECTION('',(0.,0.,-1.));
+#3606=DIRECTION('center_axis',(1.,0.,0.));
+#3607=DIRECTION('ref_axis',(0.,-1.,0.));
+#3608=DIRECTION('',(0.,-1.,0.));
+#3609=DIRECTION('',(0.,0.,-1.));
+#3610=DIRECTION('center_axis',(0.,0.,-1.));
+#3611=DIRECTION('ref_axis',(0.,1.,0.));
+#3612=DIRECTION('center_axis',(0.,0.,1.));
+#3613=DIRECTION('ref_axis',(0.,1.,0.));
+#3614=DIRECTION('',(0.,0.,-1.));
+#3615=DIRECTION('center_axis',(0.,-1.,0.));
+#3616=DIRECTION('ref_axis',(-1.,0.,0.));
+#3617=DIRECTION('',(-1.,0.,0.));
+#3618=DIRECTION('',(0.,0.,-1.));
+#3619=DIRECTION('center_axis',(0.,0.,-1.));
+#3620=DIRECTION('ref_axis',(1.,0.,0.));
+#3621=DIRECTION('center_axis',(0.,0.,1.));
+#3622=DIRECTION('ref_axis',(1.,0.,0.));
+#3623=DIRECTION('',(0.,0.,-1.));
+#3624=DIRECTION('center_axis',(-1.,0.,0.));
+#3625=DIRECTION('ref_axis',(0.,1.,0.));
+#3626=DIRECTION('',(0.,1.,0.));
+#3627=DIRECTION('center_axis',(0.,1.,0.));
+#3628=DIRECTION('ref_axis',(1.,0.,0.));
+#3629=DIRECTION('',(0.,0.,-1.));
+#3630=DIRECTION('',(1.,0.,0.));
+#3631=DIRECTION('',(0.,0.,-1.));
+#3632=DIRECTION('center_axis',(1.,0.,0.));
+#3633=DIRECTION('ref_axis',(0.,-1.,0.));
+#3634=DIRECTION('',(0.,-1.,0.));
+#3635=DIRECTION('',(0.,0.,-1.));
+#3636=DIRECTION('center_axis',(0.,-1.,0.));
+#3637=DIRECTION('ref_axis',(-1.,0.,0.));
+#3638=DIRECTION('',(-1.,0.,0.));
+#3639=DIRECTION('',(0.,0.,-1.));
+#3640=DIRECTION('center_axis',(-1.,0.,0.));
+#3641=DIRECTION('ref_axis',(0.,1.,0.));
+#3642=DIRECTION('',(0.,1.,0.));
+#3643=DIRECTION('center_axis',(0.00211883867752521,0.99999775525881,0.));
+#3644=DIRECTION('ref_axis',(0.99999775525881,-0.00211883867752521,0.));
+#3645=DIRECTION('',(0.,0.,-1.));
+#3646=DIRECTION('',(0.99999775525881,-0.00211883867752521,0.));
+#3647=DIRECTION('',(0.,0.,-1.));
+#3648=DIRECTION('center_axis',(0.99999775525881,-0.00211883867752538,0.));
+#3649=DIRECTION('ref_axis',(-0.00211883867752538,-0.99999775525881,0.));
+#3650=DIRECTION('',(-0.00211883867752538,-0.99999775525881,0.));
+#3651=DIRECTION('center_axis',(-1.,0.,0.));
+#3652=DIRECTION('ref_axis',(0.,1.,0.));
+#3653=DIRECTION('',(0.,1.,0.));
+#3654=DIRECTION('center_axis',(1.,0.,0.));
+#3655=DIRECTION('ref_axis',(0.,-1.,0.));
+#3656=DIRECTION('',(0.,-1.,0.));
+#3657=DIRECTION('center_axis',(-0.99999775525881,0.00211883867751913,0.));
+#3658=DIRECTION('ref_axis',(0.00211883867751913,0.99999775525881,0.));
+#3659=DIRECTION('',(0.00211883867751913,0.99999775525881,0.));
+#3660=DIRECTION('center_axis',(0.,0.,1.));
+#3661=DIRECTION('ref_axis',(1.,0.,0.));
+#3662=DIRECTION('center_axis',(0.,0.,1.));
+#3663=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#3664=DIRECTION('center_axis',(0.,0.,-1.));
+#3665=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#3666=DIRECTION('',(0.,0.,-1.));
+#3667=DIRECTION('center_axis',(0.,0.,1.));
+#3668=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#3669=DIRECTION('',(0.,0.,1.));
+#3670=DIRECTION('center_axis',(-1.,0.,0.));
+#3671=DIRECTION('ref_axis',(0.,-1.,0.));
+#3672=DIRECTION('',(0.,1.,0.));
+#3673=DIRECTION('',(0.,0.,-1.));
+#3674=DIRECTION('',(0.,-1.,0.));
+#3675=DIRECTION('center_axis',(0.,0.,1.));
+#3676=DIRECTION('ref_axis',(1.,0.,0.));
+#3677=DIRECTION('',(1.,0.,0.));
+#3678=DIRECTION('center_axis',(0.,0.,1.));
+#3679=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3680=DIRECTION('',(0.,-1.,0.));
+#3681=DIRECTION('center_axis',(0.,0.,1.));
+#3682=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#3683=DIRECTION('',(-1.,-4.8472887907141E-17,0.));
+#3684=DIRECTION('center_axis',(0.,0.,1.));
+#3685=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#3686=DIRECTION('center_axis',(0.,0.,1.));
+#3687=DIRECTION('ref_axis',(1.,0.,0.));
+#3688=DIRECTION('',(1.,2.89337761429314E-33,0.));
+#3689=DIRECTION('',(0.,1.,0.));
+#3690=DIRECTION('',(-1.,0.,0.));
+#3691=DIRECTION('',(-1.72904223214608E-33,-1.,0.));
+#3692=DIRECTION('center_axis',(0.,0.,1.));
+#3693=DIRECTION('ref_axis',(1.,0.,0.));
+#3694=DIRECTION('center_axis',(0.,0.,1.));
+#3695=DIRECTION('ref_axis',(1.,0.,0.));
+#3696=DIRECTION('center_axis',(0.,0.,1.));
+#3697=DIRECTION('ref_axis',(1.,0.,0.));
+#3698=DIRECTION('center_axis',(0.,0.,1.));
+#3699=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#3700=DIRECTION('center_axis',(0.,0.,-1.));
+#3701=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#3702=DIRECTION('',(0.,0.,1.));
+#3703=DIRECTION('center_axis',(4.8472887907141E-17,-1.,0.));
+#3704=DIRECTION('ref_axis',(1.,4.8472887907141E-17,0.));
+#3705=DIRECTION('',(0.,0.,-1.));
+#3706=DIRECTION('',(1.,4.8472887907141E-17,0.));
+#3707=DIRECTION('center_axis',(0.,0.,1.));
+#3708=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#3709=DIRECTION('center_axis',(0.,0.,-1.));
+#3710=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#3711=DIRECTION('',(0.,0.,1.));
+#3712=DIRECTION('center_axis',(1.,0.,0.));
+#3713=DIRECTION('ref_axis',(0.,1.,0.));
+#3714=DIRECTION('',(0.,0.,-1.));
+#3715=DIRECTION('',(0.,1.,0.));
+#3716=DIRECTION('center_axis',(0.,0.,1.));
+#3717=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3718=DIRECTION('center_axis',(0.,0.,-1.));
+#3719=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#3720=DIRECTION('',(0.,0.,1.));
+#3721=DIRECTION('center_axis',(0.,0.,1.));
+#3722=DIRECTION('ref_axis',(1.,0.,0.));
+#3723=DIRECTION('center_axis',(0.,0.,-1.));
+#3724=DIRECTION('ref_axis',(1.,0.,0.));
+#3725=DIRECTION('',(0.,0.,-1.));
+#3726=DIRECTION('center_axis',(0.,0.,1.));
+#3727=DIRECTION('ref_axis',(1.,0.,0.));
+#3728=DIRECTION('center_axis',(0.,0.,-1.));
+#3729=DIRECTION('ref_axis',(1.,0.,0.));
+#3730=DIRECTION('',(0.,0.,-1.));
+#3731=DIRECTION('center_axis',(0.,0.,1.));
+#3732=DIRECTION('ref_axis',(1.,0.,0.));
+#3733=DIRECTION('center_axis',(0.,0.,-1.));
+#3734=DIRECTION('ref_axis',(1.,0.,0.));
+#3735=DIRECTION('',(0.,0.,-1.));
+#3736=DIRECTION('center_axis',(-1.,0.,0.));
+#3737=DIRECTION('ref_axis',(0.,-1.,0.));
+#3738=DIRECTION('',(0.,0.,1.));
+#3739=DIRECTION('',(0.,-1.,0.));
+#3740=DIRECTION('',(0.,0.,1.));
+#3741=DIRECTION('center_axis',(0.,-1.,0.));
+#3742=DIRECTION('ref_axis',(1.,0.,0.));
+#3743=DIRECTION('',(1.,0.,0.));
+#3744=DIRECTION('',(0.,0.,1.));
+#3745=DIRECTION('center_axis',(1.,-1.72904223214608E-33,0.));
+#3746=DIRECTION('ref_axis',(1.72904223214608E-33,1.,0.));
+#3747=DIRECTION('',(1.72904223214608E-33,1.,0.));
+#3748=DIRECTION('',(0.,0.,1.));
+#3749=DIRECTION('center_axis',(-2.89337761429314E-33,1.,0.));
+#3750=DIRECTION('ref_axis',(-1.,-2.89337761429314E-33,0.));
+#3751=DIRECTION('',(-1.,-2.89337761429314E-33,0.));
+#3752=DIRECTION('center_axis',(0.,0.,1.));
+#3753=DIRECTION('ref_axis',(1.,0.,0.));
+#3754=DIRECTION('center_axis',(0.,0.,-1.));
+#3755=DIRECTION('ref_axis',(1.,0.,0.));
+#3756=DIRECTION('',(0.,0.,-1.));
+#3757=DIRECTION('center_axis',(0.,1.,0.));
+#3758=DIRECTION('ref_axis',(-1.,0.,0.));
+#3759=DIRECTION('',(-1.,0.,0.));
+#3760=DIRECTION('center_axis',(0.,0.,1.));
+#3761=DIRECTION('ref_axis',(1.,0.,0.));
+#3762=CARTESIAN_POINT('',(0.,0.,0.));
+#3763=CARTESIAN_POINT('Origin',(-5.,74.06,0.));
+#3764=CARTESIAN_POINT('',(-10.,74.06,18.));
+#3765=CARTESIAN_POINT('',(-5.,79.06,18.));
+#3766=CARTESIAN_POINT('Origin',(-5.,74.06,18.));
+#3767=CARTESIAN_POINT('',(-5.,79.06,0.));
+#3768=CARTESIAN_POINT('',(-5.,79.06,0.));
+#3769=CARTESIAN_POINT('',(-10.,74.06,0.));
+#3770=CARTESIAN_POINT('Origin',(-5.,74.06,0.));
+#3771=CARTESIAN_POINT('',(-10.,74.06,0.));
+#3772=CARTESIAN_POINT('Origin',(47.26,34.53,18.));
+#3773=CARTESIAN_POINT('',(-10.,-5.,18.));
+#3774=CARTESIAN_POINT('',(-10.,56.795,18.));
+#3775=CARTESIAN_POINT('',(-5.,-10.,18.));
+#3776=CARTESIAN_POINT('Origin',(-5.,-5.,18.));
+#3777=CARTESIAN_POINT('',(99.52,-10.,18.));
+#3778=CARTESIAN_POINT('',(18.63,-10.,18.));
+#3779=CARTESIAN_POINT('',(104.52,-5.,18.));
+#3780=CARTESIAN_POINT('Origin',(99.52,-5.,18.));
+#3781=CARTESIAN_POINT('',(104.52,74.06,18.));
+#3782=CARTESIAN_POINT('',(104.52,12.265,18.));
+#3783=CARTESIAN_POINT('',(99.52,79.06,18.));
+#3784=CARTESIAN_POINT('Origin',(99.52,74.06,18.));
+#3785=CARTESIAN_POINT('',(23.4403267770942,79.06,18.));
+#3786=CARTESIAN_POINT('',(75.89,79.06,18.));
+#3787=CARTESIAN_POINT('',(23.4191598922962,69.0701704256521,18.));
+#3788=CARTESIAN_POINT('',(23.3952026224009,57.7634030103233,18.));
+#3789=CARTESIAN_POINT('',(28.2191491175385,69.06,18.));
+#3790=CARTESIAN_POINT('',(37.7761134846859,69.0397502888038,18.));
+#3791=CARTESIAN_POINT('',(94.52,69.06,18.));
+#3792=CARTESIAN_POINT('',(94.52,69.06,18.));
+#3793=CARTESIAN_POINT('',(94.52,0.,18.));
+#3794=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,18.));
+#3795=CARTESIAN_POINT('',(0.,0.,18.));
+#3796=CARTESIAN_POINT('',(0.,0.,18.));
+#3797=CARTESIAN_POINT('',(0.,69.06,18.));
+#3798=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,18.));
+#3799=CARTESIAN_POINT('',(4.21914911753852,69.06,18.));
+#3800=CARTESIAN_POINT('',(94.52,69.06,18.));
+#3801=CARTESIAN_POINT('',(4.24033755187631,79.06,18.));
+#3802=CARTESIAN_POINT('',(4.15484025360816,38.7090722697651,18.));
+#3803=CARTESIAN_POINT('',(75.89,79.06,18.));
+#3804=CARTESIAN_POINT('',(98.17,-5.1,18.));
+#3805=CARTESIAN_POINT('Origin',(99.62,-5.1,18.));
+#3806=CARTESIAN_POINT('',(-6.54999999999999,-5.1,18.));
+#3807=CARTESIAN_POINT('Origin',(-5.1,-5.1,18.));
+#3808=CARTESIAN_POINT('',(98.17,74.16,18.));
+#3809=CARTESIAN_POINT('Origin',(99.62,74.16,18.));
+#3810=CARTESIAN_POINT('',(-6.4500000745058,74.16,18.));
+#3811=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,18.));
+#3812=CARTESIAN_POINT('Origin',(-10.,79.06,0.));
+#3813=CARTESIAN_POINT('',(-10.,-5.,0.));
+#3814=CARTESIAN_POINT('',(-10.,79.06,0.));
+#3815=CARTESIAN_POINT('',(-10.,-5.,0.));
+#3816=CARTESIAN_POINT('Origin',(-5.,-5.,0.));
+#3817=CARTESIAN_POINT('',(-5.,-10.,0.));
+#3818=CARTESIAN_POINT('Origin',(-5.,-5.,0.));
+#3819=CARTESIAN_POINT('',(-5.,-10.,0.));
+#3820=CARTESIAN_POINT('Origin',(99.52,-5.,0.));
+#3821=CARTESIAN_POINT('',(99.52,-10.,0.));
+#3822=CARTESIAN_POINT('',(99.52,-10.,0.));
+#3823=CARTESIAN_POINT('',(104.52,-5.,0.));
+#3824=CARTESIAN_POINT('Origin',(99.52,-5.,0.));
+#3825=CARTESIAN_POINT('',(104.52,-5.,0.));
+#3826=CARTESIAN_POINT('Origin',(104.52,-10.,0.));
+#3827=CARTESIAN_POINT('',(104.52,74.06,0.));
+#3828=CARTESIAN_POINT('',(104.52,-10.,0.));
+#3829=CARTESIAN_POINT('',(104.52,74.06,0.));
+#3830=CARTESIAN_POINT('Origin',(99.52,74.06,0.));
+#3831=CARTESIAN_POINT('',(99.52,79.06,0.));
+#3832=CARTESIAN_POINT('Origin',(99.52,74.06,0.));
+#3833=CARTESIAN_POINT('',(99.52,79.06,0.));
+#3834=CARTESIAN_POINT('Origin',(104.52,79.06,0.));
+#3835=CARTESIAN_POINT('',(4.24033755187632,79.06,14.));
+#3836=CARTESIAN_POINT('',(4.24033755187631,79.06,18.));
+#3837=CARTESIAN_POINT('',(23.4403267770944,79.06,14.));
+#3838=CARTESIAN_POINT('',(66.3801687759382,79.06,14.));
+#3839=CARTESIAN_POINT('',(23.4403267770942,79.06,21.));
+#3840=CARTESIAN_POINT('',(104.52,79.06,0.));
+#3841=CARTESIAN_POINT('Origin',(4.16350149405484,42.7967931030271,36.));
+#3842=CARTESIAN_POINT('',(4.21914911753851,69.06,14.));
+#3843=CARTESIAN_POINT('',(4.21914911753851,69.06,18.));
+#3844=CARTESIAN_POINT('',(4.24431242958124,80.9359657469501,14.));
+#3845=CARTESIAN_POINT('Origin',(23.4443232043387,80.9461361726022,36.));
+#3846=CARTESIAN_POINT('',(23.4191598922962,69.0701704256521,14.));
+#3847=CARTESIAN_POINT('',(23.4240665968502,71.3859170616409,14.));
+#3848=CARTESIAN_POINT('',(23.4191598922962,69.0701704256521,18.));
+#3849=CARTESIAN_POINT('Origin',(-10.,-10.,0.));
+#3850=CARTESIAN_POINT('',(-10.,-10.,0.));
+#3851=CARTESIAN_POINT('Origin',(28.2191491175385,69.06,14.));
+#3852=CARTESIAN_POINT('',(28.2191491175385,69.06,14.));
+#3853=CARTESIAN_POINT('',(28.2191491175385,69.06,18.));
+#3854=CARTESIAN_POINT('',(22.2192029911457,69.072712946453,14.));
+#3855=CARTESIAN_POINT('Origin',(16.203906961818,61.8409534179332,14.));
+#3856=CARTESIAN_POINT('',(8.10195348090902,69.06,14.));
+#3857=CARTESIAN_POINT('Origin',(94.52,69.06,0.));
+#3858=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,4.));
+#3859=CARTESIAN_POINT('',(94.52,69.06,4.));
+#3860=CARTESIAN_POINT('',(94.52,51.795,4.));
+#3861=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,0.));
+#3862=CARTESIAN_POINT('',(94.52,69.06,0.));
+#3863=CARTESIAN_POINT('Origin',(94.52,2.73482052102987E-31,0.));
+#3864=CARTESIAN_POINT('',(0.,0.,4.));
+#3865=CARTESIAN_POINT('',(70.89,0.,4.));
+#3866=CARTESIAN_POINT('',(0.,0.,0.));
+#3867=CARTESIAN_POINT('Origin',(0.,69.06,0.));
+#3868=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,4.));
+#3869=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,0.));
+#3870=CARTESIAN_POINT('',(23.63,69.06,4.));
+#3871=CARTESIAN_POINT('Origin',(0.,0.,0.));
+#3872=CARTESIAN_POINT('',(0.,17.265,4.));
+#3873=CARTESIAN_POINT('Origin',(99.62,-5.1,0.));
+#3874=CARTESIAN_POINT('',(98.17,-5.1,0.));
+#3875=CARTESIAN_POINT('',(98.17,-5.1,0.));
+#3876=CARTESIAN_POINT('Origin',(99.62,-5.1,0.));
+#3877=CARTESIAN_POINT('Origin',(-5.1,-5.1,0.));
+#3878=CARTESIAN_POINT('',(-6.55,-5.1,0.));
+#3879=CARTESIAN_POINT('',(-6.55,-5.1,0.));
+#3880=CARTESIAN_POINT('Origin',(-5.1,-5.1,0.));
+#3881=CARTESIAN_POINT('Origin',(99.62,74.16,0.));
+#3882=CARTESIAN_POINT('',(98.17,74.16,0.));
+#3883=CARTESIAN_POINT('',(98.17,74.16,0.));
+#3884=CARTESIAN_POINT('Origin',(99.62,74.16,0.));
+#3885=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,0.));
+#3886=CARTESIAN_POINT('',(-6.45000007450581,74.16,0.));
+#3887=CARTESIAN_POINT('',(-6.45000007450581,74.16,0.));
+#3888=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,0.));
+#3889=CARTESIAN_POINT('Origin',(47.26,34.53,4.));
+#3890=CARTESIAN_POINT('Origin',(47.26,34.53,0.));
+#3891=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#3892=CARTESIAN_POINT('',(-5.,79.06,18.));
+#3893=CARTESIAN_POINT('',(-10.,74.06,18.));
+#3894=CARTESIAN_POINT('Origin',(-5.,74.06,18.));
+#3895=CARTESIAN_POINT('',(-10.,74.06,21.));
+#3896=CARTESIAN_POINT('',(-10.,74.06,21.));
+#3897=CARTESIAN_POINT('',(-5.,79.06,21.));
+#3898=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#3899=CARTESIAN_POINT('',(-5.,79.06,21.));
+#3900=CARTESIAN_POINT('Origin',(-10.,79.06,21.));
+#3901=CARTESIAN_POINT('',(4.24033755187631,79.06,21.));
+#3902=CARTESIAN_POINT('',(75.89,79.06,21.));
+#3903=CARTESIAN_POINT('',(4.24033755187631,79.06,18.));
+#3904=CARTESIAN_POINT('',(4.24033755187631,79.06,21.));
+#3905=CARTESIAN_POINT('',(75.89,79.06,18.));
+#3906=CARTESIAN_POINT('Origin',(47.26,34.53,21.));
+#3907=CARTESIAN_POINT('',(-10.,-5.,21.));
+#3908=CARTESIAN_POINT('',(-10.,56.795,21.));
+#3909=CARTESIAN_POINT('',(-5.,-10.,21.));
+#3910=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#3911=CARTESIAN_POINT('',(99.52,-10.,21.));
+#3912=CARTESIAN_POINT('',(18.63,-10.,21.));
+#3913=CARTESIAN_POINT('',(104.52,-5.,21.));
+#3914=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#3915=CARTESIAN_POINT('',(104.52,74.06,21.));
+#3916=CARTESIAN_POINT('',(104.52,12.265,21.));
+#3917=CARTESIAN_POINT('',(99.52,79.06,21.));
+#3918=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#3919=CARTESIAN_POINT('',(23.4403267770942,79.06,21.));
+#3920=CARTESIAN_POINT('',(75.89,79.06,21.));
+#3921=CARTESIAN_POINT('',(23.3634045213564,42.7561115145685,21.));
+#3922=CARTESIAN_POINT('',(23.3952026224009,57.7634030103233,21.));
+#3923=CARTESIAN_POINT('',(4.16350149405484,42.7967931030271,21.));
+#3924=CARTESIAN_POINT('',(37.720358113746,42.7256913777202,21.));
+#3925=CARTESIAN_POINT('',(4.15484025360816,38.7090722697651,21.));
+#3926=CARTESIAN_POINT('',(65.245,59.545,21.));
+#3927=CARTESIAN_POINT('',(65.245,47.045,21.));
+#3928=CARTESIAN_POINT('',(65.245,46.9375,21.));
+#3929=CARTESIAN_POINT('',(26.545,47.045,21.));
+#3930=CARTESIAN_POINT('',(56.1525,47.045,21.));
+#3931=CARTESIAN_POINT('',(26.545,59.545,21.));
+#3932=CARTESIAN_POINT('',(26.545,40.8875,21.));
+#3933=CARTESIAN_POINT('',(37.0025,59.545,21.));
+#3934=CARTESIAN_POINT('',(87.61,59.79,21.));
+#3935=CARTESIAN_POINT('',(87.61,46.79,21.));
+#3936=CARTESIAN_POINT('',(87.61,47.16,21.));
+#3937=CARTESIAN_POINT('',(87.11,46.29,21.));
+#3938=CARTESIAN_POINT('Origin',(87.11,46.79,21.));
+#3939=CARTESIAN_POINT('',(74.11,46.29,21.));
+#3940=CARTESIAN_POINT('',(67.185,46.29,21.));
+#3941=CARTESIAN_POINT('',(73.61,46.79,21.));
+#3942=CARTESIAN_POINT('Origin',(74.11,46.79,21.));
+#3943=CARTESIAN_POINT('',(73.61,59.79,21.));
+#3944=CARTESIAN_POINT('',(73.61,40.66,21.));
+#3945=CARTESIAN_POINT('',(74.11,60.29,21.));
+#3946=CARTESIAN_POINT('Origin',(74.11,59.79,21.));
+#3947=CARTESIAN_POINT('',(87.11,60.29,21.));
+#3948=CARTESIAN_POINT('',(60.685,60.29,21.));
+#3949=CARTESIAN_POINT('Origin',(87.11,59.79,21.));
+#3950=CARTESIAN_POINT('',(58.835,39.59,21.));
+#3951=CARTESIAN_POINT('',(58.835,26.59,21.));
+#3952=CARTESIAN_POINT('',(58.835,37.06,21.));
+#3953=CARTESIAN_POINT('',(58.335,26.09,21.));
+#3954=CARTESIAN_POINT('Origin',(58.335,26.59,21.));
+#3955=CARTESIAN_POINT('',(45.335,26.09,21.));
+#3956=CARTESIAN_POINT('',(52.7975,26.09,21.));
+#3957=CARTESIAN_POINT('',(44.835,26.59,21.));
+#3958=CARTESIAN_POINT('Origin',(45.335,26.59,21.));
+#3959=CARTESIAN_POINT('',(44.835,39.59,21.));
+#3960=CARTESIAN_POINT('',(44.835,30.56,21.));
+#3961=CARTESIAN_POINT('',(45.335,40.09,21.));
+#3962=CARTESIAN_POINT('Origin',(45.335,39.59,21.));
+#3963=CARTESIAN_POINT('',(58.335,40.09,21.));
+#3964=CARTESIAN_POINT('',(46.2975,40.09,21.));
+#3965=CARTESIAN_POINT('Origin',(58.335,39.59,21.));
+#3966=CARTESIAN_POINT('',(39.785,39.59,21.));
+#3967=CARTESIAN_POINT('',(39.785,26.59,21.));
+#3968=CARTESIAN_POINT('',(39.785,37.06,21.));
+#3969=CARTESIAN_POINT('',(39.285,26.09,21.));
+#3970=CARTESIAN_POINT('Origin',(39.285,26.59,21.));
+#3971=CARTESIAN_POINT('',(26.285,26.09,21.));
+#3972=CARTESIAN_POINT('',(43.2725,26.09,21.));
+#3973=CARTESIAN_POINT('',(25.785,26.59,21.));
+#3974=CARTESIAN_POINT('Origin',(26.285,26.59,21.));
+#3975=CARTESIAN_POINT('',(25.785,39.59,21.));
+#3976=CARTESIAN_POINT('',(25.785,30.56,21.));
+#3977=CARTESIAN_POINT('',(26.285,40.09,21.));
+#3978=CARTESIAN_POINT('Origin',(26.285,39.59,21.));
+#3979=CARTESIAN_POINT('',(39.285,40.09,21.));
+#3980=CARTESIAN_POINT('',(36.7725,40.09,21.));
+#3981=CARTESIAN_POINT('Origin',(39.285,39.59,21.));
+#3982=CARTESIAN_POINT('',(20.735,20.54,21.));
+#3983=CARTESIAN_POINT('',(20.735,7.54,21.));
+#3984=CARTESIAN_POINT('',(20.735,27.535,21.));
+#3985=CARTESIAN_POINT('',(20.235,7.04,21.));
+#3986=CARTESIAN_POINT('Origin',(20.235,7.54,21.));
+#3987=CARTESIAN_POINT('',(7.235,7.04000000000001,21.));
+#3988=CARTESIAN_POINT('',(33.7475,7.04,21.));
+#3989=CARTESIAN_POINT('',(6.735,7.54,21.));
+#3990=CARTESIAN_POINT('Origin',(7.235,7.54,21.));
+#3991=CARTESIAN_POINT('',(6.735,20.54,21.));
+#3992=CARTESIAN_POINT('',(6.735,21.035,21.));
+#3993=CARTESIAN_POINT('',(7.235,21.04,21.));
+#3994=CARTESIAN_POINT('Origin',(7.235,20.54,21.));
+#3995=CARTESIAN_POINT('',(20.235,21.04,21.));
+#3996=CARTESIAN_POINT('',(27.2475,21.04,21.));
+#3997=CARTESIAN_POINT('Origin',(20.235,20.54,21.));
+#3998=CARTESIAN_POINT('',(87.41,20.54,21.));
+#3999=CARTESIAN_POINT('',(87.41,7.54,21.));
+#4000=CARTESIAN_POINT('',(87.41,27.535,21.));
+#4001=CARTESIAN_POINT('',(86.91,7.04,21.));
+#4002=CARTESIAN_POINT('Origin',(86.91,7.54,21.));
+#4003=CARTESIAN_POINT('',(73.91,7.04000000000001,21.));
+#4004=CARTESIAN_POINT('',(67.085,7.04,21.));
+#4005=CARTESIAN_POINT('',(73.41,7.54,21.));
+#4006=CARTESIAN_POINT('Origin',(73.91,7.54,21.));
+#4007=CARTESIAN_POINT('',(73.41,20.54,21.));
+#4008=CARTESIAN_POINT('',(73.41,21.035,21.));
+#4009=CARTESIAN_POINT('',(73.91,21.04,21.));
+#4010=CARTESIAN_POINT('Origin',(73.91,20.54,21.));
+#4011=CARTESIAN_POINT('',(86.91,21.04,21.));
+#4012=CARTESIAN_POINT('',(60.585,21.04,21.));
+#4013=CARTESIAN_POINT('Origin',(86.91,20.54,21.));
+#4014=CARTESIAN_POINT('',(58.835,20.54,21.));
+#4015=CARTESIAN_POINT('',(58.835,7.54,21.));
+#4016=CARTESIAN_POINT('',(58.835,27.535,21.));
+#4017=CARTESIAN_POINT('',(58.335,7.04,21.));
+#4018=CARTESIAN_POINT('Origin',(58.335,7.54,21.));
+#4019=CARTESIAN_POINT('',(45.335,7.04000000000001,21.));
+#4020=CARTESIAN_POINT('',(52.7975,7.04,21.));
+#4021=CARTESIAN_POINT('',(44.835,7.54,21.));
+#4022=CARTESIAN_POINT('Origin',(45.335,7.54,21.));
+#4023=CARTESIAN_POINT('',(44.835,20.54,21.));
+#4024=CARTESIAN_POINT('',(44.835,21.035,21.));
+#4025=CARTESIAN_POINT('',(45.335,21.04,21.));
+#4026=CARTESIAN_POINT('Origin',(45.335,20.54,21.));
+#4027=CARTESIAN_POINT('',(58.335,21.04,21.));
+#4028=CARTESIAN_POINT('',(46.2975,21.04,21.));
+#4029=CARTESIAN_POINT('Origin',(58.335,20.54,21.));
+#4030=CARTESIAN_POINT('',(20.735,39.59,21.));
+#4031=CARTESIAN_POINT('',(20.735,26.59,21.));
+#4032=CARTESIAN_POINT('',(20.735,37.06,21.));
+#4033=CARTESIAN_POINT('',(20.235,26.09,21.));
+#4034=CARTESIAN_POINT('Origin',(20.235,26.59,21.));
+#4035=CARTESIAN_POINT('',(7.235,26.09,21.));
+#4036=CARTESIAN_POINT('',(33.7475,26.09,21.));
+#4037=CARTESIAN_POINT('',(6.735,26.59,21.));
+#4038=CARTESIAN_POINT('Origin',(7.235,26.59,21.));
+#4039=CARTESIAN_POINT('',(6.735,39.59,21.));
+#4040=CARTESIAN_POINT('',(6.735,30.56,21.));
+#4041=CARTESIAN_POINT('',(7.235,40.09,21.));
+#4042=CARTESIAN_POINT('Origin',(7.235,39.59,21.));
+#4043=CARTESIAN_POINT('',(20.235,40.09,21.));
+#4044=CARTESIAN_POINT('',(27.2475,40.09,21.));
+#4045=CARTESIAN_POINT('Origin',(20.235,39.59,21.));
+#4046=CARTESIAN_POINT('',(39.785,20.54,21.));
+#4047=CARTESIAN_POINT('',(39.785,7.54,21.));
+#4048=CARTESIAN_POINT('',(39.785,27.535,21.));
+#4049=CARTESIAN_POINT('',(39.285,7.04,21.));
+#4050=CARTESIAN_POINT('Origin',(39.285,7.54,21.));
+#4051=CARTESIAN_POINT('',(26.285,7.04000000000001,21.));
+#4052=CARTESIAN_POINT('',(43.2725,7.04,21.));
+#4053=CARTESIAN_POINT('',(25.785,7.54,21.));
+#4054=CARTESIAN_POINT('Origin',(26.285,7.54,21.));
+#4055=CARTESIAN_POINT('',(25.785,20.54,21.));
+#4056=CARTESIAN_POINT('',(25.785,21.035,21.));
+#4057=CARTESIAN_POINT('',(26.285,21.04,21.));
+#4058=CARTESIAN_POINT('Origin',(26.285,20.54,21.));
+#4059=CARTESIAN_POINT('',(39.285,21.04,21.));
+#4060=CARTESIAN_POINT('',(36.7725,21.04,21.));
+#4061=CARTESIAN_POINT('Origin',(39.285,20.54,21.));
+#4062=CARTESIAN_POINT('',(87.41,39.59,21.));
+#4063=CARTESIAN_POINT('',(87.41,26.59,21.));
+#4064=CARTESIAN_POINT('',(87.41,37.06,21.));
+#4065=CARTESIAN_POINT('',(86.91,26.09,21.));
+#4066=CARTESIAN_POINT('Origin',(86.91,26.59,21.));
+#4067=CARTESIAN_POINT('',(73.91,26.09,21.));
+#4068=CARTESIAN_POINT('',(67.085,26.09,21.));
+#4069=CARTESIAN_POINT('',(73.41,26.59,21.));
+#4070=CARTESIAN_POINT('Origin',(73.91,26.59,21.));
+#4071=CARTESIAN_POINT('',(73.41,39.59,21.));
+#4072=CARTESIAN_POINT('',(73.41,30.56,21.));
+#4073=CARTESIAN_POINT('',(73.91,40.09,21.));
+#4074=CARTESIAN_POINT('Origin',(73.91,39.59,21.));
+#4075=CARTESIAN_POINT('',(86.91,40.09,21.));
+#4076=CARTESIAN_POINT('',(60.585,40.09,21.));
+#4077=CARTESIAN_POINT('Origin',(86.91,39.59,21.));
+#4078=CARTESIAN_POINT('',(-6.4500000745058,74.16,21.));
+#4079=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#4080=CARTESIAN_POINT('',(98.17,74.16,21.));
+#4081=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#4082=CARTESIAN_POINT('',(-6.54999999999999,-5.10000000000001,21.));
+#4083=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#4084=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#4085=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#4086=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#4087=CARTESIAN_POINT('',(-10.,-5.,18.));
+#4088=CARTESIAN_POINT('',(-5.,-10.,18.));
+#4089=CARTESIAN_POINT('Origin',(-5.,-5.,18.));
+#4090=CARTESIAN_POINT('',(-5.,-10.,21.));
+#4091=CARTESIAN_POINT('',(-10.,-5.,21.));
+#4092=CARTESIAN_POINT('Origin',(104.52,-10.,21.));
+#4093=CARTESIAN_POINT('',(99.52,-10.,18.));
+#4094=CARTESIAN_POINT('',(18.63,-10.,18.));
+#4095=CARTESIAN_POINT('',(99.52,-10.,21.));
+#4096=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#4097=CARTESIAN_POINT('',(104.52,-5.,18.));
+#4098=CARTESIAN_POINT('Origin',(99.52,-5.,18.));
+#4099=CARTESIAN_POINT('',(104.52,-5.,21.));
+#4100=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#4101=CARTESIAN_POINT('',(104.52,74.06,18.));
+#4102=CARTESIAN_POINT('',(99.52,79.06,18.));
+#4103=CARTESIAN_POINT('Origin',(99.52,74.06,18.));
+#4104=CARTESIAN_POINT('',(99.52,79.06,21.));
+#4105=CARTESIAN_POINT('',(104.52,74.06,21.));
+#4106=CARTESIAN_POINT('Origin',(23.4403267770942,79.06,21.));
+#4107=CARTESIAN_POINT('',(23.4403267770942,79.06,18.));
+#4108=CARTESIAN_POINT('',(75.89,79.06,18.));
+#4109=CARTESIAN_POINT('',(23.4403267770942,79.06,21.));
+#4110=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#4111=CARTESIAN_POINT('',(98.17,-5.1,18.));
+#4112=CARTESIAN_POINT('Origin',(99.62,-5.1,18.));
+#4113=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#4114=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#4115=CARTESIAN_POINT('',(-6.54999999999999,-5.1,18.));
+#4116=CARTESIAN_POINT('Origin',(-5.1,-5.1,18.));
+#4117=CARTESIAN_POINT('',(-6.55,-5.1,21.));
+#4118=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#4119=CARTESIAN_POINT('',(98.17,74.16,18.));
+#4120=CARTESIAN_POINT('Origin',(99.62,74.16,18.));
+#4121=CARTESIAN_POINT('',(98.17,74.16,21.));
+#4122=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#4123=CARTESIAN_POINT('',(-6.4500000745058,74.16,18.));
+#4124=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,18.));
+#4125=CARTESIAN_POINT('',(-6.45000007450581,74.16,21.));
+#4126=CARTESIAN_POINT('Origin',(86.91,26.59,21.));
+#4127=CARTESIAN_POINT('',(87.41,26.59,18.));
+#4128=CARTESIAN_POINT('',(87.41,26.59,21.));
+#4129=CARTESIAN_POINT('',(86.91,26.09,18.));
+#4130=CARTESIAN_POINT('Origin',(86.91,26.59,18.));
+#4131=CARTESIAN_POINT('',(86.91,26.09,21.));
+#4132=CARTESIAN_POINT('Origin',(73.91,26.09,21.));
+#4133=CARTESIAN_POINT('',(73.91,26.09,18.));
+#4134=CARTESIAN_POINT('',(67.085,26.09,18.));
+#4135=CARTESIAN_POINT('',(73.91,26.09,21.));
+#4136=CARTESIAN_POINT('Origin',(73.91,26.59,21.));
+#4137=CARTESIAN_POINT('',(73.41,26.59,18.));
+#4138=CARTESIAN_POINT('Origin',(73.91,26.59,18.));
+#4139=CARTESIAN_POINT('',(73.41,26.59,21.));
+#4140=CARTESIAN_POINT('Origin',(73.41,39.59,21.));
+#4141=CARTESIAN_POINT('',(73.41,39.59,18.));
+#4142=CARTESIAN_POINT('',(73.41,30.56,18.));
+#4143=CARTESIAN_POINT('',(73.41,39.59,21.));
+#4144=CARTESIAN_POINT('Origin',(73.91,39.59,21.));
+#4145=CARTESIAN_POINT('',(73.91,40.09,18.));
+#4146=CARTESIAN_POINT('Origin',(73.91,39.59,18.));
+#4147=CARTESIAN_POINT('',(73.91,40.09,21.));
+#4148=CARTESIAN_POINT('Origin',(86.91,40.09,21.));
+#4149=CARTESIAN_POINT('',(86.91,40.09,18.));
+#4150=CARTESIAN_POINT('',(60.585,40.09,18.));
+#4151=CARTESIAN_POINT('',(86.91,40.09,21.));
+#4152=CARTESIAN_POINT('Origin',(86.91,39.59,21.));
+#4153=CARTESIAN_POINT('',(87.41,39.59,18.));
+#4154=CARTESIAN_POINT('Origin',(86.91,39.59,18.));
+#4155=CARTESIAN_POINT('',(87.41,39.59,21.));
+#4156=CARTESIAN_POINT('Origin',(87.41,26.59,21.));
+#4157=CARTESIAN_POINT('',(87.41,37.06,18.));
+#4158=CARTESIAN_POINT('Origin',(39.285,7.54,21.));
+#4159=CARTESIAN_POINT('',(39.785,7.54,18.));
+#4160=CARTESIAN_POINT('',(39.785,7.54,21.));
+#4161=CARTESIAN_POINT('',(39.285,7.04000000000001,18.));
+#4162=CARTESIAN_POINT('Origin',(39.285,7.54,18.));
+#4163=CARTESIAN_POINT('',(39.285,7.04,21.));
+#4164=CARTESIAN_POINT('Origin',(26.285,7.04,21.));
+#4165=CARTESIAN_POINT('',(26.285,7.04000000000001,18.));
+#4166=CARTESIAN_POINT('',(43.2725,7.04,18.));
+#4167=CARTESIAN_POINT('',(26.285,7.04000000000001,21.));
+#4168=CARTESIAN_POINT('Origin',(26.285,7.54,21.));
+#4169=CARTESIAN_POINT('',(25.785,7.54,18.));
+#4170=CARTESIAN_POINT('Origin',(26.285,7.54,18.));
+#4171=CARTESIAN_POINT('',(25.785,7.54,21.));
+#4172=CARTESIAN_POINT('Origin',(25.785,20.54,21.));
+#4173=CARTESIAN_POINT('',(25.785,20.54,18.));
+#4174=CARTESIAN_POINT('',(25.785,21.035,18.));
+#4175=CARTESIAN_POINT('',(25.785,20.54,21.));
+#4176=CARTESIAN_POINT('Origin',(26.285,20.54,21.));
+#4177=CARTESIAN_POINT('',(26.285,21.04,18.));
+#4178=CARTESIAN_POINT('Origin',(26.285,20.54,18.));
+#4179=CARTESIAN_POINT('',(26.285,21.04,21.));
+#4180=CARTESIAN_POINT('Origin',(39.285,21.04,21.));
+#4181=CARTESIAN_POINT('',(39.285,21.04,18.));
+#4182=CARTESIAN_POINT('',(36.7725,21.04,18.));
+#4183=CARTESIAN_POINT('',(39.285,21.04,21.));
+#4184=CARTESIAN_POINT('Origin',(39.285,20.54,21.));
+#4185=CARTESIAN_POINT('',(39.785,20.54,18.));
+#4186=CARTESIAN_POINT('Origin',(39.285,20.54,18.));
+#4187=CARTESIAN_POINT('',(39.785,20.54,21.));
+#4188=CARTESIAN_POINT('Origin',(39.785,7.54,21.));
+#4189=CARTESIAN_POINT('',(39.785,27.535,18.));
+#4190=CARTESIAN_POINT('Origin',(20.235,26.59,21.));
+#4191=CARTESIAN_POINT('',(20.735,26.59,18.));
+#4192=CARTESIAN_POINT('',(20.735,26.59,21.));
+#4193=CARTESIAN_POINT('',(20.235,26.09,18.));
+#4194=CARTESIAN_POINT('Origin',(20.235,26.59,18.));
+#4195=CARTESIAN_POINT('',(20.235,26.09,21.));
+#4196=CARTESIAN_POINT('Origin',(7.235,26.09,21.));
+#4197=CARTESIAN_POINT('',(7.235,26.09,18.));
+#4198=CARTESIAN_POINT('',(33.7475,26.09,18.));
+#4199=CARTESIAN_POINT('',(7.235,26.09,21.));
+#4200=CARTESIAN_POINT('Origin',(7.235,26.59,21.));
+#4201=CARTESIAN_POINT('',(6.735,26.59,18.));
+#4202=CARTESIAN_POINT('Origin',(7.235,26.59,18.));
+#4203=CARTESIAN_POINT('',(6.735,26.59,21.));
+#4204=CARTESIAN_POINT('Origin',(6.735,39.59,21.));
+#4205=CARTESIAN_POINT('',(6.735,39.59,18.));
+#4206=CARTESIAN_POINT('',(6.735,30.56,18.));
+#4207=CARTESIAN_POINT('',(6.735,39.59,21.));
+#4208=CARTESIAN_POINT('Origin',(7.235,39.59,21.));
+#4209=CARTESIAN_POINT('',(7.235,40.09,18.));
+#4210=CARTESIAN_POINT('Origin',(7.235,39.59,18.));
+#4211=CARTESIAN_POINT('',(7.235,40.09,21.));
+#4212=CARTESIAN_POINT('Origin',(20.235,40.09,21.));
+#4213=CARTESIAN_POINT('',(20.235,40.09,18.));
+#4214=CARTESIAN_POINT('',(27.2475,40.09,18.));
+#4215=CARTESIAN_POINT('',(20.235,40.09,21.));
+#4216=CARTESIAN_POINT('Origin',(20.235,39.59,21.));
+#4217=CARTESIAN_POINT('',(20.735,39.59,18.));
+#4218=CARTESIAN_POINT('Origin',(20.235,39.59,18.));
+#4219=CARTESIAN_POINT('',(20.735,39.59,21.));
+#4220=CARTESIAN_POINT('Origin',(20.735,26.59,21.));
+#4221=CARTESIAN_POINT('',(20.735,37.06,18.));
+#4222=CARTESIAN_POINT('Origin',(58.335,7.54,21.));
+#4223=CARTESIAN_POINT('',(58.835,7.54,18.));
+#4224=CARTESIAN_POINT('',(58.835,7.54,21.));
+#4225=CARTESIAN_POINT('',(58.335,7.04000000000001,18.));
+#4226=CARTESIAN_POINT('Origin',(58.335,7.54,18.));
+#4227=CARTESIAN_POINT('',(58.335,7.04,21.));
+#4228=CARTESIAN_POINT('Origin',(45.335,7.04,21.));
+#4229=CARTESIAN_POINT('',(45.335,7.04000000000001,18.));
+#4230=CARTESIAN_POINT('',(52.7975,7.04,18.));
+#4231=CARTESIAN_POINT('',(45.335,7.04000000000001,21.));
+#4232=CARTESIAN_POINT('Origin',(45.335,7.54,21.));
+#4233=CARTESIAN_POINT('',(44.835,7.54,18.));
+#4234=CARTESIAN_POINT('Origin',(45.335,7.54,18.));
+#4235=CARTESIAN_POINT('',(44.835,7.54,21.));
+#4236=CARTESIAN_POINT('Origin',(44.835,20.54,21.));
+#4237=CARTESIAN_POINT('',(44.835,20.54,18.));
+#4238=CARTESIAN_POINT('',(44.835,21.035,18.));
+#4239=CARTESIAN_POINT('',(44.835,20.54,21.));
+#4240=CARTESIAN_POINT('Origin',(45.335,20.54,21.));
+#4241=CARTESIAN_POINT('',(45.335,21.04,18.));
+#4242=CARTESIAN_POINT('Origin',(45.335,20.54,18.));
+#4243=CARTESIAN_POINT('',(45.335,21.04,21.));
+#4244=CARTESIAN_POINT('Origin',(58.335,21.04,21.));
+#4245=CARTESIAN_POINT('',(58.335,21.04,18.));
+#4246=CARTESIAN_POINT('',(46.2975,21.04,18.));
+#4247=CARTESIAN_POINT('',(58.335,21.04,21.));
+#4248=CARTESIAN_POINT('Origin',(58.335,20.54,21.));
+#4249=CARTESIAN_POINT('',(58.835,20.54,18.));
+#4250=CARTESIAN_POINT('Origin',(58.335,20.54,18.));
+#4251=CARTESIAN_POINT('',(58.835,20.54,21.));
+#4252=CARTESIAN_POINT('Origin',(58.835,7.54,21.));
+#4253=CARTESIAN_POINT('',(58.835,27.535,18.));
+#4254=CARTESIAN_POINT('Origin',(86.91,7.54,21.));
+#4255=CARTESIAN_POINT('',(87.41,7.54,18.));
+#4256=CARTESIAN_POINT('',(87.41,7.54,21.));
+#4257=CARTESIAN_POINT('',(86.91,7.04000000000001,18.));
+#4258=CARTESIAN_POINT('Origin',(86.91,7.54,18.));
+#4259=CARTESIAN_POINT('',(86.91,7.04,21.));
+#4260=CARTESIAN_POINT('Origin',(73.91,7.04,21.));
+#4261=CARTESIAN_POINT('',(73.91,7.04000000000001,18.));
+#4262=CARTESIAN_POINT('',(67.085,7.04,18.));
+#4263=CARTESIAN_POINT('',(73.91,7.04000000000001,21.));
+#4264=CARTESIAN_POINT('Origin',(73.91,7.54,21.));
+#4265=CARTESIAN_POINT('',(73.41,7.54,18.));
+#4266=CARTESIAN_POINT('Origin',(73.91,7.54,18.));
+#4267=CARTESIAN_POINT('',(73.41,7.54,21.));
+#4268=CARTESIAN_POINT('Origin',(73.41,20.54,21.));
+#4269=CARTESIAN_POINT('',(73.41,20.54,18.));
+#4270=CARTESIAN_POINT('',(73.41,21.035,18.));
+#4271=CARTESIAN_POINT('',(73.41,20.54,21.));
+#4272=CARTESIAN_POINT('Origin',(73.91,20.54,21.));
+#4273=CARTESIAN_POINT('',(73.91,21.04,18.));
+#4274=CARTESIAN_POINT('Origin',(73.91,20.54,18.));
+#4275=CARTESIAN_POINT('',(73.91,21.04,21.));
+#4276=CARTESIAN_POINT('Origin',(86.91,21.04,21.));
+#4277=CARTESIAN_POINT('',(86.91,21.04,18.));
+#4278=CARTESIAN_POINT('',(60.585,21.04,18.));
+#4279=CARTESIAN_POINT('',(86.91,21.04,21.));
+#4280=CARTESIAN_POINT('Origin',(86.91,20.54,21.));
+#4281=CARTESIAN_POINT('',(87.41,20.54,18.));
+#4282=CARTESIAN_POINT('Origin',(86.91,20.54,18.));
+#4283=CARTESIAN_POINT('',(87.41,20.54,21.));
+#4284=CARTESIAN_POINT('Origin',(87.41,7.54,21.));
+#4285=CARTESIAN_POINT('',(87.41,27.535,18.));
+#4286=CARTESIAN_POINT('Origin',(20.235,7.54,21.));
+#4287=CARTESIAN_POINT('',(20.735,7.54,18.));
+#4288=CARTESIAN_POINT('',(20.735,7.54,21.));
+#4289=CARTESIAN_POINT('',(20.235,7.04000000000001,18.));
+#4290=CARTESIAN_POINT('Origin',(20.235,7.54,18.));
+#4291=CARTESIAN_POINT('',(20.235,7.04,21.));
+#4292=CARTESIAN_POINT('Origin',(7.235,7.04,21.));
+#4293=CARTESIAN_POINT('',(7.235,7.04000000000001,18.));
+#4294=CARTESIAN_POINT('',(33.7475,7.04,18.));
+#4295=CARTESIAN_POINT('',(7.235,7.04000000000001,21.));
+#4296=CARTESIAN_POINT('Origin',(7.235,7.54,21.));
+#4297=CARTESIAN_POINT('',(6.735,7.54,18.));
+#4298=CARTESIAN_POINT('Origin',(7.235,7.54,18.));
+#4299=CARTESIAN_POINT('',(6.735,7.54,21.));
+#4300=CARTESIAN_POINT('Origin',(6.735,20.54,21.));
+#4301=CARTESIAN_POINT('',(6.735,20.54,18.));
+#4302=CARTESIAN_POINT('',(6.735,21.035,18.));
+#4303=CARTESIAN_POINT('',(6.735,20.54,21.));
+#4304=CARTESIAN_POINT('Origin',(7.235,20.54,21.));
+#4305=CARTESIAN_POINT('',(7.235,21.04,18.));
+#4306=CARTESIAN_POINT('Origin',(7.235,20.54,18.));
+#4307=CARTESIAN_POINT('',(7.235,21.04,21.));
+#4308=CARTESIAN_POINT('Origin',(20.235,21.04,21.));
+#4309=CARTESIAN_POINT('',(20.235,21.04,18.));
+#4310=CARTESIAN_POINT('',(27.2475,21.04,18.));
+#4311=CARTESIAN_POINT('',(20.235,21.04,21.));
+#4312=CARTESIAN_POINT('Origin',(20.235,20.54,21.));
+#4313=CARTESIAN_POINT('',(20.735,20.54,18.));
+#4314=CARTESIAN_POINT('Origin',(20.235,20.54,18.));
+#4315=CARTESIAN_POINT('',(20.735,20.54,21.));
+#4316=CARTESIAN_POINT('Origin',(20.735,7.54,21.));
+#4317=CARTESIAN_POINT('',(20.735,27.535,18.));
+#4318=CARTESIAN_POINT('Origin',(39.285,26.59,21.));
+#4319=CARTESIAN_POINT('',(39.785,26.59,18.));
+#4320=CARTESIAN_POINT('',(39.785,26.59,21.));
+#4321=CARTESIAN_POINT('',(39.285,26.09,18.));
+#4322=CARTESIAN_POINT('Origin',(39.285,26.59,18.));
+#4323=CARTESIAN_POINT('',(39.285,26.09,21.));
+#4324=CARTESIAN_POINT('Origin',(26.285,26.09,21.));
+#4325=CARTESIAN_POINT('',(26.285,26.09,18.));
+#4326=CARTESIAN_POINT('',(43.2725,26.09,18.));
+#4327=CARTESIAN_POINT('',(26.285,26.09,21.));
+#4328=CARTESIAN_POINT('Origin',(26.285,26.59,21.));
+#4329=CARTESIAN_POINT('',(25.785,26.59,18.));
+#4330=CARTESIAN_POINT('Origin',(26.285,26.59,18.));
+#4331=CARTESIAN_POINT('',(25.785,26.59,21.));
+#4332=CARTESIAN_POINT('Origin',(25.785,39.59,21.));
+#4333=CARTESIAN_POINT('',(25.785,39.59,18.));
+#4334=CARTESIAN_POINT('',(25.785,30.56,18.));
+#4335=CARTESIAN_POINT('',(25.785,39.59,21.));
+#4336=CARTESIAN_POINT('Origin',(26.285,39.59,21.));
+#4337=CARTESIAN_POINT('',(26.285,40.09,18.));
+#4338=CARTESIAN_POINT('Origin',(26.285,39.59,18.));
+#4339=CARTESIAN_POINT('',(26.285,40.09,21.));
+#4340=CARTESIAN_POINT('Origin',(39.285,40.09,21.));
+#4341=CARTESIAN_POINT('',(39.285,40.09,18.));
+#4342=CARTESIAN_POINT('',(36.7725,40.09,18.));
+#4343=CARTESIAN_POINT('',(39.285,40.09,21.));
+#4344=CARTESIAN_POINT('Origin',(39.285,39.59,21.));
+#4345=CARTESIAN_POINT('',(39.785,39.59,18.));
+#4346=CARTESIAN_POINT('Origin',(39.285,39.59,18.));
+#4347=CARTESIAN_POINT('',(39.785,39.59,21.));
+#4348=CARTESIAN_POINT('Origin',(39.785,26.59,21.));
+#4349=CARTESIAN_POINT('',(39.785,37.06,18.));
+#4350=CARTESIAN_POINT('Origin',(58.335,26.59,21.));
+#4351=CARTESIAN_POINT('',(58.835,26.59,18.));
+#4352=CARTESIAN_POINT('',(58.835,26.59,21.));
+#4353=CARTESIAN_POINT('',(58.335,26.09,18.));
+#4354=CARTESIAN_POINT('Origin',(58.335,26.59,18.));
+#4355=CARTESIAN_POINT('',(58.335,26.09,21.));
+#4356=CARTESIAN_POINT('Origin',(45.335,26.09,21.));
+#4357=CARTESIAN_POINT('',(45.335,26.09,18.));
+#4358=CARTESIAN_POINT('',(52.7975,26.09,18.));
+#4359=CARTESIAN_POINT('',(45.335,26.09,21.));
+#4360=CARTESIAN_POINT('Origin',(45.335,26.59,21.));
+#4361=CARTESIAN_POINT('',(44.835,26.59,18.));
+#4362=CARTESIAN_POINT('Origin',(45.335,26.59,18.));
+#4363=CARTESIAN_POINT('',(44.835,26.59,21.));
+#4364=CARTESIAN_POINT('Origin',(44.835,39.59,21.));
+#4365=CARTESIAN_POINT('',(44.835,39.59,18.));
+#4366=CARTESIAN_POINT('',(44.835,30.56,18.));
+#4367=CARTESIAN_POINT('',(44.835,39.59,21.));
+#4368=CARTESIAN_POINT('Origin',(45.335,39.59,21.));
+#4369=CARTESIAN_POINT('',(45.335,40.09,18.));
+#4370=CARTESIAN_POINT('Origin',(45.335,39.59,18.));
+#4371=CARTESIAN_POINT('',(45.335,40.09,21.));
+#4372=CARTESIAN_POINT('Origin',(58.335,40.09,21.));
+#4373=CARTESIAN_POINT('',(58.335,40.09,18.));
+#4374=CARTESIAN_POINT('',(46.2975,40.09,18.));
+#4375=CARTESIAN_POINT('',(58.335,40.09,21.));
+#4376=CARTESIAN_POINT('Origin',(58.335,39.59,21.));
+#4377=CARTESIAN_POINT('',(58.835,39.59,18.));
+#4378=CARTESIAN_POINT('Origin',(58.335,39.59,18.));
+#4379=CARTESIAN_POINT('',(58.835,39.59,21.));
+#4380=CARTESIAN_POINT('Origin',(58.835,26.59,21.));
+#4381=CARTESIAN_POINT('',(58.835,37.06,18.));
+#4382=CARTESIAN_POINT('Origin',(87.11,46.79,21.));
+#4383=CARTESIAN_POINT('',(87.61,46.79,18.));
+#4384=CARTESIAN_POINT('',(87.61,46.79,21.));
+#4385=CARTESIAN_POINT('',(87.11,46.29,18.));
+#4386=CARTESIAN_POINT('Origin',(87.11,46.79,18.));
+#4387=CARTESIAN_POINT('',(87.11,46.29,21.));
+#4388=CARTESIAN_POINT('Origin',(74.11,46.29,21.));
+#4389=CARTESIAN_POINT('',(74.11,46.29,18.));
+#4390=CARTESIAN_POINT('',(67.185,46.29,18.));
+#4391=CARTESIAN_POINT('',(74.11,46.29,21.));
+#4392=CARTESIAN_POINT('Origin',(74.11,46.79,21.));
+#4393=CARTESIAN_POINT('',(73.61,46.79,18.));
+#4394=CARTESIAN_POINT('Origin',(74.11,46.79,18.));
+#4395=CARTESIAN_POINT('',(73.61,46.79,21.));
+#4396=CARTESIAN_POINT('Origin',(73.61,59.79,21.));
+#4397=CARTESIAN_POINT('',(73.61,59.79,18.));
+#4398=CARTESIAN_POINT('',(73.61,40.66,18.));
+#4399=CARTESIAN_POINT('',(73.61,59.79,21.));
+#4400=CARTESIAN_POINT('Origin',(74.11,59.79,21.));
+#4401=CARTESIAN_POINT('',(74.11,60.29,18.));
+#4402=CARTESIAN_POINT('Origin',(74.11,59.79,18.));
+#4403=CARTESIAN_POINT('',(74.11,60.29,21.));
+#4404=CARTESIAN_POINT('Origin',(87.11,60.29,21.));
+#4405=CARTESIAN_POINT('',(87.11,60.29,18.));
+#4406=CARTESIAN_POINT('',(60.685,60.29,18.));
+#4407=CARTESIAN_POINT('',(87.11,60.29,21.));
+#4408=CARTESIAN_POINT('Origin',(87.11,59.79,21.));
+#4409=CARTESIAN_POINT('',(87.61,59.79,18.));
+#4410=CARTESIAN_POINT('Origin',(87.11,59.79,18.));
+#4411=CARTESIAN_POINT('',(87.61,59.79,21.));
+#4412=CARTESIAN_POINT('Origin',(87.61,46.79,21.));
+#4413=CARTESIAN_POINT('',(87.61,47.16,18.));
+#4414=CARTESIAN_POINT('Origin',(26.545,47.045,21.));
+#4415=CARTESIAN_POINT('',(65.245,47.045,18.));
+#4416=CARTESIAN_POINT('',(65.245,47.045,21.));
+#4417=CARTESIAN_POINT('',(26.545,47.045,18.));
+#4418=CARTESIAN_POINT('',(56.1525,47.045,18.));
+#4419=CARTESIAN_POINT('',(26.545,47.045,21.));
+#4420=CARTESIAN_POINT('Origin',(26.545,59.545,21.));
+#4421=CARTESIAN_POINT('',(26.545,59.545,18.));
+#4422=CARTESIAN_POINT('',(26.545,40.8875,18.));
+#4423=CARTESIAN_POINT('',(26.545,59.545,21.));
+#4424=CARTESIAN_POINT('Origin',(65.245,59.545,21.));
+#4425=CARTESIAN_POINT('',(65.245,59.545,18.));
+#4426=CARTESIAN_POINT('',(37.0025,59.545,18.));
+#4427=CARTESIAN_POINT('',(65.245,59.545,21.));
+#4428=CARTESIAN_POINT('Origin',(65.245,47.045,21.));
+#4429=CARTESIAN_POINT('',(65.245,46.9375,18.));
+#4430=CARTESIAN_POINT('Origin',(4.16350149405484,42.7967931030271,21.));
+#4431=CARTESIAN_POINT('',(23.3634045213564,42.7561115145685,18.));
+#4432=CARTESIAN_POINT('',(23.3634045213564,42.7561115145685,21.));
+#4433=CARTESIAN_POINT('',(4.16350149405484,42.7967931030271,18.));
+#4434=CARTESIAN_POINT('',(37.720358113746,42.7256913777202,18.));
+#4435=CARTESIAN_POINT('',(4.16350149405484,42.7967931030271,21.));
+#4436=CARTESIAN_POINT('Origin',(4.24033755187632,79.06,21.));
+#4437=CARTESIAN_POINT('',(4.15484025360816,38.7090722697651,18.));
+#4438=CARTESIAN_POINT('Origin',(-10.,-10.,21.));
+#4439=CARTESIAN_POINT('',(-10.,56.795,18.));
+#4440=CARTESIAN_POINT('Origin',(104.52,79.06,21.));
+#4441=CARTESIAN_POINT('',(104.52,12.265,18.));
+#4442=CARTESIAN_POINT('Origin',(23.3634045213564,42.7561115145685,21.));
+#4443=CARTESIAN_POINT('',(23.3952026224009,57.7634030103233,18.));
+#4444=CARTESIAN_POINT('Origin',(47.26,34.53,18.));
+#4445=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#4446=CARTESIAN_POINT('',(-10.,74.06,27.));
+#4447=CARTESIAN_POINT('',(-5.,79.06,27.));
+#4448=CARTESIAN_POINT('Origin',(-5.,74.06,27.));
+#4449=CARTESIAN_POINT('',(-5.,79.06,21.));
+#4450=CARTESIAN_POINT('',(-5.,79.06,21.));
+#4451=CARTESIAN_POINT('',(-10.,74.06,21.));
+#4452=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#4453=CARTESIAN_POINT('',(-10.,74.06,21.));
+#4454=CARTESIAN_POINT('Origin',(-10.,79.06,21.));
+#4455=CARTESIAN_POINT('',(-10.,-5.,21.));
+#4456=CARTESIAN_POINT('',(-10.,56.795,21.));
+#4457=CARTESIAN_POINT('',(-10.,-5.,27.));
+#4458=CARTESIAN_POINT('',(-10.,-5.,21.));
+#4459=CARTESIAN_POINT('',(-10.,56.795,27.));
+#4460=CARTESIAN_POINT('Origin',(47.26,34.53,21.));
+#4461=CARTESIAN_POINT('',(99.52,79.06,21.));
+#4462=CARTESIAN_POINT('',(75.89,79.06,21.));
+#4463=CARTESIAN_POINT('',(104.52,74.06,21.));
+#4464=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#4465=CARTESIAN_POINT('',(104.52,-5.,21.));
+#4466=CARTESIAN_POINT('',(104.52,12.265,21.));
+#4467=CARTESIAN_POINT('',(99.52,-10.,21.));
+#4468=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#4469=CARTESIAN_POINT('',(-5.,-10.,21.));
+#4470=CARTESIAN_POINT('',(18.63,-10.,21.));
+#4471=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#4472=CARTESIAN_POINT('',(-6.45000007450581,74.16,21.));
+#4473=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#4474=CARTESIAN_POINT('',(0.,0.,21.));
+#4475=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,21.));
+#4476=CARTESIAN_POINT('',(70.89,0.,21.));
+#4477=CARTESIAN_POINT('',(94.52,69.06,21.));
+#4478=CARTESIAN_POINT('',(94.52,51.795,21.));
+#4479=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,21.));
+#4480=CARTESIAN_POINT('',(23.63,69.06,21.));
+#4481=CARTESIAN_POINT('',(0.,17.265,21.));
+#4482=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#4483=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#4484=CARTESIAN_POINT('',(-6.55,-5.1,21.));
+#4485=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#4486=CARTESIAN_POINT('',(98.17,74.16,21.));
+#4487=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#4488=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#4489=CARTESIAN_POINT('',(-5.,-10.,27.));
+#4490=CARTESIAN_POINT('Origin',(-5.,-5.,27.));
+#4491=CARTESIAN_POINT('',(-5.,-10.,21.));
+#4492=CARTESIAN_POINT('Origin',(-10.,-10.,21.));
+#4493=CARTESIAN_POINT('',(99.52,-10.,27.));
+#4494=CARTESIAN_POINT('',(99.52,-10.,21.));
+#4495=CARTESIAN_POINT('',(18.63,-10.,27.));
+#4496=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#4497=CARTESIAN_POINT('',(104.52,-5.,27.));
+#4498=CARTESIAN_POINT('Origin',(99.52,-5.,27.));
+#4499=CARTESIAN_POINT('',(104.52,-5.,21.));
+#4500=CARTESIAN_POINT('Origin',(104.52,-10.,21.));
+#4501=CARTESIAN_POINT('',(104.52,74.06,27.));
+#4502=CARTESIAN_POINT('',(104.52,74.06,21.));
+#4503=CARTESIAN_POINT('',(104.52,12.265,27.));
+#4504=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#4505=CARTESIAN_POINT('',(99.52,79.06,27.));
+#4506=CARTESIAN_POINT('Origin',(99.52,74.06,27.));
+#4507=CARTESIAN_POINT('',(99.52,79.06,21.));
+#4508=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#4509=CARTESIAN_POINT('',(98.17,74.16,27.));
+#4510=CARTESIAN_POINT('Origin',(99.62,74.16,27.));
+#4511=CARTESIAN_POINT('',(98.17,74.16,21.));
+#4512=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#4513=CARTESIAN_POINT('',(-6.55,-5.1,27.));
+#4514=CARTESIAN_POINT('Origin',(-5.1,-5.1,27.));
+#4515=CARTESIAN_POINT('',(-6.55,-5.1,21.));
+#4516=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#4517=CARTESIAN_POINT('',(98.17,-5.1,27.));
+#4518=CARTESIAN_POINT('Origin',(99.62,-5.1,27.));
+#4519=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#4520=CARTESIAN_POINT('Origin',(94.52,69.06,21.));
+#4521=CARTESIAN_POINT('',(94.52,0.,27.));
+#4522=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,21.));
+#4523=CARTESIAN_POINT('',(94.52,69.06,27.));
+#4524=CARTESIAN_POINT('',(94.52,51.795,27.));
+#4525=CARTESIAN_POINT('',(94.52,69.06,21.));
+#4526=CARTESIAN_POINT('Origin',(0.,69.06,21.));
+#4527=CARTESIAN_POINT('',(0.,69.06,27.));
+#4528=CARTESIAN_POINT('',(23.63,69.06,27.));
+#4529=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,21.));
+#4530=CARTESIAN_POINT('Origin',(-2.98519141380022E-32,0.,21.));
+#4531=CARTESIAN_POINT('',(0.,0.,27.));
+#4532=CARTESIAN_POINT('',(0.,17.265,27.));
+#4533=CARTESIAN_POINT('',(0.,0.,21.));
+#4534=CARTESIAN_POINT('Origin',(94.52,6.83705130257469E-32,21.));
+#4535=CARTESIAN_POINT('',(70.89,0.,27.));
+#4536=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#4537=CARTESIAN_POINT('',(-6.45000007450581,74.16,27.));
+#4538=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,27.));
+#4539=CARTESIAN_POINT('',(-6.45000007450581,74.16,21.));
+#4540=CARTESIAN_POINT('Origin',(104.52,79.06,21.));
+#4541=CARTESIAN_POINT('',(75.89,79.06,27.));
+#4542=CARTESIAN_POINT('Origin',(47.26,34.53,27.));
+#4543=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#4547,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#4544=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#4547,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#4545=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#4543))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#4547,#4548,#4549))
+REPRESENTATION_CONTEXT('','3D')
+);
+#4546=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#4544))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#4547,#4548,#4549))
+REPRESENTATION_CONTEXT('','3D')
+);
+#4547=(
+LENGTH_UNIT()
+NAMED_UNIT(*)
+SI_UNIT(.MILLI.,.METRE.)
+);
+#4548=(
+NAMED_UNIT(*)
+PLANE_ANGLE_UNIT()
+SI_UNIT($,.RADIAN.)
+);
+#4549=(
+NAMED_UNIT(*)
+SI_UNIT($,.STERADIAN.)
+SOLID_ANGLE_UNIT()
+);
+#4550=SHAPE_DEFINITION_REPRESENTATION(#4551,#4552);
+#4551=PRODUCT_DEFINITION_SHAPE('',$,#4554);
+#4552=SHAPE_REPRESENTATION('',(#2727),#4545);
+#4553=PRODUCT_DEFINITION_CONTEXT('part definition',#4558,'design');
+#4554=PRODUCT_DEFINITION('hackpad','hackpad v5',#4555,#4553);
+#4555=PRODUCT_DEFINITION_FORMATION('',$,#4560);
+#4556=PRODUCT_RELATED_PRODUCT_CATEGORY('hackpad v5','hackpad v5',(#4560));
+#4557=APPLICATION_PROTOCOL_DEFINITION('international standard',
+'automotive_design',2009,#4558);
+#4558=APPLICATION_CONTEXT(
+'Core Data for Automotive Mechanical Design Process');
+#4559=PRODUCT_CONTEXT('part definition',#4558,'mechanical');
+#4560=PRODUCT('hackpad','hackpad v5',$,(#4559));
+#4561=PRESENTATION_STYLE_ASSIGNMENT((#4562));
+#4562=SURFACE_STYLE_USAGE(.BOTH.,#4563);
+#4563=SURFACE_SIDE_STYLE('',(#4564));
+#4564=SURFACE_STYLE_FILL_AREA(#4565);
+#4565=FILL_AREA_STYLE('Steel - Satin',(#4566));
+#4566=FILL_AREA_STYLE_COLOUR('Steel - Satin',#4567);
+#4567=COLOUR_RGB('Steel - Satin',0.627450980392157,0.627450980392157,0.627450980392157);
+ENDSEC;
+END-ISO-10303-21;
diff --git a/hackpads/blipyboard/cad/bottom.step b/hackpads/blipyboard/cad/bottom.step
new file mode 100644
index 0000000000..bd8b7e4535
--- /dev/null
+++ b/hackpads/blipyboard/cad/bottom.step
@@ -0,0 +1,833 @@
+ISO-10303-21;
+HEADER;
+/* Generated by software containing ST-Developer
+ * from STEP Tools, Inc. (www.steptools.com)
+ */
+
+FILE_DESCRIPTION(
+/* description */ (''),
+/* implementation_level */ '2;1');
+
+FILE_NAME(
+/* name */ 'bottom.step',
+/* time_stamp */ '2025-06-27T17:52:25-07:00',
+/* author */ (''),
+/* organization */ (''),
+/* preprocessor_version */ 'ST-DEVELOPER v20.1',
+/* originating_system */ 'Autodesk Translation Framework v14.10.0.0',
+/* authorisation */ '');
+
+FILE_SCHEMA (('AUTOMOTIVE_DESIGN { 1 0 10303 214 3 1 1 }'));
+ENDSEC;
+
+DATA;
+#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#13),#764);
+#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#770,#12);
+#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#14),#763);
+#13=STYLED_ITEM('',(#779),#14);
+#14=MANIFOLD_SOLID_BREP('bottom',#464);
+#15=FACE_BOUND('',#63,.T.);
+#16=FACE_BOUND('',#64,.T.);
+#17=FACE_BOUND('',#65,.T.);
+#18=FACE_BOUND('',#66,.T.);
+#19=FACE_BOUND('',#88,.T.);
+#20=FACE_BOUND('',#89,.T.);
+#21=FACE_BOUND('',#90,.T.);
+#22=FACE_BOUND('',#91,.T.);
+#23=PLANE('',#469);
+#24=PLANE('',#477);
+#25=PLANE('',#482);
+#26=PLANE('',#485);
+#27=PLANE('',#486);
+#28=PLANE('',#487);
+#29=PLANE('',#488);
+#30=PLANE('',#489);
+#31=PLANE('',#490);
+#32=PLANE('',#491);
+#33=PLANE('',#492);
+#34=PLANE('',#493);
+#35=PLANE('',#494);
+#36=PLANE('',#503);
+#37=PLANE('',#504);
+#38=FACE_OUTER_BOUND('',#61,.T.);
+#39=FACE_OUTER_BOUND('',#62,.T.);
+#40=FACE_OUTER_BOUND('',#67,.T.);
+#41=FACE_OUTER_BOUND('',#68,.T.);
+#42=FACE_OUTER_BOUND('',#69,.T.);
+#43=FACE_OUTER_BOUND('',#70,.T.);
+#44=FACE_OUTER_BOUND('',#71,.T.);
+#45=FACE_OUTER_BOUND('',#72,.T.);
+#46=FACE_OUTER_BOUND('',#73,.T.);
+#47=FACE_OUTER_BOUND('',#74,.T.);
+#48=FACE_OUTER_BOUND('',#75,.T.);
+#49=FACE_OUTER_BOUND('',#76,.T.);
+#50=FACE_OUTER_BOUND('',#77,.T.);
+#51=FACE_OUTER_BOUND('',#78,.T.);
+#52=FACE_OUTER_BOUND('',#79,.T.);
+#53=FACE_OUTER_BOUND('',#80,.T.);
+#54=FACE_OUTER_BOUND('',#81,.T.);
+#55=FACE_OUTER_BOUND('',#82,.T.);
+#56=FACE_OUTER_BOUND('',#83,.T.);
+#57=FACE_OUTER_BOUND('',#84,.T.);
+#58=FACE_OUTER_BOUND('',#85,.T.);
+#59=FACE_OUTER_BOUND('',#86,.T.);
+#60=FACE_OUTER_BOUND('',#87,.T.);
+#61=EDGE_LOOP('',(#307,#308,#309,#310));
+#62=EDGE_LOOP('',(#311,#312,#313,#314,#315,#316,#317,#318,#319,#320,#321,
+#322,#323,#324,#325,#326,#327));
+#63=EDGE_LOOP('',(#328));
+#64=EDGE_LOOP('',(#329));
+#65=EDGE_LOOP('',(#330));
+#66=EDGE_LOOP('',(#331));
+#67=EDGE_LOOP('',(#332,#333,#334,#335));
+#68=EDGE_LOOP('',(#336,#337,#338,#339));
+#69=EDGE_LOOP('',(#340,#341,#342,#343));
+#70=EDGE_LOOP('',(#344,#345,#346,#347));
+#71=EDGE_LOOP('',(#348,#349,#350,#351));
+#72=EDGE_LOOP('',(#352,#353,#354,#355,#356,#357,#358,#359));
+#73=EDGE_LOOP('',(#360,#361,#362,#363));
+#74=EDGE_LOOP('',(#364,#365,#366,#367));
+#75=EDGE_LOOP('',(#368,#369,#370,#371));
+#76=EDGE_LOOP('',(#372,#373,#374,#375));
+#77=EDGE_LOOP('',(#376,#377,#378,#379,#380));
+#78=EDGE_LOOP('',(#381,#382,#383,#384));
+#79=EDGE_LOOP('',(#385,#386,#387,#388));
+#80=EDGE_LOOP('',(#389,#390,#391,#392,#393,#394,#395,#396));
+#81=EDGE_LOOP('',(#397,#398,#399,#400));
+#82=EDGE_LOOP('',(#401,#402,#403,#404));
+#83=EDGE_LOOP('',(#405,#406,#407,#408));
+#84=EDGE_LOOP('',(#409,#410,#411,#412));
+#85=EDGE_LOOP('',(#413,#414,#415,#416));
+#86=EDGE_LOOP('',(#417,#418,#419,#420));
+#87=EDGE_LOOP('',(#421,#422,#423,#424,#425,#426,#427,#428));
+#88=EDGE_LOOP('',(#429));
+#89=EDGE_LOOP('',(#430));
+#90=EDGE_LOOP('',(#431));
+#91=EDGE_LOOP('',(#432));
+#92=LINE('',#638,#139);
+#93=LINE('',#641,#140);
+#94=LINE('',#644,#141);
+#95=LINE('',#648,#142);
+#96=LINE('',#652,#143);
+#97=LINE('',#656,#144);
+#98=LINE('',#658,#145);
+#99=LINE('',#660,#146);
+#100=LINE('',#662,#147);
+#101=LINE('',#664,#148);
+#102=LINE('',#666,#149);
+#103=LINE('',#668,#150);
+#104=LINE('',#670,#151);
+#105=LINE('',#672,#152);
+#106=LINE('',#673,#153);
+#107=LINE('',#684,#154);
+#108=LINE('',#685,#155);
+#109=LINE('',#689,#156);
+#110=LINE('',#692,#157);
+#111=LINE('',#695,#158);
+#112=LINE('',#698,#159);
+#113=LINE('',#699,#160);
+#114=LINE('',#703,#161);
+#115=LINE('',#706,#162);
+#116=LINE('',#708,#163);
+#117=LINE('',#709,#164);
+#118=LINE('',#710,#165);
+#119=LINE('',#713,#166);
+#120=LINE('',#714,#167);
+#121=LINE('',#717,#168);
+#122=LINE('',#718,#169);
+#123=LINE('',#720,#170);
+#124=LINE('',#723,#171);
+#125=LINE('',#724,#172);
+#126=LINE('',#726,#173);
+#127=LINE('',#730,#174);
+#128=LINE('',#731,#175);
+#129=LINE('',#732,#176);
+#130=LINE('',#735,#177);
+#131=LINE('',#736,#178);
+#132=LINE('',#739,#179);
+#133=LINE('',#740,#180);
+#134=LINE('',#742,#181);
+#135=LINE('',#745,#182);
+#136=LINE('',#749,#183);
+#137=LINE('',#753,#184);
+#138=LINE('',#757,#185);
+#139=VECTOR('',#511,10.);
+#140=VECTOR('',#514,10.);
+#141=VECTOR('',#517,10.);
+#142=VECTOR('',#520,10.);
+#143=VECTOR('',#523,10.);
+#144=VECTOR('',#526,10.);
+#145=VECTOR('',#527,10.);
+#146=VECTOR('',#528,10.);
+#147=VECTOR('',#529,10.);
+#148=VECTOR('',#530,10.);
+#149=VECTOR('',#531,10.);
+#150=VECTOR('',#532,10.);
+#151=VECTOR('',#533,10.);
+#152=VECTOR('',#534,10.);
+#153=VECTOR('',#535,10.);
+#154=VECTOR('',#546,10.);
+#155=VECTOR('',#547,10.);
+#156=VECTOR('',#552,10.);
+#157=VECTOR('',#555,10.);
+#158=VECTOR('',#558,10.);
+#159=VECTOR('',#561,10.);
+#160=VECTOR('',#562,10.);
+#161=VECTOR('',#567,10.);
+#162=VECTOR('',#570,10.);
+#163=VECTOR('',#571,10.);
+#164=VECTOR('',#572,10.);
+#165=VECTOR('',#573,10.);
+#166=VECTOR('',#576,10.);
+#167=VECTOR('',#577,10.);
+#168=VECTOR('',#580,10.);
+#169=VECTOR('',#581,10.);
+#170=VECTOR('',#584,10.);
+#171=VECTOR('',#587,10.);
+#172=VECTOR('',#588,10.);
+#173=VECTOR('',#591,10.);
+#174=VECTOR('',#594,10.);
+#175=VECTOR('',#595,10.);
+#176=VECTOR('',#596,10.);
+#177=VECTOR('',#599,10.);
+#178=VECTOR('',#600,10.);
+#179=VECTOR('',#603,10.);
+#180=VECTOR('',#604,10.);
+#181=VECTOR('',#607,10.);
+#182=VECTOR('',#610,1.45);
+#183=VECTOR('',#615,1.45);
+#184=VECTOR('',#620,1.45);
+#185=VECTOR('',#625,1.45);
+#186=CIRCLE('',#467,5.);
+#187=CIRCLE('',#468,5.);
+#188=CIRCLE('',#470,5.);
+#189=CIRCLE('',#471,5.);
+#190=CIRCLE('',#472,5.);
+#191=CIRCLE('',#473,1.45);
+#192=CIRCLE('',#474,1.45);
+#193=CIRCLE('',#475,1.45);
+#194=CIRCLE('',#476,1.45);
+#195=CIRCLE('',#479,5.);
+#196=CIRCLE('',#481,5.);
+#197=CIRCLE('',#484,5.);
+#198=CIRCLE('',#496,1.45);
+#199=CIRCLE('',#498,1.45);
+#200=CIRCLE('',#500,1.45);
+#201=CIRCLE('',#502,1.45);
+#202=VERTEX_POINT('',#634);
+#203=VERTEX_POINT('',#635);
+#204=VERTEX_POINT('',#637);
+#205=VERTEX_POINT('',#639);
+#206=VERTEX_POINT('',#643);
+#207=VERTEX_POINT('',#645);
+#208=VERTEX_POINT('',#647);
+#209=VERTEX_POINT('',#649);
+#210=VERTEX_POINT('',#651);
+#211=VERTEX_POINT('',#653);
+#212=VERTEX_POINT('',#655);
+#213=VERTEX_POINT('',#657);
+#214=VERTEX_POINT('',#659);
+#215=VERTEX_POINT('',#661);
+#216=VERTEX_POINT('',#663);
+#217=VERTEX_POINT('',#665);
+#218=VERTEX_POINT('',#667);
+#219=VERTEX_POINT('',#669);
+#220=VERTEX_POINT('',#671);
+#221=VERTEX_POINT('',#674);
+#222=VERTEX_POINT('',#676);
+#223=VERTEX_POINT('',#678);
+#224=VERTEX_POINT('',#680);
+#225=VERTEX_POINT('',#683);
+#226=VERTEX_POINT('',#687);
+#227=VERTEX_POINT('',#691);
+#228=VERTEX_POINT('',#693);
+#229=VERTEX_POINT('',#697);
+#230=VERTEX_POINT('',#701);
+#231=VERTEX_POINT('',#705);
+#232=VERTEX_POINT('',#707);
+#233=VERTEX_POINT('',#712);
+#234=VERTEX_POINT('',#716);
+#235=VERTEX_POINT('',#722);
+#236=VERTEX_POINT('',#728);
+#237=VERTEX_POINT('',#729);
+#238=VERTEX_POINT('',#734);
+#239=VERTEX_POINT('',#738);
+#240=VERTEX_POINT('',#744);
+#241=VERTEX_POINT('',#748);
+#242=VERTEX_POINT('',#752);
+#243=VERTEX_POINT('',#756);
+#244=EDGE_CURVE('',#202,#203,#186,.T.);
+#245=EDGE_CURVE('',#203,#204,#92,.T.);
+#246=EDGE_CURVE('',#204,#205,#187,.T.);
+#247=EDGE_CURVE('',#205,#202,#93,.T.);
+#248=EDGE_CURVE('',#206,#202,#94,.T.);
+#249=EDGE_CURVE('',#207,#206,#188,.T.);
+#250=EDGE_CURVE('',#208,#207,#95,.T.);
+#251=EDGE_CURVE('',#209,#208,#189,.T.);
+#252=EDGE_CURVE('',#210,#209,#96,.T.);
+#253=EDGE_CURVE('',#211,#210,#190,.T.);
+#254=EDGE_CURVE('',#212,#211,#97,.T.);
+#255=EDGE_CURVE('',#213,#212,#98,.T.);
+#256=EDGE_CURVE('',#213,#214,#99,.T.);
+#257=EDGE_CURVE('',#214,#215,#100,.T.);
+#258=EDGE_CURVE('',#215,#216,#101,.T.);
+#259=EDGE_CURVE('',#216,#217,#102,.T.);
+#260=EDGE_CURVE('',#217,#218,#103,.T.);
+#261=EDGE_CURVE('',#218,#219,#104,.T.);
+#262=EDGE_CURVE('',#220,#219,#105,.T.);
+#263=EDGE_CURVE('',#203,#220,#106,.T.);
+#264=EDGE_CURVE('',#221,#221,#191,.T.);
+#265=EDGE_CURVE('',#222,#222,#192,.T.);
+#266=EDGE_CURVE('',#223,#223,#193,.T.);
+#267=EDGE_CURVE('',#224,#224,#194,.T.);
+#268=EDGE_CURVE('',#205,#225,#107,.T.);
+#269=EDGE_CURVE('',#206,#225,#108,.T.);
+#270=EDGE_CURVE('',#225,#226,#195,.T.);
+#271=EDGE_CURVE('',#226,#207,#109,.T.);
+#272=EDGE_CURVE('',#208,#227,#110,.T.);
+#273=EDGE_CURVE('',#227,#228,#196,.T.);
+#274=EDGE_CURVE('',#228,#209,#111,.T.);
+#275=EDGE_CURVE('',#228,#229,#112,.T.);
+#276=EDGE_CURVE('',#210,#229,#113,.T.);
+#277=EDGE_CURVE('',#229,#230,#197,.T.);
+#278=EDGE_CURVE('',#230,#211,#114,.T.);
+#279=EDGE_CURVE('',#220,#231,#115,.T.);
+#280=EDGE_CURVE('',#232,#231,#116,.T.);
+#281=EDGE_CURVE('',#212,#232,#117,.T.);
+#282=EDGE_CURVE('',#230,#204,#118,.T.);
+#283=EDGE_CURVE('',#233,#219,#119,.T.);
+#284=EDGE_CURVE('',#233,#231,#120,.T.);
+#285=EDGE_CURVE('',#234,#232,#121,.T.);
+#286=EDGE_CURVE('',#234,#213,#122,.T.);
+#287=EDGE_CURVE('',#226,#227,#123,.T.);
+#288=EDGE_CURVE('',#214,#235,#124,.T.);
+#289=EDGE_CURVE('',#235,#234,#125,.T.);
+#290=EDGE_CURVE('',#235,#233,#126,.T.);
+#291=EDGE_CURVE('',#236,#237,#127,.T.);
+#292=EDGE_CURVE('',#236,#216,#128,.T.);
+#293=EDGE_CURVE('',#237,#215,#129,.T.);
+#294=EDGE_CURVE('',#238,#236,#130,.T.);
+#295=EDGE_CURVE('',#238,#217,#131,.T.);
+#296=EDGE_CURVE('',#239,#218,#132,.T.);
+#297=EDGE_CURVE('',#237,#239,#133,.T.);
+#298=EDGE_CURVE('',#239,#238,#134,.T.);
+#299=EDGE_CURVE('',#221,#240,#135,.T.);
+#300=EDGE_CURVE('',#240,#240,#198,.T.);
+#301=EDGE_CURVE('',#222,#241,#136,.T.);
+#302=EDGE_CURVE('',#241,#241,#199,.T.);
+#303=EDGE_CURVE('',#223,#242,#137,.T.);
+#304=EDGE_CURVE('',#242,#242,#200,.T.);
+#305=EDGE_CURVE('',#224,#243,#138,.T.);
+#306=EDGE_CURVE('',#243,#243,#201,.T.);
+#307=ORIENTED_EDGE('',*,*,#244,.T.);
+#308=ORIENTED_EDGE('',*,*,#245,.T.);
+#309=ORIENTED_EDGE('',*,*,#246,.T.);
+#310=ORIENTED_EDGE('',*,*,#247,.T.);
+#311=ORIENTED_EDGE('',*,*,#244,.F.);
+#312=ORIENTED_EDGE('',*,*,#248,.F.);
+#313=ORIENTED_EDGE('',*,*,#249,.F.);
+#314=ORIENTED_EDGE('',*,*,#250,.F.);
+#315=ORIENTED_EDGE('',*,*,#251,.F.);
+#316=ORIENTED_EDGE('',*,*,#252,.F.);
+#317=ORIENTED_EDGE('',*,*,#253,.F.);
+#318=ORIENTED_EDGE('',*,*,#254,.F.);
+#319=ORIENTED_EDGE('',*,*,#255,.F.);
+#320=ORIENTED_EDGE('',*,*,#256,.T.);
+#321=ORIENTED_EDGE('',*,*,#257,.T.);
+#322=ORIENTED_EDGE('',*,*,#258,.T.);
+#323=ORIENTED_EDGE('',*,*,#259,.T.);
+#324=ORIENTED_EDGE('',*,*,#260,.T.);
+#325=ORIENTED_EDGE('',*,*,#261,.T.);
+#326=ORIENTED_EDGE('',*,*,#262,.F.);
+#327=ORIENTED_EDGE('',*,*,#263,.F.);
+#328=ORIENTED_EDGE('',*,*,#264,.F.);
+#329=ORIENTED_EDGE('',*,*,#265,.F.);
+#330=ORIENTED_EDGE('',*,*,#266,.F.);
+#331=ORIENTED_EDGE('',*,*,#267,.F.);
+#332=ORIENTED_EDGE('',*,*,#247,.F.);
+#333=ORIENTED_EDGE('',*,*,#268,.T.);
+#334=ORIENTED_EDGE('',*,*,#269,.F.);
+#335=ORIENTED_EDGE('',*,*,#248,.T.);
+#336=ORIENTED_EDGE('',*,*,#249,.T.);
+#337=ORIENTED_EDGE('',*,*,#269,.T.);
+#338=ORIENTED_EDGE('',*,*,#270,.T.);
+#339=ORIENTED_EDGE('',*,*,#271,.T.);
+#340=ORIENTED_EDGE('',*,*,#251,.T.);
+#341=ORIENTED_EDGE('',*,*,#272,.T.);
+#342=ORIENTED_EDGE('',*,*,#273,.T.);
+#343=ORIENTED_EDGE('',*,*,#274,.T.);
+#344=ORIENTED_EDGE('',*,*,#274,.F.);
+#345=ORIENTED_EDGE('',*,*,#275,.T.);
+#346=ORIENTED_EDGE('',*,*,#276,.F.);
+#347=ORIENTED_EDGE('',*,*,#252,.T.);
+#348=ORIENTED_EDGE('',*,*,#253,.T.);
+#349=ORIENTED_EDGE('',*,*,#276,.T.);
+#350=ORIENTED_EDGE('',*,*,#277,.T.);
+#351=ORIENTED_EDGE('',*,*,#278,.T.);
+#352=ORIENTED_EDGE('',*,*,#245,.F.);
+#353=ORIENTED_EDGE('',*,*,#263,.T.);
+#354=ORIENTED_EDGE('',*,*,#279,.T.);
+#355=ORIENTED_EDGE('',*,*,#280,.F.);
+#356=ORIENTED_EDGE('',*,*,#281,.F.);
+#357=ORIENTED_EDGE('',*,*,#254,.T.);
+#358=ORIENTED_EDGE('',*,*,#278,.F.);
+#359=ORIENTED_EDGE('',*,*,#282,.T.);
+#360=ORIENTED_EDGE('',*,*,#262,.T.);
+#361=ORIENTED_EDGE('',*,*,#283,.F.);
+#362=ORIENTED_EDGE('',*,*,#284,.T.);
+#363=ORIENTED_EDGE('',*,*,#279,.F.);
+#364=ORIENTED_EDGE('',*,*,#255,.T.);
+#365=ORIENTED_EDGE('',*,*,#281,.T.);
+#366=ORIENTED_EDGE('',*,*,#285,.F.);
+#367=ORIENTED_EDGE('',*,*,#286,.T.);
+#368=ORIENTED_EDGE('',*,*,#271,.F.);
+#369=ORIENTED_EDGE('',*,*,#287,.T.);
+#370=ORIENTED_EDGE('',*,*,#272,.F.);
+#371=ORIENTED_EDGE('',*,*,#250,.T.);
+#372=ORIENTED_EDGE('',*,*,#288,.F.);
+#373=ORIENTED_EDGE('',*,*,#256,.F.);
+#374=ORIENTED_EDGE('',*,*,#286,.F.);
+#375=ORIENTED_EDGE('',*,*,#289,.F.);
+#376=ORIENTED_EDGE('',*,*,#285,.T.);
+#377=ORIENTED_EDGE('',*,*,#280,.T.);
+#378=ORIENTED_EDGE('',*,*,#284,.F.);
+#379=ORIENTED_EDGE('',*,*,#290,.F.);
+#380=ORIENTED_EDGE('',*,*,#289,.T.);
+#381=ORIENTED_EDGE('',*,*,#291,.F.);
+#382=ORIENTED_EDGE('',*,*,#292,.T.);
+#383=ORIENTED_EDGE('',*,*,#258,.F.);
+#384=ORIENTED_EDGE('',*,*,#293,.F.);
+#385=ORIENTED_EDGE('',*,*,#294,.F.);
+#386=ORIENTED_EDGE('',*,*,#295,.T.);
+#387=ORIENTED_EDGE('',*,*,#259,.F.);
+#388=ORIENTED_EDGE('',*,*,#292,.F.);
+#389=ORIENTED_EDGE('',*,*,#283,.T.);
+#390=ORIENTED_EDGE('',*,*,#261,.F.);
+#391=ORIENTED_EDGE('',*,*,#296,.F.);
+#392=ORIENTED_EDGE('',*,*,#297,.F.);
+#393=ORIENTED_EDGE('',*,*,#293,.T.);
+#394=ORIENTED_EDGE('',*,*,#257,.F.);
+#395=ORIENTED_EDGE('',*,*,#288,.T.);
+#396=ORIENTED_EDGE('',*,*,#290,.T.);
+#397=ORIENTED_EDGE('',*,*,#298,.F.);
+#398=ORIENTED_EDGE('',*,*,#296,.T.);
+#399=ORIENTED_EDGE('',*,*,#260,.F.);
+#400=ORIENTED_EDGE('',*,*,#295,.F.);
+#401=ORIENTED_EDGE('',*,*,#264,.T.);
+#402=ORIENTED_EDGE('',*,*,#299,.T.);
+#403=ORIENTED_EDGE('',*,*,#300,.T.);
+#404=ORIENTED_EDGE('',*,*,#299,.F.);
+#405=ORIENTED_EDGE('',*,*,#265,.T.);
+#406=ORIENTED_EDGE('',*,*,#301,.T.);
+#407=ORIENTED_EDGE('',*,*,#302,.T.);
+#408=ORIENTED_EDGE('',*,*,#301,.F.);
+#409=ORIENTED_EDGE('',*,*,#266,.T.);
+#410=ORIENTED_EDGE('',*,*,#303,.T.);
+#411=ORIENTED_EDGE('',*,*,#304,.T.);
+#412=ORIENTED_EDGE('',*,*,#303,.F.);
+#413=ORIENTED_EDGE('',*,*,#267,.T.);
+#414=ORIENTED_EDGE('',*,*,#305,.T.);
+#415=ORIENTED_EDGE('',*,*,#306,.T.);
+#416=ORIENTED_EDGE('',*,*,#305,.F.);
+#417=ORIENTED_EDGE('',*,*,#294,.T.);
+#418=ORIENTED_EDGE('',*,*,#291,.T.);
+#419=ORIENTED_EDGE('',*,*,#297,.T.);
+#420=ORIENTED_EDGE('',*,*,#298,.T.);
+#421=ORIENTED_EDGE('',*,*,#246,.F.);
+#422=ORIENTED_EDGE('',*,*,#282,.F.);
+#423=ORIENTED_EDGE('',*,*,#277,.F.);
+#424=ORIENTED_EDGE('',*,*,#275,.F.);
+#425=ORIENTED_EDGE('',*,*,#273,.F.);
+#426=ORIENTED_EDGE('',*,*,#287,.F.);
+#427=ORIENTED_EDGE('',*,*,#270,.F.);
+#428=ORIENTED_EDGE('',*,*,#268,.F.);
+#429=ORIENTED_EDGE('',*,*,#306,.F.);
+#430=ORIENTED_EDGE('',*,*,#304,.F.);
+#431=ORIENTED_EDGE('',*,*,#302,.F.);
+#432=ORIENTED_EDGE('',*,*,#300,.F.);
+#433=CYLINDRICAL_SURFACE('',#466,5.);
+#434=CYLINDRICAL_SURFACE('',#478,5.);
+#435=CYLINDRICAL_SURFACE('',#480,5.);
+#436=CYLINDRICAL_SURFACE('',#483,5.);
+#437=CYLINDRICAL_SURFACE('',#495,1.45);
+#438=CYLINDRICAL_SURFACE('',#497,1.45);
+#439=CYLINDRICAL_SURFACE('',#499,1.45);
+#440=CYLINDRICAL_SURFACE('',#501,1.45);
+#441=ADVANCED_FACE('',(#38),#433,.T.);
+#442=ADVANCED_FACE('',(#39,#15,#16,#17,#18),#23,.T.);
+#443=ADVANCED_FACE('',(#40),#24,.T.);
+#444=ADVANCED_FACE('',(#41),#434,.T.);
+#445=ADVANCED_FACE('',(#42),#435,.T.);
+#446=ADVANCED_FACE('',(#43),#25,.T.);
+#447=ADVANCED_FACE('',(#44),#436,.T.);
+#448=ADVANCED_FACE('',(#45),#26,.T.);
+#449=ADVANCED_FACE('',(#46),#27,.F.);
+#450=ADVANCED_FACE('',(#47),#28,.T.);
+#451=ADVANCED_FACE('',(#48),#29,.T.);
+#452=ADVANCED_FACE('',(#49),#30,.T.);
+#453=ADVANCED_FACE('',(#50),#31,.F.);
+#454=ADVANCED_FACE('',(#51),#32,.T.);
+#455=ADVANCED_FACE('',(#52),#33,.T.);
+#456=ADVANCED_FACE('',(#53),#34,.T.);
+#457=ADVANCED_FACE('',(#54),#35,.T.);
+#458=ADVANCED_FACE('',(#55),#437,.F.);
+#459=ADVANCED_FACE('',(#56),#438,.F.);
+#460=ADVANCED_FACE('',(#57),#439,.F.);
+#461=ADVANCED_FACE('',(#58),#440,.F.);
+#462=ADVANCED_FACE('',(#59),#36,.T.);
+#463=ADVANCED_FACE('',(#60,#19,#20,#21,#22),#37,.F.);
+#464=CLOSED_SHELL('',(#441,#442,#443,#444,#445,#446,#447,#448,#449,#450,
+#451,#452,#453,#454,#455,#456,#457,#458,#459,#460,#461,#462,#463));
+#465=AXIS2_PLACEMENT_3D('',#632,#505,#506);
+#466=AXIS2_PLACEMENT_3D('',#633,#507,#508);
+#467=AXIS2_PLACEMENT_3D('',#636,#509,#510);
+#468=AXIS2_PLACEMENT_3D('',#640,#512,#513);
+#469=AXIS2_PLACEMENT_3D('',#642,#515,#516);
+#470=AXIS2_PLACEMENT_3D('',#646,#518,#519);
+#471=AXIS2_PLACEMENT_3D('',#650,#521,#522);
+#472=AXIS2_PLACEMENT_3D('',#654,#524,#525);
+#473=AXIS2_PLACEMENT_3D('',#675,#536,#537);
+#474=AXIS2_PLACEMENT_3D('',#677,#538,#539);
+#475=AXIS2_PLACEMENT_3D('',#679,#540,#541);
+#476=AXIS2_PLACEMENT_3D('',#681,#542,#543);
+#477=AXIS2_PLACEMENT_3D('',#682,#544,#545);
+#478=AXIS2_PLACEMENT_3D('',#686,#548,#549);
+#479=AXIS2_PLACEMENT_3D('',#688,#550,#551);
+#480=AXIS2_PLACEMENT_3D('',#690,#553,#554);
+#481=AXIS2_PLACEMENT_3D('',#694,#556,#557);
+#482=AXIS2_PLACEMENT_3D('',#696,#559,#560);
+#483=AXIS2_PLACEMENT_3D('',#700,#563,#564);
+#484=AXIS2_PLACEMENT_3D('',#702,#565,#566);
+#485=AXIS2_PLACEMENT_3D('',#704,#568,#569);
+#486=AXIS2_PLACEMENT_3D('',#711,#574,#575);
+#487=AXIS2_PLACEMENT_3D('',#715,#578,#579);
+#488=AXIS2_PLACEMENT_3D('',#719,#582,#583);
+#489=AXIS2_PLACEMENT_3D('',#721,#585,#586);
+#490=AXIS2_PLACEMENT_3D('',#725,#589,#590);
+#491=AXIS2_PLACEMENT_3D('',#727,#592,#593);
+#492=AXIS2_PLACEMENT_3D('',#733,#597,#598);
+#493=AXIS2_PLACEMENT_3D('',#737,#601,#602);
+#494=AXIS2_PLACEMENT_3D('',#741,#605,#606);
+#495=AXIS2_PLACEMENT_3D('',#743,#608,#609);
+#496=AXIS2_PLACEMENT_3D('',#746,#611,#612);
+#497=AXIS2_PLACEMENT_3D('',#747,#613,#614);
+#498=AXIS2_PLACEMENT_3D('',#750,#616,#617);
+#499=AXIS2_PLACEMENT_3D('',#751,#618,#619);
+#500=AXIS2_PLACEMENT_3D('',#754,#621,#622);
+#501=AXIS2_PLACEMENT_3D('',#755,#623,#624);
+#502=AXIS2_PLACEMENT_3D('',#758,#626,#627);
+#503=AXIS2_PLACEMENT_3D('',#759,#628,#629);
+#504=AXIS2_PLACEMENT_3D('',#760,#630,#631);
+#505=DIRECTION('axis',(0.,0.,1.));
+#506=DIRECTION('refdir',(1.,0.,0.));
+#507=DIRECTION('center_axis',(0.,0.,1.));
+#508=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#509=DIRECTION('center_axis',(0.,0.,-1.));
+#510=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#511=DIRECTION('',(0.,0.,-1.));
+#512=DIRECTION('center_axis',(0.,0.,1.));
+#513=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#514=DIRECTION('',(0.,0.,1.));
+#515=DIRECTION('center_axis',(0.,0.,1.));
+#516=DIRECTION('ref_axis',(1.,0.,0.));
+#517=DIRECTION('',(0.,1.,0.));
+#518=DIRECTION('center_axis',(0.,0.,-1.));
+#519=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#520=DIRECTION('',(-1.,-4.8472887907141E-17,0.));
+#521=DIRECTION('center_axis',(0.,0.,-1.));
+#522=DIRECTION('ref_axis',(0.707106781186548,-0.707106781186547,0.));
+#523=DIRECTION('',(0.,-1.,0.));
+#524=DIRECTION('center_axis',(0.,0.,-1.));
+#525=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#526=DIRECTION('',(1.,0.,0.));
+#527=DIRECTION('',(0.00211883867751913,0.99999775525881,0.));
+#528=DIRECTION('',(0.99999775525881,-0.00211883867752468,0.));
+#529=DIRECTION('',(1.,0.,0.));
+#530=DIRECTION('',(0.,-1.,0.));
+#531=DIRECTION('',(-1.,-2.89337761429314E-33,0.));
+#532=DIRECTION('',(1.72904223214608E-33,1.,0.));
+#533=DIRECTION('',(1.,0.,0.));
+#534=DIRECTION('',(-0.00211883867752538,-0.99999775525881,0.));
+#535=DIRECTION('',(1.,0.,0.));
+#536=DIRECTION('center_axis',(0.,0.,1.));
+#537=DIRECTION('ref_axis',(1.,0.,0.));
+#538=DIRECTION('center_axis',(0.,0.,1.));
+#539=DIRECTION('ref_axis',(1.,0.,0.));
+#540=DIRECTION('center_axis',(0.,0.,1.));
+#541=DIRECTION('ref_axis',(1.,0.,0.));
+#542=DIRECTION('center_axis',(0.,0.,1.));
+#543=DIRECTION('ref_axis',(1.,0.,0.));
+#544=DIRECTION('center_axis',(-1.,0.,0.));
+#545=DIRECTION('ref_axis',(0.,-1.,0.));
+#546=DIRECTION('',(0.,-1.,0.));
+#547=DIRECTION('',(0.,0.,-1.));
+#548=DIRECTION('center_axis',(0.,0.,1.));
+#549=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#550=DIRECTION('center_axis',(0.,0.,1.));
+#551=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#552=DIRECTION('',(0.,0.,1.));
+#553=DIRECTION('center_axis',(0.,0.,1.));
+#554=DIRECTION('ref_axis',(0.707106781186548,-0.707106781186547,0.));
+#555=DIRECTION('',(0.,0.,-1.));
+#556=DIRECTION('center_axis',(0.,0.,1.));
+#557=DIRECTION('ref_axis',(0.707106781186548,-0.707106781186547,0.));
+#558=DIRECTION('',(0.,0.,1.));
+#559=DIRECTION('center_axis',(1.,0.,0.));
+#560=DIRECTION('ref_axis',(0.,1.,0.));
+#561=DIRECTION('',(0.,1.,0.));
+#562=DIRECTION('',(0.,0.,-1.));
+#563=DIRECTION('center_axis',(0.,0.,1.));
+#564=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#565=DIRECTION('center_axis',(0.,0.,1.));
+#566=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#567=DIRECTION('',(0.,0.,1.));
+#568=DIRECTION('center_axis',(0.,1.,0.));
+#569=DIRECTION('ref_axis',(-1.,0.,0.));
+#570=DIRECTION('',(0.,0.,-1.));
+#571=DIRECTION('',(-1.,0.,0.));
+#572=DIRECTION('',(0.,0.,-1.));
+#573=DIRECTION('',(-1.,0.,0.));
+#574=DIRECTION('center_axis',(-0.99999775525881,0.00211883867752538,0.));
+#575=DIRECTION('ref_axis',(0.00211883867752538,0.99999775525881,0.));
+#576=DIRECTION('',(0.,0.,1.));
+#577=DIRECTION('',(0.00211883867752538,0.99999775525881,0.));
+#578=DIRECTION('center_axis',(-0.99999775525881,0.00211883867751913,0.));
+#579=DIRECTION('ref_axis',(0.,0.,1.));
+#580=DIRECTION('',(0.00211883867752468,0.99999775525881,0.));
+#581=DIRECTION('',(0.,0.,1.));
+#582=DIRECTION('center_axis',(4.8472887907141E-17,-1.,0.));
+#583=DIRECTION('ref_axis',(1.,4.8472887907141E-17,0.));
+#584=DIRECTION('',(1.,4.8472887907141E-17,0.));
+#585=DIRECTION('center_axis',(-0.00211883867752468,-0.99999775525881,0.));
+#586=DIRECTION('ref_axis',(0.,0.,1.));
+#587=DIRECTION('',(0.,0.,-1.));
+#588=DIRECTION('',(-0.99999775525881,0.00211883867752468,0.));
+#589=DIRECTION('center_axis',(0.,0.,-1.));
+#590=DIRECTION('ref_axis',(-1.,0.,0.));
+#591=DIRECTION('',(-1.,0.,0.));
+#592=DIRECTION('center_axis',(-1.,0.,0.));
+#593=DIRECTION('ref_axis',(0.,-1.,0.));
+#594=DIRECTION('',(0.,1.,0.));
+#595=DIRECTION('',(0.,0.,1.));
+#596=DIRECTION('',(0.,0.,1.));
+#597=DIRECTION('center_axis',(-2.89337761429314E-33,1.,0.));
+#598=DIRECTION('ref_axis',(-1.,-2.89337761429314E-33,0.));
+#599=DIRECTION('',(1.,2.89337761429314E-33,0.));
+#600=DIRECTION('',(0.,0.,1.));
+#601=DIRECTION('center_axis',(0.,-1.,0.));
+#602=DIRECTION('ref_axis',(1.,0.,0.));
+#603=DIRECTION('',(0.,0.,1.));
+#604=DIRECTION('',(-1.,0.,0.));
+#605=DIRECTION('center_axis',(1.,-1.72904223214608E-33,0.));
+#606=DIRECTION('ref_axis',(1.72904223214608E-33,1.,0.));
+#607=DIRECTION('',(-1.72904223214608E-33,-1.,0.));
+#608=DIRECTION('center_axis',(0.,0.,1.));
+#609=DIRECTION('ref_axis',(1.,0.,0.));
+#610=DIRECTION('',(0.,0.,-1.));
+#611=DIRECTION('center_axis',(0.,0.,-1.));
+#612=DIRECTION('ref_axis',(1.,0.,0.));
+#613=DIRECTION('center_axis',(0.,0.,1.));
+#614=DIRECTION('ref_axis',(1.,0.,0.));
+#615=DIRECTION('',(0.,0.,-1.));
+#616=DIRECTION('center_axis',(0.,0.,-1.));
+#617=DIRECTION('ref_axis',(1.,0.,0.));
+#618=DIRECTION('center_axis',(0.,0.,1.));
+#619=DIRECTION('ref_axis',(1.,0.,0.));
+#620=DIRECTION('',(0.,0.,-1.));
+#621=DIRECTION('center_axis',(0.,0.,-1.));
+#622=DIRECTION('ref_axis',(1.,0.,0.));
+#623=DIRECTION('center_axis',(0.,0.,1.));
+#624=DIRECTION('ref_axis',(1.,0.,0.));
+#625=DIRECTION('',(0.,0.,-1.));
+#626=DIRECTION('center_axis',(0.,0.,-1.));
+#627=DIRECTION('ref_axis',(1.,0.,0.));
+#628=DIRECTION('center_axis',(0.,0.,1.));
+#629=DIRECTION('ref_axis',(1.,0.,0.));
+#630=DIRECTION('center_axis',(0.,0.,1.));
+#631=DIRECTION('ref_axis',(1.,0.,0.));
+#632=CARTESIAN_POINT('',(0.,0.,0.));
+#633=CARTESIAN_POINT('Origin',(-5.,74.06,0.));
+#634=CARTESIAN_POINT('',(-10.,74.06,18.));
+#635=CARTESIAN_POINT('',(-5.,79.06,18.));
+#636=CARTESIAN_POINT('Origin',(-5.,74.06,18.));
+#637=CARTESIAN_POINT('',(-5.,79.06,0.));
+#638=CARTESIAN_POINT('',(-5.,79.06,0.));
+#639=CARTESIAN_POINT('',(-10.,74.06,0.));
+#640=CARTESIAN_POINT('Origin',(-5.,74.06,0.));
+#641=CARTESIAN_POINT('',(-10.,74.06,0.));
+#642=CARTESIAN_POINT('Origin',(47.26,34.53,18.));
+#643=CARTESIAN_POINT('',(-10.,-5.,18.));
+#644=CARTESIAN_POINT('',(-10.,56.795,18.));
+#645=CARTESIAN_POINT('',(-5.,-10.,18.));
+#646=CARTESIAN_POINT('Origin',(-5.,-5.,18.));
+#647=CARTESIAN_POINT('',(99.52,-10.,18.));
+#648=CARTESIAN_POINT('',(18.63,-10.,18.));
+#649=CARTESIAN_POINT('',(104.52,-5.,18.));
+#650=CARTESIAN_POINT('Origin',(99.52,-5.,18.));
+#651=CARTESIAN_POINT('',(104.52,74.06,18.));
+#652=CARTESIAN_POINT('',(104.52,12.265,18.));
+#653=CARTESIAN_POINT('',(99.52,79.06,18.));
+#654=CARTESIAN_POINT('Origin',(99.52,74.06,18.));
+#655=CARTESIAN_POINT('',(23.4403267770942,79.06,18.));
+#656=CARTESIAN_POINT('',(75.89,79.06,18.));
+#657=CARTESIAN_POINT('',(23.4191598922962,69.0701704256521,18.));
+#658=CARTESIAN_POINT('',(23.3952026224009,57.7634030103233,18.));
+#659=CARTESIAN_POINT('',(28.2191491175385,69.06,18.));
+#660=CARTESIAN_POINT('',(37.7761134846859,69.0397502888038,18.));
+#661=CARTESIAN_POINT('',(94.52,69.06,18.));
+#662=CARTESIAN_POINT('',(94.52,69.06,18.));
+#663=CARTESIAN_POINT('',(94.52,0.,18.));
+#664=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,18.));
+#665=CARTESIAN_POINT('',(0.,0.,18.));
+#666=CARTESIAN_POINT('',(0.,0.,18.));
+#667=CARTESIAN_POINT('',(0.,69.06,18.));
+#668=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,18.));
+#669=CARTESIAN_POINT('',(4.21914911753852,69.06,18.));
+#670=CARTESIAN_POINT('',(94.52,69.06,18.));
+#671=CARTESIAN_POINT('',(4.24033755187631,79.06,18.));
+#672=CARTESIAN_POINT('',(4.15484025360816,38.7090722697651,18.));
+#673=CARTESIAN_POINT('',(75.89,79.06,18.));
+#674=CARTESIAN_POINT('',(98.17,-5.1,18.));
+#675=CARTESIAN_POINT('Origin',(99.62,-5.1,18.));
+#676=CARTESIAN_POINT('',(-6.54999999999999,-5.1,18.));
+#677=CARTESIAN_POINT('Origin',(-5.1,-5.1,18.));
+#678=CARTESIAN_POINT('',(98.17,74.16,18.));
+#679=CARTESIAN_POINT('Origin',(99.62,74.16,18.));
+#680=CARTESIAN_POINT('',(-6.4500000745058,74.16,18.));
+#681=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,18.));
+#682=CARTESIAN_POINT('Origin',(-10.,79.06,0.));
+#683=CARTESIAN_POINT('',(-10.,-5.,0.));
+#684=CARTESIAN_POINT('',(-10.,79.06,0.));
+#685=CARTESIAN_POINT('',(-10.,-5.,0.));
+#686=CARTESIAN_POINT('Origin',(-5.,-5.,0.));
+#687=CARTESIAN_POINT('',(-5.,-10.,0.));
+#688=CARTESIAN_POINT('Origin',(-5.,-5.,0.));
+#689=CARTESIAN_POINT('',(-5.,-10.,0.));
+#690=CARTESIAN_POINT('Origin',(99.52,-5.,0.));
+#691=CARTESIAN_POINT('',(99.52,-10.,0.));
+#692=CARTESIAN_POINT('',(99.52,-10.,0.));
+#693=CARTESIAN_POINT('',(104.52,-5.,0.));
+#694=CARTESIAN_POINT('Origin',(99.52,-5.,0.));
+#695=CARTESIAN_POINT('',(104.52,-5.,0.));
+#696=CARTESIAN_POINT('Origin',(104.52,-10.,0.));
+#697=CARTESIAN_POINT('',(104.52,74.06,0.));
+#698=CARTESIAN_POINT('',(104.52,-10.,0.));
+#699=CARTESIAN_POINT('',(104.52,74.06,0.));
+#700=CARTESIAN_POINT('Origin',(99.52,74.06,0.));
+#701=CARTESIAN_POINT('',(99.52,79.06,0.));
+#702=CARTESIAN_POINT('Origin',(99.52,74.06,0.));
+#703=CARTESIAN_POINT('',(99.52,79.06,0.));
+#704=CARTESIAN_POINT('Origin',(104.52,79.06,0.));
+#705=CARTESIAN_POINT('',(4.24033755187632,79.06,14.));
+#706=CARTESIAN_POINT('',(4.24033755187631,79.06,18.));
+#707=CARTESIAN_POINT('',(23.4403267770944,79.06,14.));
+#708=CARTESIAN_POINT('',(66.3801687759382,79.06,14.));
+#709=CARTESIAN_POINT('',(23.4403267770942,79.06,21.));
+#710=CARTESIAN_POINT('',(104.52,79.06,0.));
+#711=CARTESIAN_POINT('Origin',(4.16350149405484,42.7967931030271,36.));
+#712=CARTESIAN_POINT('',(4.21914911753851,69.06,14.));
+#713=CARTESIAN_POINT('',(4.21914911753851,69.06,18.));
+#714=CARTESIAN_POINT('',(4.24431242958124,80.9359657469501,14.));
+#715=CARTESIAN_POINT('Origin',(23.4443232043387,80.9461361726022,36.));
+#716=CARTESIAN_POINT('',(23.4191598922962,69.0701704256521,14.));
+#717=CARTESIAN_POINT('',(23.4240665968502,71.3859170616409,14.));
+#718=CARTESIAN_POINT('',(23.4191598922962,69.0701704256521,18.));
+#719=CARTESIAN_POINT('Origin',(-10.,-10.,0.));
+#720=CARTESIAN_POINT('',(-10.,-10.,0.));
+#721=CARTESIAN_POINT('Origin',(28.2191491175385,69.06,14.));
+#722=CARTESIAN_POINT('',(28.2191491175385,69.06,14.));
+#723=CARTESIAN_POINT('',(28.2191491175385,69.06,18.));
+#724=CARTESIAN_POINT('',(22.2192029911457,69.072712946453,14.));
+#725=CARTESIAN_POINT('Origin',(16.203906961818,61.8409534179332,14.));
+#726=CARTESIAN_POINT('',(8.10195348090902,69.06,14.));
+#727=CARTESIAN_POINT('Origin',(94.52,69.06,0.));
+#728=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,4.));
+#729=CARTESIAN_POINT('',(94.52,69.06,4.));
+#730=CARTESIAN_POINT('',(94.52,51.795,4.));
+#731=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,0.));
+#732=CARTESIAN_POINT('',(94.52,69.06,0.));
+#733=CARTESIAN_POINT('Origin',(94.52,2.73482052102987E-31,0.));
+#734=CARTESIAN_POINT('',(0.,0.,4.));
+#735=CARTESIAN_POINT('',(70.89,0.,4.));
+#736=CARTESIAN_POINT('',(0.,0.,0.));
+#737=CARTESIAN_POINT('Origin',(0.,69.06,0.));
+#738=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,4.));
+#739=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,0.));
+#740=CARTESIAN_POINT('',(23.63,69.06,4.));
+#741=CARTESIAN_POINT('Origin',(0.,0.,0.));
+#742=CARTESIAN_POINT('',(0.,17.265,4.));
+#743=CARTESIAN_POINT('Origin',(99.62,-5.1,0.));
+#744=CARTESIAN_POINT('',(98.17,-5.1,0.));
+#745=CARTESIAN_POINT('',(98.17,-5.1,0.));
+#746=CARTESIAN_POINT('Origin',(99.62,-5.1,0.));
+#747=CARTESIAN_POINT('Origin',(-5.1,-5.1,0.));
+#748=CARTESIAN_POINT('',(-6.55,-5.1,0.));
+#749=CARTESIAN_POINT('',(-6.55,-5.1,0.));
+#750=CARTESIAN_POINT('Origin',(-5.1,-5.1,0.));
+#751=CARTESIAN_POINT('Origin',(99.62,74.16,0.));
+#752=CARTESIAN_POINT('',(98.17,74.16,0.));
+#753=CARTESIAN_POINT('',(98.17,74.16,0.));
+#754=CARTESIAN_POINT('Origin',(99.62,74.16,0.));
+#755=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,0.));
+#756=CARTESIAN_POINT('',(-6.45000007450581,74.16,0.));
+#757=CARTESIAN_POINT('',(-6.45000007450581,74.16,0.));
+#758=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,0.));
+#759=CARTESIAN_POINT('Origin',(47.26,34.53,4.));
+#760=CARTESIAN_POINT('Origin',(47.26,34.53,0.));
+#761=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#765,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#762=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#765,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#763=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#761))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#765,#766,#767))
+REPRESENTATION_CONTEXT('','3D')
+);
+#764=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#762))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#765,#766,#767))
+REPRESENTATION_CONTEXT('','3D')
+);
+#765=(
+LENGTH_UNIT()
+NAMED_UNIT(*)
+SI_UNIT(.MILLI.,.METRE.)
+);
+#766=(
+NAMED_UNIT(*)
+PLANE_ANGLE_UNIT()
+SI_UNIT($,.RADIAN.)
+);
+#767=(
+NAMED_UNIT(*)
+SI_UNIT($,.STERADIAN.)
+SOLID_ANGLE_UNIT()
+);
+#768=SHAPE_DEFINITION_REPRESENTATION(#769,#770);
+#769=PRODUCT_DEFINITION_SHAPE('',$,#772);
+#770=SHAPE_REPRESENTATION('',(#465),#763);
+#771=PRODUCT_DEFINITION_CONTEXT('part definition',#776,'design');
+#772=PRODUCT_DEFINITION('hackpad','hackpad v5',#773,#771);
+#773=PRODUCT_DEFINITION_FORMATION('',$,#778);
+#774=PRODUCT_RELATED_PRODUCT_CATEGORY('hackpad v5','hackpad v5',(#778));
+#775=APPLICATION_PROTOCOL_DEFINITION('international standard',
+'automotive_design',2009,#776);
+#776=APPLICATION_CONTEXT(
+'Core Data for Automotive Mechanical Design Process');
+#777=PRODUCT_CONTEXT('part definition',#776,'mechanical');
+#778=PRODUCT('hackpad','hackpad v5',$,(#777));
+#779=PRESENTATION_STYLE_ASSIGNMENT((#780));
+#780=SURFACE_STYLE_USAGE(.BOTH.,#781);
+#781=SURFACE_SIDE_STYLE('',(#782));
+#782=SURFACE_STYLE_FILL_AREA(#783);
+#783=FILL_AREA_STYLE('Steel - Satin',(#784));
+#784=FILL_AREA_STYLE_COLOUR('Steel - Satin',#785);
+#785=COLOUR_RGB('Steel - Satin',0.627450980392157,0.627450980392157,0.627450980392157);
+ENDSEC;
+END-ISO-10303-21;
diff --git a/hackpads/blipyboard/cad/plate.step b/hackpads/blipyboard/cad/plate.step
new file mode 100644
index 0000000000..3a561e98ce
--- /dev/null
+++ b/hackpads/blipyboard/cad/plate.step
@@ -0,0 +1,3298 @@
+ISO-10303-21;
+HEADER;
+/* Generated by software containing ST-Developer
+ * from STEP Tools, Inc. (www.steptools.com)
+ */
+
+FILE_DESCRIPTION(
+/* description */ (''),
+/* implementation_level */ '2;1');
+
+FILE_NAME(
+/* name */ 'plate.step',
+/* time_stamp */ '2025-06-27T19:17:16-07:00',
+/* author */ (''),
+/* organization */ (''),
+/* preprocessor_version */ 'ST-DEVELOPER v20.1',
+/* originating_system */ 'Autodesk Translation Framework v14.10.0.0',
+/* authorisation */ '');
+
+FILE_SCHEMA (('AUTOMOTIVE_DESIGN { 1 0 10303 214 3 1 1 }'));
+ENDSEC;
+
+DATA;
+#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#13),#3219);
+#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#3225,#12);
+#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#14),#3218);
+#13=STYLED_ITEM('',(#3234),#14);
+#14=MANIFOLD_SOLID_BREP('plate',#1923);
+#15=FACE_BOUND('',#190,.T.);
+#16=FACE_BOUND('',#191,.T.);
+#17=FACE_BOUND('',#192,.T.);
+#18=FACE_BOUND('',#193,.T.);
+#19=FACE_BOUND('',#194,.T.);
+#20=FACE_BOUND('',#195,.T.);
+#21=FACE_BOUND('',#196,.T.);
+#22=FACE_BOUND('',#197,.T.);
+#23=FACE_BOUND('',#198,.T.);
+#24=FACE_BOUND('',#199,.T.);
+#25=FACE_BOUND('',#200,.T.);
+#26=FACE_BOUND('',#201,.T.);
+#27=FACE_BOUND('',#202,.T.);
+#28=FACE_BOUND('',#203,.T.);
+#29=FACE_BOUND('',#295,.T.);
+#30=FACE_BOUND('',#296,.T.);
+#31=FACE_BOUND('',#297,.T.);
+#32=FACE_BOUND('',#298,.T.);
+#33=FACE_BOUND('',#299,.T.);
+#34=FACE_BOUND('',#300,.T.);
+#35=FACE_BOUND('',#301,.T.);
+#36=FACE_BOUND('',#302,.T.);
+#37=FACE_BOUND('',#303,.T.);
+#38=FACE_BOUND('',#304,.T.);
+#39=FACE_BOUND('',#305,.T.);
+#40=FACE_BOUND('',#306,.T.);
+#41=FACE_BOUND('',#307,.T.);
+#42=FACE_BOUND('',#308,.T.);
+#43=PLANE('',#1928);
+#44=PLANE('',#1929);
+#45=PLANE('',#1975);
+#46=PLANE('',#1980);
+#47=PLANE('',#1991);
+#48=PLANE('',#1994);
+#49=PLANE('',#1997);
+#50=PLANE('',#2000);
+#51=PLANE('',#2003);
+#52=PLANE('',#2006);
+#53=PLANE('',#2009);
+#54=PLANE('',#2012);
+#55=PLANE('',#2015);
+#56=PLANE('',#2018);
+#57=PLANE('',#2021);
+#58=PLANE('',#2024);
+#59=PLANE('',#2027);
+#60=PLANE('',#2030);
+#61=PLANE('',#2033);
+#62=PLANE('',#2036);
+#63=PLANE('',#2039);
+#64=PLANE('',#2042);
+#65=PLANE('',#2045);
+#66=PLANE('',#2048);
+#67=PLANE('',#2051);
+#68=PLANE('',#2054);
+#69=PLANE('',#2057);
+#70=PLANE('',#2060);
+#71=PLANE('',#2063);
+#72=PLANE('',#2066);
+#73=PLANE('',#2069);
+#74=PLANE('',#2072);
+#75=PLANE('',#2075);
+#76=PLANE('',#2078);
+#77=PLANE('',#2081);
+#78=PLANE('',#2084);
+#79=PLANE('',#2087);
+#80=PLANE('',#2090);
+#81=PLANE('',#2093);
+#82=PLANE('',#2096);
+#83=PLANE('',#2097);
+#84=PLANE('',#2098);
+#85=PLANE('',#2099);
+#86=PLANE('',#2100);
+#87=PLANE('',#2101);
+#88=PLANE('',#2102);
+#89=PLANE('',#2103);
+#90=PLANE('',#2104);
+#91=PLANE('',#2105);
+#92=PLANE('',#2106);
+#93=FACE_OUTER_BOUND('',#187,.T.);
+#94=FACE_OUTER_BOUND('',#188,.T.);
+#95=FACE_OUTER_BOUND('',#189,.T.);
+#96=FACE_OUTER_BOUND('',#204,.T.);
+#97=FACE_OUTER_BOUND('',#205,.T.);
+#98=FACE_OUTER_BOUND('',#206,.T.);
+#99=FACE_OUTER_BOUND('',#207,.T.);
+#100=FACE_OUTER_BOUND('',#208,.T.);
+#101=FACE_OUTER_BOUND('',#209,.T.);
+#102=FACE_OUTER_BOUND('',#210,.T.);
+#103=FACE_OUTER_BOUND('',#211,.T.);
+#104=FACE_OUTER_BOUND('',#212,.T.);
+#105=FACE_OUTER_BOUND('',#213,.T.);
+#106=FACE_OUTER_BOUND('',#214,.T.);
+#107=FACE_OUTER_BOUND('',#215,.T.);
+#108=FACE_OUTER_BOUND('',#216,.T.);
+#109=FACE_OUTER_BOUND('',#217,.T.);
+#110=FACE_OUTER_BOUND('',#218,.T.);
+#111=FACE_OUTER_BOUND('',#219,.T.);
+#112=FACE_OUTER_BOUND('',#220,.T.);
+#113=FACE_OUTER_BOUND('',#221,.T.);
+#114=FACE_OUTER_BOUND('',#222,.T.);
+#115=FACE_OUTER_BOUND('',#223,.T.);
+#116=FACE_OUTER_BOUND('',#224,.T.);
+#117=FACE_OUTER_BOUND('',#225,.T.);
+#118=FACE_OUTER_BOUND('',#226,.T.);
+#119=FACE_OUTER_BOUND('',#227,.T.);
+#120=FACE_OUTER_BOUND('',#228,.T.);
+#121=FACE_OUTER_BOUND('',#229,.T.);
+#122=FACE_OUTER_BOUND('',#230,.T.);
+#123=FACE_OUTER_BOUND('',#231,.T.);
+#124=FACE_OUTER_BOUND('',#232,.T.);
+#125=FACE_OUTER_BOUND('',#233,.T.);
+#126=FACE_OUTER_BOUND('',#234,.T.);
+#127=FACE_OUTER_BOUND('',#235,.T.);
+#128=FACE_OUTER_BOUND('',#236,.T.);
+#129=FACE_OUTER_BOUND('',#237,.T.);
+#130=FACE_OUTER_BOUND('',#238,.T.);
+#131=FACE_OUTER_BOUND('',#239,.T.);
+#132=FACE_OUTER_BOUND('',#240,.T.);
+#133=FACE_OUTER_BOUND('',#241,.T.);
+#134=FACE_OUTER_BOUND('',#242,.T.);
+#135=FACE_OUTER_BOUND('',#243,.T.);
+#136=FACE_OUTER_BOUND('',#244,.T.);
+#137=FACE_OUTER_BOUND('',#245,.T.);
+#138=FACE_OUTER_BOUND('',#246,.T.);
+#139=FACE_OUTER_BOUND('',#247,.T.);
+#140=FACE_OUTER_BOUND('',#248,.T.);
+#141=FACE_OUTER_BOUND('',#249,.T.);
+#142=FACE_OUTER_BOUND('',#250,.T.);
+#143=FACE_OUTER_BOUND('',#251,.T.);
+#144=FACE_OUTER_BOUND('',#252,.T.);
+#145=FACE_OUTER_BOUND('',#253,.T.);
+#146=FACE_OUTER_BOUND('',#254,.T.);
+#147=FACE_OUTER_BOUND('',#255,.T.);
+#148=FACE_OUTER_BOUND('',#256,.T.);
+#149=FACE_OUTER_BOUND('',#257,.T.);
+#150=FACE_OUTER_BOUND('',#258,.T.);
+#151=FACE_OUTER_BOUND('',#259,.T.);
+#152=FACE_OUTER_BOUND('',#260,.T.);
+#153=FACE_OUTER_BOUND('',#261,.T.);
+#154=FACE_OUTER_BOUND('',#262,.T.);
+#155=FACE_OUTER_BOUND('',#263,.T.);
+#156=FACE_OUTER_BOUND('',#264,.T.);
+#157=FACE_OUTER_BOUND('',#265,.T.);
+#158=FACE_OUTER_BOUND('',#266,.T.);
+#159=FACE_OUTER_BOUND('',#267,.T.);
+#160=FACE_OUTER_BOUND('',#268,.T.);
+#161=FACE_OUTER_BOUND('',#269,.T.);
+#162=FACE_OUTER_BOUND('',#270,.T.);
+#163=FACE_OUTER_BOUND('',#271,.T.);
+#164=FACE_OUTER_BOUND('',#272,.T.);
+#165=FACE_OUTER_BOUND('',#273,.T.);
+#166=FACE_OUTER_BOUND('',#274,.T.);
+#167=FACE_OUTER_BOUND('',#275,.T.);
+#168=FACE_OUTER_BOUND('',#276,.T.);
+#169=FACE_OUTER_BOUND('',#277,.T.);
+#170=FACE_OUTER_BOUND('',#278,.T.);
+#171=FACE_OUTER_BOUND('',#279,.T.);
+#172=FACE_OUTER_BOUND('',#280,.T.);
+#173=FACE_OUTER_BOUND('',#281,.T.);
+#174=FACE_OUTER_BOUND('',#282,.T.);
+#175=FACE_OUTER_BOUND('',#283,.T.);
+#176=FACE_OUTER_BOUND('',#284,.T.);
+#177=FACE_OUTER_BOUND('',#285,.T.);
+#178=FACE_OUTER_BOUND('',#286,.T.);
+#179=FACE_OUTER_BOUND('',#287,.T.);
+#180=FACE_OUTER_BOUND('',#288,.T.);
+#181=FACE_OUTER_BOUND('',#289,.T.);
+#182=FACE_OUTER_BOUND('',#290,.T.);
+#183=FACE_OUTER_BOUND('',#291,.T.);
+#184=FACE_OUTER_BOUND('',#292,.T.);
+#185=FACE_OUTER_BOUND('',#293,.T.);
+#186=FACE_OUTER_BOUND('',#294,.T.);
+#187=EDGE_LOOP('',(#1233,#1234,#1235,#1236));
+#188=EDGE_LOOP('',(#1237,#1238,#1239,#1240));
+#189=EDGE_LOOP('',(#1241,#1242,#1243,#1244,#1245,#1246,#1247,#1248,#1249,
+#1250,#1251,#1252));
+#190=EDGE_LOOP('',(#1253,#1254,#1255,#1256));
+#191=EDGE_LOOP('',(#1257,#1258,#1259,#1260,#1261,#1262,#1263,#1264));
+#192=EDGE_LOOP('',(#1265,#1266,#1267,#1268,#1269,#1270,#1271,#1272));
+#193=EDGE_LOOP('',(#1273,#1274,#1275,#1276,#1277,#1278,#1279,#1280));
+#194=EDGE_LOOP('',(#1281,#1282,#1283,#1284,#1285,#1286,#1287,#1288));
+#195=EDGE_LOOP('',(#1289,#1290,#1291,#1292,#1293,#1294,#1295,#1296));
+#196=EDGE_LOOP('',(#1297,#1298,#1299,#1300,#1301,#1302,#1303,#1304));
+#197=EDGE_LOOP('',(#1305,#1306,#1307,#1308,#1309,#1310,#1311,#1312));
+#198=EDGE_LOOP('',(#1313,#1314,#1315,#1316,#1317,#1318,#1319,#1320));
+#199=EDGE_LOOP('',(#1321,#1322,#1323,#1324,#1325,#1326,#1327,#1328));
+#200=EDGE_LOOP('',(#1329));
+#201=EDGE_LOOP('',(#1330));
+#202=EDGE_LOOP('',(#1331));
+#203=EDGE_LOOP('',(#1332));
+#204=EDGE_LOOP('',(#1333,#1334,#1335,#1336));
+#205=EDGE_LOOP('',(#1337,#1338,#1339,#1340));
+#206=EDGE_LOOP('',(#1341,#1342,#1343,#1344));
+#207=EDGE_LOOP('',(#1345,#1346,#1347,#1348));
+#208=EDGE_LOOP('',(#1349,#1350,#1351,#1352));
+#209=EDGE_LOOP('',(#1353,#1354,#1355,#1356));
+#210=EDGE_LOOP('',(#1357,#1358,#1359,#1360));
+#211=EDGE_LOOP('',(#1361,#1362,#1363,#1364));
+#212=EDGE_LOOP('',(#1365,#1366,#1367,#1368));
+#213=EDGE_LOOP('',(#1369,#1370,#1371,#1372));
+#214=EDGE_LOOP('',(#1373,#1374,#1375,#1376));
+#215=EDGE_LOOP('',(#1377,#1378,#1379,#1380));
+#216=EDGE_LOOP('',(#1381,#1382,#1383,#1384));
+#217=EDGE_LOOP('',(#1385,#1386,#1387,#1388));
+#218=EDGE_LOOP('',(#1389,#1390,#1391,#1392));
+#219=EDGE_LOOP('',(#1393,#1394,#1395,#1396));
+#220=EDGE_LOOP('',(#1397,#1398,#1399,#1400));
+#221=EDGE_LOOP('',(#1401,#1402,#1403,#1404));
+#222=EDGE_LOOP('',(#1405,#1406,#1407,#1408));
+#223=EDGE_LOOP('',(#1409,#1410,#1411,#1412));
+#224=EDGE_LOOP('',(#1413,#1414,#1415,#1416));
+#225=EDGE_LOOP('',(#1417,#1418,#1419,#1420));
+#226=EDGE_LOOP('',(#1421,#1422,#1423,#1424));
+#227=EDGE_LOOP('',(#1425,#1426,#1427,#1428));
+#228=EDGE_LOOP('',(#1429,#1430,#1431,#1432));
+#229=EDGE_LOOP('',(#1433,#1434,#1435,#1436));
+#230=EDGE_LOOP('',(#1437,#1438,#1439,#1440));
+#231=EDGE_LOOP('',(#1441,#1442,#1443,#1444));
+#232=EDGE_LOOP('',(#1445,#1446,#1447,#1448));
+#233=EDGE_LOOP('',(#1449,#1450,#1451,#1452));
+#234=EDGE_LOOP('',(#1453,#1454,#1455,#1456));
+#235=EDGE_LOOP('',(#1457,#1458,#1459,#1460));
+#236=EDGE_LOOP('',(#1461,#1462,#1463,#1464));
+#237=EDGE_LOOP('',(#1465,#1466,#1467,#1468));
+#238=EDGE_LOOP('',(#1469,#1470,#1471,#1472));
+#239=EDGE_LOOP('',(#1473,#1474,#1475,#1476));
+#240=EDGE_LOOP('',(#1477,#1478,#1479,#1480));
+#241=EDGE_LOOP('',(#1481,#1482,#1483,#1484));
+#242=EDGE_LOOP('',(#1485,#1486,#1487,#1488));
+#243=EDGE_LOOP('',(#1489,#1490,#1491,#1492));
+#244=EDGE_LOOP('',(#1493,#1494,#1495,#1496));
+#245=EDGE_LOOP('',(#1497,#1498,#1499,#1500));
+#246=EDGE_LOOP('',(#1501,#1502,#1503,#1504));
+#247=EDGE_LOOP('',(#1505,#1506,#1507,#1508));
+#248=EDGE_LOOP('',(#1509,#1510,#1511,#1512));
+#249=EDGE_LOOP('',(#1513,#1514,#1515,#1516));
+#250=EDGE_LOOP('',(#1517,#1518,#1519,#1520));
+#251=EDGE_LOOP('',(#1521,#1522,#1523,#1524));
+#252=EDGE_LOOP('',(#1525,#1526,#1527,#1528));
+#253=EDGE_LOOP('',(#1529,#1530,#1531,#1532));
+#254=EDGE_LOOP('',(#1533,#1534,#1535,#1536));
+#255=EDGE_LOOP('',(#1537,#1538,#1539,#1540));
+#256=EDGE_LOOP('',(#1541,#1542,#1543,#1544));
+#257=EDGE_LOOP('',(#1545,#1546,#1547,#1548));
+#258=EDGE_LOOP('',(#1549,#1550,#1551,#1552));
+#259=EDGE_LOOP('',(#1553,#1554,#1555,#1556));
+#260=EDGE_LOOP('',(#1557,#1558,#1559,#1560));
+#261=EDGE_LOOP('',(#1561,#1562,#1563,#1564));
+#262=EDGE_LOOP('',(#1565,#1566,#1567,#1568));
+#263=EDGE_LOOP('',(#1569,#1570,#1571,#1572));
+#264=EDGE_LOOP('',(#1573,#1574,#1575,#1576));
+#265=EDGE_LOOP('',(#1577,#1578,#1579,#1580));
+#266=EDGE_LOOP('',(#1581,#1582,#1583,#1584));
+#267=EDGE_LOOP('',(#1585,#1586,#1587,#1588));
+#268=EDGE_LOOP('',(#1589,#1590,#1591,#1592));
+#269=EDGE_LOOP('',(#1593,#1594,#1595,#1596));
+#270=EDGE_LOOP('',(#1597,#1598,#1599,#1600));
+#271=EDGE_LOOP('',(#1601,#1602,#1603,#1604));
+#272=EDGE_LOOP('',(#1605,#1606,#1607,#1608));
+#273=EDGE_LOOP('',(#1609,#1610,#1611,#1612));
+#274=EDGE_LOOP('',(#1613,#1614,#1615,#1616));
+#275=EDGE_LOOP('',(#1617,#1618,#1619,#1620));
+#276=EDGE_LOOP('',(#1621,#1622,#1623,#1624));
+#277=EDGE_LOOP('',(#1625,#1626,#1627,#1628));
+#278=EDGE_LOOP('',(#1629,#1630,#1631,#1632));
+#279=EDGE_LOOP('',(#1633,#1634,#1635,#1636));
+#280=EDGE_LOOP('',(#1637,#1638,#1639,#1640));
+#281=EDGE_LOOP('',(#1641,#1642,#1643,#1644));
+#282=EDGE_LOOP('',(#1645,#1646,#1647,#1648));
+#283=EDGE_LOOP('',(#1649,#1650,#1651,#1652));
+#284=EDGE_LOOP('',(#1653,#1654,#1655,#1656));
+#285=EDGE_LOOP('',(#1657,#1658,#1659,#1660));
+#286=EDGE_LOOP('',(#1661,#1662,#1663,#1664));
+#287=EDGE_LOOP('',(#1665,#1666,#1667,#1668));
+#288=EDGE_LOOP('',(#1669,#1670,#1671,#1672));
+#289=EDGE_LOOP('',(#1673,#1674,#1675,#1676));
+#290=EDGE_LOOP('',(#1677,#1678,#1679,#1680));
+#291=EDGE_LOOP('',(#1681,#1682,#1683,#1684));
+#292=EDGE_LOOP('',(#1685,#1686,#1687,#1688));
+#293=EDGE_LOOP('',(#1689,#1690,#1691,#1692));
+#294=EDGE_LOOP('',(#1693,#1694,#1695,#1696,#1697,#1698,#1699,#1700,#1701,
+#1702,#1703,#1704));
+#295=EDGE_LOOP('',(#1705,#1706,#1707,#1708));
+#296=EDGE_LOOP('',(#1709,#1710,#1711,#1712,#1713,#1714,#1715,#1716));
+#297=EDGE_LOOP('',(#1717,#1718,#1719,#1720,#1721,#1722,#1723,#1724));
+#298=EDGE_LOOP('',(#1725,#1726,#1727,#1728,#1729,#1730,#1731,#1732));
+#299=EDGE_LOOP('',(#1733,#1734,#1735,#1736,#1737,#1738,#1739,#1740));
+#300=EDGE_LOOP('',(#1741,#1742,#1743,#1744,#1745,#1746,#1747,#1748));
+#301=EDGE_LOOP('',(#1749,#1750,#1751,#1752,#1753,#1754,#1755,#1756));
+#302=EDGE_LOOP('',(#1757,#1758,#1759,#1760,#1761,#1762,#1763,#1764));
+#303=EDGE_LOOP('',(#1765,#1766,#1767,#1768,#1769,#1770,#1771,#1772));
+#304=EDGE_LOOP('',(#1773,#1774,#1775,#1776,#1777,#1778,#1779,#1780));
+#305=EDGE_LOOP('',(#1781));
+#306=EDGE_LOOP('',(#1782));
+#307=EDGE_LOOP('',(#1783));
+#308=EDGE_LOOP('',(#1784));
+#309=LINE('',#2667,#497);
+#310=LINE('',#2670,#498);
+#311=LINE('',#2673,#499);
+#312=LINE('',#2675,#500);
+#313=LINE('',#2676,#501);
+#314=LINE('',#2679,#502);
+#315=LINE('',#2683,#503);
+#316=LINE('',#2687,#504);
+#317=LINE('',#2691,#505);
+#318=LINE('',#2693,#506);
+#319=LINE('',#2695,#507);
+#320=LINE('',#2696,#508);
+#321=LINE('',#2699,#509);
+#322=LINE('',#2701,#510);
+#323=LINE('',#2703,#511);
+#324=LINE('',#2704,#512);
+#325=LINE('',#2707,#513);
+#326=LINE('',#2711,#514);
+#327=LINE('',#2715,#515);
+#328=LINE('',#2719,#516);
+#329=LINE('',#2723,#517);
+#330=LINE('',#2727,#518);
+#331=LINE('',#2731,#519);
+#332=LINE('',#2735,#520);
+#333=LINE('',#2739,#521);
+#334=LINE('',#2743,#522);
+#335=LINE('',#2747,#523);
+#336=LINE('',#2751,#524);
+#337=LINE('',#2755,#525);
+#338=LINE('',#2759,#526);
+#339=LINE('',#2763,#527);
+#340=LINE('',#2767,#528);
+#341=LINE('',#2771,#529);
+#342=LINE('',#2775,#530);
+#343=LINE('',#2779,#531);
+#344=LINE('',#2783,#532);
+#345=LINE('',#2787,#533);
+#346=LINE('',#2791,#534);
+#347=LINE('',#2795,#535);
+#348=LINE('',#2799,#536);
+#349=LINE('',#2803,#537);
+#350=LINE('',#2807,#538);
+#351=LINE('',#2811,#539);
+#352=LINE('',#2815,#540);
+#353=LINE('',#2819,#541);
+#354=LINE('',#2823,#542);
+#355=LINE('',#2827,#543);
+#356=LINE('',#2831,#544);
+#357=LINE('',#2835,#545);
+#358=LINE('',#2839,#546);
+#359=LINE('',#2843,#547);
+#360=LINE('',#2847,#548);
+#361=LINE('',#2861,#549);
+#362=LINE('',#2862,#550);
+#363=LINE('',#2865,#551);
+#364=LINE('',#2866,#552);
+#365=LINE('',#2870,#553);
+#366=LINE('',#2875,#554);
+#367=LINE('',#2876,#555);
+#368=LINE('',#2879,#556);
+#369=LINE('',#2880,#557);
+#370=LINE('',#2884,#558);
+#371=LINE('',#2888,#559);
+#372=LINE('',#2892,#560);
+#373=LINE('',#2896,#561);
+#374=LINE('',#2899,#562);
+#375=LINE('',#2902,#563);
+#376=LINE('',#2905,#564);
+#377=LINE('',#2906,#565);
+#378=LINE('',#2910,#566);
+#379=LINE('',#2913,#567);
+#380=LINE('',#2914,#568);
+#381=LINE('',#2918,#569);
+#382=LINE('',#2921,#570);
+#383=LINE('',#2922,#571);
+#384=LINE('',#2926,#572);
+#385=LINE('',#2928,#573);
+#386=LINE('',#2931,#574);
+#387=LINE('',#2934,#575);
+#388=LINE('',#2937,#576);
+#389=LINE('',#2938,#577);
+#390=LINE('',#2942,#578);
+#391=LINE('',#2945,#579);
+#392=LINE('',#2946,#580);
+#393=LINE('',#2950,#581);
+#394=LINE('',#2953,#582);
+#395=LINE('',#2954,#583);
+#396=LINE('',#2958,#584);
+#397=LINE('',#2960,#585);
+#398=LINE('',#2963,#586);
+#399=LINE('',#2966,#587);
+#400=LINE('',#2969,#588);
+#401=LINE('',#2970,#589);
+#402=LINE('',#2974,#590);
+#403=LINE('',#2977,#591);
+#404=LINE('',#2978,#592);
+#405=LINE('',#2982,#593);
+#406=LINE('',#2985,#594);
+#407=LINE('',#2986,#595);
+#408=LINE('',#2990,#596);
+#409=LINE('',#2992,#597);
+#410=LINE('',#2995,#598);
+#411=LINE('',#2998,#599);
+#412=LINE('',#3001,#600);
+#413=LINE('',#3002,#601);
+#414=LINE('',#3006,#602);
+#415=LINE('',#3009,#603);
+#416=LINE('',#3010,#604);
+#417=LINE('',#3014,#605);
+#418=LINE('',#3017,#606);
+#419=LINE('',#3018,#607);
+#420=LINE('',#3022,#608);
+#421=LINE('',#3024,#609);
+#422=LINE('',#3027,#610);
+#423=LINE('',#3030,#611);
+#424=LINE('',#3033,#612);
+#425=LINE('',#3034,#613);
+#426=LINE('',#3038,#614);
+#427=LINE('',#3041,#615);
+#428=LINE('',#3042,#616);
+#429=LINE('',#3046,#617);
+#430=LINE('',#3049,#618);
+#431=LINE('',#3050,#619);
+#432=LINE('',#3054,#620);
+#433=LINE('',#3056,#621);
+#434=LINE('',#3059,#622);
+#435=LINE('',#3062,#623);
+#436=LINE('',#3065,#624);
+#437=LINE('',#3066,#625);
+#438=LINE('',#3070,#626);
+#439=LINE('',#3073,#627);
+#440=LINE('',#3074,#628);
+#441=LINE('',#3078,#629);
+#442=LINE('',#3081,#630);
+#443=LINE('',#3082,#631);
+#444=LINE('',#3086,#632);
+#445=LINE('',#3088,#633);
+#446=LINE('',#3091,#634);
+#447=LINE('',#3094,#635);
+#448=LINE('',#3097,#636);
+#449=LINE('',#3098,#637);
+#450=LINE('',#3102,#638);
+#451=LINE('',#3105,#639);
+#452=LINE('',#3106,#640);
+#453=LINE('',#3110,#641);
+#454=LINE('',#3113,#642);
+#455=LINE('',#3114,#643);
+#456=LINE('',#3118,#644);
+#457=LINE('',#3120,#645);
+#458=LINE('',#3123,#646);
+#459=LINE('',#3126,#647);
+#460=LINE('',#3129,#648);
+#461=LINE('',#3130,#649);
+#462=LINE('',#3134,#650);
+#463=LINE('',#3137,#651);
+#464=LINE('',#3138,#652);
+#465=LINE('',#3142,#653);
+#466=LINE('',#3145,#654);
+#467=LINE('',#3146,#655);
+#468=LINE('',#3150,#656);
+#469=LINE('',#3152,#657);
+#470=LINE('',#3155,#658);
+#471=LINE('',#3158,#659);
+#472=LINE('',#3161,#660);
+#473=LINE('',#3162,#661);
+#474=LINE('',#3166,#662);
+#475=LINE('',#3169,#663);
+#476=LINE('',#3170,#664);
+#477=LINE('',#3174,#665);
+#478=LINE('',#3177,#666);
+#479=LINE('',#3178,#667);
+#480=LINE('',#3182,#668);
+#481=LINE('',#3184,#669);
+#482=LINE('',#3187,#670);
+#483=LINE('',#3189,#671);
+#484=LINE('',#3190,#672);
+#485=LINE('',#3193,#673);
+#486=LINE('',#3194,#674);
+#487=LINE('',#3197,#675);
+#488=LINE('',#3198,#676);
+#489=LINE('',#3200,#677);
+#490=LINE('',#3203,#678);
+#491=LINE('',#3205,#679);
+#492=LINE('',#3206,#680);
+#493=LINE('',#3208,#681);
+#494=LINE('',#3210,#682);
+#495=LINE('',#3212,#683);
+#496=LINE('',#3214,#684);
+#497=VECTOR('',#2113,10.);
+#498=VECTOR('',#2116,10.);
+#499=VECTOR('',#2119,10.);
+#500=VECTOR('',#2120,10.);
+#501=VECTOR('',#2121,10.);
+#502=VECTOR('',#2124,10.);
+#503=VECTOR('',#2127,10.);
+#504=VECTOR('',#2130,10.);
+#505=VECTOR('',#2133,10.);
+#506=VECTOR('',#2134,10.);
+#507=VECTOR('',#2135,10.);
+#508=VECTOR('',#2136,10.);
+#509=VECTOR('',#2137,10.);
+#510=VECTOR('',#2138,10.);
+#511=VECTOR('',#2139,10.);
+#512=VECTOR('',#2140,10.);
+#513=VECTOR('',#2141,10.);
+#514=VECTOR('',#2144,10.);
+#515=VECTOR('',#2147,10.);
+#516=VECTOR('',#2150,10.);
+#517=VECTOR('',#2153,10.);
+#518=VECTOR('',#2156,10.);
+#519=VECTOR('',#2159,10.);
+#520=VECTOR('',#2162,10.);
+#521=VECTOR('',#2165,10.);
+#522=VECTOR('',#2168,10.);
+#523=VECTOR('',#2171,10.);
+#524=VECTOR('',#2174,10.);
+#525=VECTOR('',#2177,10.);
+#526=VECTOR('',#2180,10.);
+#527=VECTOR('',#2183,10.);
+#528=VECTOR('',#2186,10.);
+#529=VECTOR('',#2189,10.);
+#530=VECTOR('',#2192,10.);
+#531=VECTOR('',#2195,10.);
+#532=VECTOR('',#2198,10.);
+#533=VECTOR('',#2201,10.);
+#534=VECTOR('',#2204,10.);
+#535=VECTOR('',#2207,10.);
+#536=VECTOR('',#2210,10.);
+#537=VECTOR('',#2213,10.);
+#538=VECTOR('',#2216,10.);
+#539=VECTOR('',#2219,10.);
+#540=VECTOR('',#2222,10.);
+#541=VECTOR('',#2225,10.);
+#542=VECTOR('',#2228,10.);
+#543=VECTOR('',#2231,10.);
+#544=VECTOR('',#2234,10.);
+#545=VECTOR('',#2237,10.);
+#546=VECTOR('',#2240,10.);
+#547=VECTOR('',#2243,10.);
+#548=VECTOR('',#2246,10.);
+#549=VECTOR('',#2261,10.);
+#550=VECTOR('',#2262,10.);
+#551=VECTOR('',#2265,10.);
+#552=VECTOR('',#2266,10.);
+#553=VECTOR('',#2271,10.);
+#554=VECTOR('',#2276,10.);
+#555=VECTOR('',#2277,10.);
+#556=VECTOR('',#2280,10.);
+#557=VECTOR('',#2281,10.);
+#558=VECTOR('',#2286,1.45);
+#559=VECTOR('',#2291,1.45);
+#560=VECTOR('',#2296,1.45);
+#561=VECTOR('',#2301,1.45);
+#562=VECTOR('',#2304,10.);
+#563=VECTOR('',#2307,10.);
+#564=VECTOR('',#2310,10.);
+#565=VECTOR('',#2311,10.);
+#566=VECTOR('',#2316,10.);
+#567=VECTOR('',#2319,10.);
+#568=VECTOR('',#2320,10.);
+#569=VECTOR('',#2325,10.);
+#570=VECTOR('',#2328,10.);
+#571=VECTOR('',#2329,10.);
+#572=VECTOR('',#2334,10.);
+#573=VECTOR('',#2337,10.);
+#574=VECTOR('',#2340,10.);
+#575=VECTOR('',#2343,10.);
+#576=VECTOR('',#2346,10.);
+#577=VECTOR('',#2347,10.);
+#578=VECTOR('',#2352,10.);
+#579=VECTOR('',#2355,10.);
+#580=VECTOR('',#2356,10.);
+#581=VECTOR('',#2361,10.);
+#582=VECTOR('',#2364,10.);
+#583=VECTOR('',#2365,10.);
+#584=VECTOR('',#2370,10.);
+#585=VECTOR('',#2373,10.);
+#586=VECTOR('',#2376,10.);
+#587=VECTOR('',#2379,10.);
+#588=VECTOR('',#2382,10.);
+#589=VECTOR('',#2383,10.);
+#590=VECTOR('',#2388,10.);
+#591=VECTOR('',#2391,10.);
+#592=VECTOR('',#2392,10.);
+#593=VECTOR('',#2397,10.);
+#594=VECTOR('',#2400,10.);
+#595=VECTOR('',#2401,10.);
+#596=VECTOR('',#2406,10.);
+#597=VECTOR('',#2409,10.);
+#598=VECTOR('',#2412,10.);
+#599=VECTOR('',#2415,10.);
+#600=VECTOR('',#2418,10.);
+#601=VECTOR('',#2419,10.);
+#602=VECTOR('',#2424,10.);
+#603=VECTOR('',#2427,10.);
+#604=VECTOR('',#2428,10.);
+#605=VECTOR('',#2433,10.);
+#606=VECTOR('',#2436,10.);
+#607=VECTOR('',#2437,10.);
+#608=VECTOR('',#2442,10.);
+#609=VECTOR('',#2445,10.);
+#610=VECTOR('',#2448,10.);
+#611=VECTOR('',#2451,10.);
+#612=VECTOR('',#2454,10.);
+#613=VECTOR('',#2455,10.);
+#614=VECTOR('',#2460,10.);
+#615=VECTOR('',#2463,10.);
+#616=VECTOR('',#2464,10.);
+#617=VECTOR('',#2469,10.);
+#618=VECTOR('',#2472,10.);
+#619=VECTOR('',#2473,10.);
+#620=VECTOR('',#2478,10.);
+#621=VECTOR('',#2481,10.);
+#622=VECTOR('',#2484,10.);
+#623=VECTOR('',#2487,10.);
+#624=VECTOR('',#2490,10.);
+#625=VECTOR('',#2491,10.);
+#626=VECTOR('',#2496,10.);
+#627=VECTOR('',#2499,10.);
+#628=VECTOR('',#2500,10.);
+#629=VECTOR('',#2505,10.);
+#630=VECTOR('',#2508,10.);
+#631=VECTOR('',#2509,10.);
+#632=VECTOR('',#2514,10.);
+#633=VECTOR('',#2517,10.);
+#634=VECTOR('',#2520,10.);
+#635=VECTOR('',#2523,10.);
+#636=VECTOR('',#2526,10.);
+#637=VECTOR('',#2527,10.);
+#638=VECTOR('',#2532,10.);
+#639=VECTOR('',#2535,10.);
+#640=VECTOR('',#2536,10.);
+#641=VECTOR('',#2541,10.);
+#642=VECTOR('',#2544,10.);
+#643=VECTOR('',#2545,10.);
+#644=VECTOR('',#2550,10.);
+#645=VECTOR('',#2553,10.);
+#646=VECTOR('',#2556,10.);
+#647=VECTOR('',#2559,10.);
+#648=VECTOR('',#2562,10.);
+#649=VECTOR('',#2563,10.);
+#650=VECTOR('',#2568,10.);
+#651=VECTOR('',#2571,10.);
+#652=VECTOR('',#2572,10.);
+#653=VECTOR('',#2577,10.);
+#654=VECTOR('',#2580,10.);
+#655=VECTOR('',#2581,10.);
+#656=VECTOR('',#2586,10.);
+#657=VECTOR('',#2589,10.);
+#658=VECTOR('',#2592,10.);
+#659=VECTOR('',#2595,10.);
+#660=VECTOR('',#2598,10.);
+#661=VECTOR('',#2599,10.);
+#662=VECTOR('',#2604,10.);
+#663=VECTOR('',#2607,10.);
+#664=VECTOR('',#2608,10.);
+#665=VECTOR('',#2613,10.);
+#666=VECTOR('',#2616,10.);
+#667=VECTOR('',#2617,10.);
+#668=VECTOR('',#2622,10.);
+#669=VECTOR('',#2625,10.);
+#670=VECTOR('',#2628,10.);
+#671=VECTOR('',#2629,10.);
+#672=VECTOR('',#2630,10.);
+#673=VECTOR('',#2633,10.);
+#674=VECTOR('',#2634,10.);
+#675=VECTOR('',#2637,10.);
+#676=VECTOR('',#2638,10.);
+#677=VECTOR('',#2641,10.);
+#678=VECTOR('',#2644,10.);
+#679=VECTOR('',#2645,10.);
+#680=VECTOR('',#2646,10.);
+#681=VECTOR('',#2649,10.);
+#682=VECTOR('',#2652,10.);
+#683=VECTOR('',#2655,10.);
+#684=VECTOR('',#2658,10.);
+#685=CIRCLE('',#1926,5.);
+#686=CIRCLE('',#1927,5.);
+#687=CIRCLE('',#1930,5.);
+#688=CIRCLE('',#1931,5.);
+#689=CIRCLE('',#1932,5.);
+#690=CIRCLE('',#1933,0.499999999999998);
+#691=CIRCLE('',#1934,0.499999999999998);
+#692=CIRCLE('',#1935,0.499999999999998);
+#693=CIRCLE('',#1936,0.499999999999989);
+#694=CIRCLE('',#1937,0.499999999999998);
+#695=CIRCLE('',#1938,0.499999999999998);
+#696=CIRCLE('',#1939,0.499999999999998);
+#697=CIRCLE('',#1940,0.499999999999998);
+#698=CIRCLE('',#1941,0.499999999999998);
+#699=CIRCLE('',#1942,0.499999999999998);
+#700=CIRCLE('',#1943,0.499999999999998);
+#701=CIRCLE('',#1944,0.499999999999998);
+#702=CIRCLE('',#1945,0.500000000000003);
+#703=CIRCLE('',#1946,0.5);
+#704=CIRCLE('',#1947,0.499999999999998);
+#705=CIRCLE('',#1948,0.499999999999998);
+#706=CIRCLE('',#1949,0.500000000000003);
+#707=CIRCLE('',#1950,0.499999999999998);
+#708=CIRCLE('',#1951,0.499999999999998);
+#709=CIRCLE('',#1952,0.499999999999989);
+#710=CIRCLE('',#1953,0.500000000000003);
+#711=CIRCLE('',#1954,0.499999999999998);
+#712=CIRCLE('',#1955,0.499999999999998);
+#713=CIRCLE('',#1956,0.499999999999998);
+#714=CIRCLE('',#1957,0.499999999999998);
+#715=CIRCLE('',#1958,0.5);
+#716=CIRCLE('',#1959,0.499999999999998);
+#717=CIRCLE('',#1960,0.499999999999998);
+#718=CIRCLE('',#1961,0.500000000000003);
+#719=CIRCLE('',#1962,0.499999999999998);
+#720=CIRCLE('',#1963,0.499999999999998);
+#721=CIRCLE('',#1964,0.499999999999998);
+#722=CIRCLE('',#1965,0.499999999999998);
+#723=CIRCLE('',#1966,0.499999999999998);
+#724=CIRCLE('',#1967,0.499999999999998);
+#725=CIRCLE('',#1968,0.499999999999989);
+#726=CIRCLE('',#1969,1.45);
+#727=CIRCLE('',#1970,1.45);
+#728=CIRCLE('',#1971,1.45);
+#729=CIRCLE('',#1972,1.45);
+#730=CIRCLE('',#1974,5.);
+#731=CIRCLE('',#1977,5.);
+#732=CIRCLE('',#1979,5.);
+#733=CIRCLE('',#1982,1.45);
+#734=CIRCLE('',#1984,1.45);
+#735=CIRCLE('',#1986,1.45);
+#736=CIRCLE('',#1988,1.45);
+#737=CIRCLE('',#1990,0.499999999999998);
+#738=CIRCLE('',#1993,0.499999999999998);
+#739=CIRCLE('',#1996,0.499999999999998);
+#740=CIRCLE('',#1999,0.499999999999989);
+#741=CIRCLE('',#2002,0.500000000000003);
+#742=CIRCLE('',#2005,0.499999999999998);
+#743=CIRCLE('',#2008,0.499999999999998);
+#744=CIRCLE('',#2011,0.499999999999998);
+#745=CIRCLE('',#2014,0.499999999999998);
+#746=CIRCLE('',#2017,0.5);
+#747=CIRCLE('',#2020,0.499999999999998);
+#748=CIRCLE('',#2023,0.499999999999998);
+#749=CIRCLE('',#2026,0.500000000000003);
+#750=CIRCLE('',#2029,0.499999999999998);
+#751=CIRCLE('',#2032,0.499999999999998);
+#752=CIRCLE('',#2035,0.499999999999998);
+#753=CIRCLE('',#2038,0.500000000000003);
+#754=CIRCLE('',#2041,0.499999999999998);
+#755=CIRCLE('',#2044,0.499999999999998);
+#756=CIRCLE('',#2047,0.499999999999989);
+#757=CIRCLE('',#2050,0.500000000000003);
+#758=CIRCLE('',#2053,0.5);
+#759=CIRCLE('',#2056,0.499999999999998);
+#760=CIRCLE('',#2059,0.499999999999998);
+#761=CIRCLE('',#2062,0.499999999999998);
+#762=CIRCLE('',#2065,0.499999999999998);
+#763=CIRCLE('',#2068,0.499999999999998);
+#764=CIRCLE('',#2071,0.499999999999998);
+#765=CIRCLE('',#2074,0.499999999999998);
+#766=CIRCLE('',#2077,0.499999999999998);
+#767=CIRCLE('',#2080,0.499999999999998);
+#768=CIRCLE('',#2083,0.499999999999998);
+#769=CIRCLE('',#2086,0.499999999999998);
+#770=CIRCLE('',#2089,0.499999999999998);
+#771=CIRCLE('',#2092,0.499999999999998);
+#772=CIRCLE('',#2095,0.499999999999989);
+#773=VERTEX_POINT('',#2663);
+#774=VERTEX_POINT('',#2664);
+#775=VERTEX_POINT('',#2666);
+#776=VERTEX_POINT('',#2668);
+#777=VERTEX_POINT('',#2672);
+#778=VERTEX_POINT('',#2674);
+#779=VERTEX_POINT('',#2678);
+#780=VERTEX_POINT('',#2680);
+#781=VERTEX_POINT('',#2682);
+#782=VERTEX_POINT('',#2684);
+#783=VERTEX_POINT('',#2686);
+#784=VERTEX_POINT('',#2688);
+#785=VERTEX_POINT('',#2690);
+#786=VERTEX_POINT('',#2692);
+#787=VERTEX_POINT('',#2694);
+#788=VERTEX_POINT('',#2697);
+#789=VERTEX_POINT('',#2698);
+#790=VERTEX_POINT('',#2700);
+#791=VERTEX_POINT('',#2702);
+#792=VERTEX_POINT('',#2705);
+#793=VERTEX_POINT('',#2706);
+#794=VERTEX_POINT('',#2708);
+#795=VERTEX_POINT('',#2710);
+#796=VERTEX_POINT('',#2712);
+#797=VERTEX_POINT('',#2714);
+#798=VERTEX_POINT('',#2716);
+#799=VERTEX_POINT('',#2718);
+#800=VERTEX_POINT('',#2721);
+#801=VERTEX_POINT('',#2722);
+#802=VERTEX_POINT('',#2724);
+#803=VERTEX_POINT('',#2726);
+#804=VERTEX_POINT('',#2728);
+#805=VERTEX_POINT('',#2730);
+#806=VERTEX_POINT('',#2732);
+#807=VERTEX_POINT('',#2734);
+#808=VERTEX_POINT('',#2737);
+#809=VERTEX_POINT('',#2738);
+#810=VERTEX_POINT('',#2740);
+#811=VERTEX_POINT('',#2742);
+#812=VERTEX_POINT('',#2744);
+#813=VERTEX_POINT('',#2746);
+#814=VERTEX_POINT('',#2748);
+#815=VERTEX_POINT('',#2750);
+#816=VERTEX_POINT('',#2753);
+#817=VERTEX_POINT('',#2754);
+#818=VERTEX_POINT('',#2756);
+#819=VERTEX_POINT('',#2758);
+#820=VERTEX_POINT('',#2760);
+#821=VERTEX_POINT('',#2762);
+#822=VERTEX_POINT('',#2764);
+#823=VERTEX_POINT('',#2766);
+#824=VERTEX_POINT('',#2769);
+#825=VERTEX_POINT('',#2770);
+#826=VERTEX_POINT('',#2772);
+#827=VERTEX_POINT('',#2774);
+#828=VERTEX_POINT('',#2776);
+#829=VERTEX_POINT('',#2778);
+#830=VERTEX_POINT('',#2780);
+#831=VERTEX_POINT('',#2782);
+#832=VERTEX_POINT('',#2785);
+#833=VERTEX_POINT('',#2786);
+#834=VERTEX_POINT('',#2788);
+#835=VERTEX_POINT('',#2790);
+#836=VERTEX_POINT('',#2792);
+#837=VERTEX_POINT('',#2794);
+#838=VERTEX_POINT('',#2796);
+#839=VERTEX_POINT('',#2798);
+#840=VERTEX_POINT('',#2801);
+#841=VERTEX_POINT('',#2802);
+#842=VERTEX_POINT('',#2804);
+#843=VERTEX_POINT('',#2806);
+#844=VERTEX_POINT('',#2808);
+#845=VERTEX_POINT('',#2810);
+#846=VERTEX_POINT('',#2812);
+#847=VERTEX_POINT('',#2814);
+#848=VERTEX_POINT('',#2817);
+#849=VERTEX_POINT('',#2818);
+#850=VERTEX_POINT('',#2820);
+#851=VERTEX_POINT('',#2822);
+#852=VERTEX_POINT('',#2824);
+#853=VERTEX_POINT('',#2826);
+#854=VERTEX_POINT('',#2828);
+#855=VERTEX_POINT('',#2830);
+#856=VERTEX_POINT('',#2833);
+#857=VERTEX_POINT('',#2834);
+#858=VERTEX_POINT('',#2836);
+#859=VERTEX_POINT('',#2838);
+#860=VERTEX_POINT('',#2840);
+#861=VERTEX_POINT('',#2842);
+#862=VERTEX_POINT('',#2844);
+#863=VERTEX_POINT('',#2846);
+#864=VERTEX_POINT('',#2849);
+#865=VERTEX_POINT('',#2851);
+#866=VERTEX_POINT('',#2853);
+#867=VERTEX_POINT('',#2855);
+#868=VERTEX_POINT('',#2858);
+#869=VERTEX_POINT('',#2859);
+#870=VERTEX_POINT('',#2864);
+#871=VERTEX_POINT('',#2868);
+#872=VERTEX_POINT('',#2872);
+#873=VERTEX_POINT('',#2873);
+#874=VERTEX_POINT('',#2878);
+#875=VERTEX_POINT('',#2882);
+#876=VERTEX_POINT('',#2886);
+#877=VERTEX_POINT('',#2890);
+#878=VERTEX_POINT('',#2894);
+#879=VERTEX_POINT('',#2898);
+#880=VERTEX_POINT('',#2900);
+#881=VERTEX_POINT('',#2904);
+#882=VERTEX_POINT('',#2908);
+#883=VERTEX_POINT('',#2912);
+#884=VERTEX_POINT('',#2916);
+#885=VERTEX_POINT('',#2920);
+#886=VERTEX_POINT('',#2924);
+#887=VERTEX_POINT('',#2930);
+#888=VERTEX_POINT('',#2932);
+#889=VERTEX_POINT('',#2936);
+#890=VERTEX_POINT('',#2940);
+#891=VERTEX_POINT('',#2944);
+#892=VERTEX_POINT('',#2948);
+#893=VERTEX_POINT('',#2952);
+#894=VERTEX_POINT('',#2956);
+#895=VERTEX_POINT('',#2962);
+#896=VERTEX_POINT('',#2964);
+#897=VERTEX_POINT('',#2968);
+#898=VERTEX_POINT('',#2972);
+#899=VERTEX_POINT('',#2976);
+#900=VERTEX_POINT('',#2980);
+#901=VERTEX_POINT('',#2984);
+#902=VERTEX_POINT('',#2988);
+#903=VERTEX_POINT('',#2994);
+#904=VERTEX_POINT('',#2996);
+#905=VERTEX_POINT('',#3000);
+#906=VERTEX_POINT('',#3004);
+#907=VERTEX_POINT('',#3008);
+#908=VERTEX_POINT('',#3012);
+#909=VERTEX_POINT('',#3016);
+#910=VERTEX_POINT('',#3020);
+#911=VERTEX_POINT('',#3026);
+#912=VERTEX_POINT('',#3028);
+#913=VERTEX_POINT('',#3032);
+#914=VERTEX_POINT('',#3036);
+#915=VERTEX_POINT('',#3040);
+#916=VERTEX_POINT('',#3044);
+#917=VERTEX_POINT('',#3048);
+#918=VERTEX_POINT('',#3052);
+#919=VERTEX_POINT('',#3058);
+#920=VERTEX_POINT('',#3060);
+#921=VERTEX_POINT('',#3064);
+#922=VERTEX_POINT('',#3068);
+#923=VERTEX_POINT('',#3072);
+#924=VERTEX_POINT('',#3076);
+#925=VERTEX_POINT('',#3080);
+#926=VERTEX_POINT('',#3084);
+#927=VERTEX_POINT('',#3090);
+#928=VERTEX_POINT('',#3092);
+#929=VERTEX_POINT('',#3096);
+#930=VERTEX_POINT('',#3100);
+#931=VERTEX_POINT('',#3104);
+#932=VERTEX_POINT('',#3108);
+#933=VERTEX_POINT('',#3112);
+#934=VERTEX_POINT('',#3116);
+#935=VERTEX_POINT('',#3122);
+#936=VERTEX_POINT('',#3124);
+#937=VERTEX_POINT('',#3128);
+#938=VERTEX_POINT('',#3132);
+#939=VERTEX_POINT('',#3136);
+#940=VERTEX_POINT('',#3140);
+#941=VERTEX_POINT('',#3144);
+#942=VERTEX_POINT('',#3148);
+#943=VERTEX_POINT('',#3154);
+#944=VERTEX_POINT('',#3156);
+#945=VERTEX_POINT('',#3160);
+#946=VERTEX_POINT('',#3164);
+#947=VERTEX_POINT('',#3168);
+#948=VERTEX_POINT('',#3172);
+#949=VERTEX_POINT('',#3176);
+#950=VERTEX_POINT('',#3180);
+#951=VERTEX_POINT('',#3186);
+#952=VERTEX_POINT('',#3188);
+#953=VERTEX_POINT('',#3192);
+#954=VERTEX_POINT('',#3196);
+#955=VERTEX_POINT('',#3202);
+#956=VERTEX_POINT('',#3204);
+#957=EDGE_CURVE('',#773,#774,#685,.T.);
+#958=EDGE_CURVE('',#774,#775,#309,.T.);
+#959=EDGE_CURVE('',#775,#776,#686,.T.);
+#960=EDGE_CURVE('',#776,#773,#310,.T.);
+#961=EDGE_CURVE('',#777,#776,#311,.T.);
+#962=EDGE_CURVE('',#777,#778,#312,.T.);
+#963=EDGE_CURVE('',#773,#778,#313,.T.);
+#964=EDGE_CURVE('',#775,#779,#314,.T.);
+#965=EDGE_CURVE('',#780,#779,#687,.T.);
+#966=EDGE_CURVE('',#780,#781,#315,.T.);
+#967=EDGE_CURVE('',#782,#781,#688,.T.);
+#968=EDGE_CURVE('',#782,#783,#316,.T.);
+#969=EDGE_CURVE('',#784,#783,#689,.T.);
+#970=EDGE_CURVE('',#784,#785,#317,.T.);
+#971=EDGE_CURVE('',#785,#786,#318,.T.);
+#972=EDGE_CURVE('',#786,#787,#319,.T.);
+#973=EDGE_CURVE('',#787,#777,#320,.T.);
+#974=EDGE_CURVE('',#788,#789,#321,.T.);
+#975=EDGE_CURVE('',#789,#790,#322,.T.);
+#976=EDGE_CURVE('',#790,#791,#323,.T.);
+#977=EDGE_CURVE('',#791,#788,#324,.T.);
+#978=EDGE_CURVE('',#792,#793,#325,.T.);
+#979=EDGE_CURVE('',#793,#794,#690,.T.);
+#980=EDGE_CURVE('',#794,#795,#326,.T.);
+#981=EDGE_CURVE('',#795,#796,#691,.T.);
+#982=EDGE_CURVE('',#796,#797,#327,.T.);
+#983=EDGE_CURVE('',#797,#798,#692,.T.);
+#984=EDGE_CURVE('',#798,#799,#328,.T.);
+#985=EDGE_CURVE('',#799,#792,#693,.T.);
+#986=EDGE_CURVE('',#800,#801,#329,.T.);
+#987=EDGE_CURVE('',#801,#802,#694,.T.);
+#988=EDGE_CURVE('',#802,#803,#330,.T.);
+#989=EDGE_CURVE('',#803,#804,#695,.T.);
+#990=EDGE_CURVE('',#804,#805,#331,.T.);
+#991=EDGE_CURVE('',#805,#806,#696,.T.);
+#992=EDGE_CURVE('',#806,#807,#332,.T.);
+#993=EDGE_CURVE('',#807,#800,#697,.T.);
+#994=EDGE_CURVE('',#808,#809,#333,.T.);
+#995=EDGE_CURVE('',#809,#810,#698,.T.);
+#996=EDGE_CURVE('',#810,#811,#334,.T.);
+#997=EDGE_CURVE('',#811,#812,#699,.T.);
+#998=EDGE_CURVE('',#812,#813,#335,.T.);
+#999=EDGE_CURVE('',#813,#814,#700,.T.);
+#1000=EDGE_CURVE('',#814,#815,#336,.T.);
+#1001=EDGE_CURVE('',#815,#808,#701,.T.);
+#1002=EDGE_CURVE('',#816,#817,#337,.T.);
+#1003=EDGE_CURVE('',#817,#818,#702,.T.);
+#1004=EDGE_CURVE('',#818,#819,#338,.T.);
+#1005=EDGE_CURVE('',#819,#820,#703,.T.);
+#1006=EDGE_CURVE('',#820,#821,#339,.T.);
+#1007=EDGE_CURVE('',#821,#822,#704,.T.);
+#1008=EDGE_CURVE('',#822,#823,#340,.T.);
+#1009=EDGE_CURVE('',#823,#816,#705,.T.);
+#1010=EDGE_CURVE('',#824,#825,#341,.T.);
+#1011=EDGE_CURVE('',#825,#826,#706,.T.);
+#1012=EDGE_CURVE('',#826,#827,#342,.T.);
+#1013=EDGE_CURVE('',#827,#828,#707,.T.);
+#1014=EDGE_CURVE('',#828,#829,#343,.T.);
+#1015=EDGE_CURVE('',#829,#830,#708,.T.);
+#1016=EDGE_CURVE('',#830,#831,#344,.T.);
+#1017=EDGE_CURVE('',#831,#824,#709,.T.);
+#1018=EDGE_CURVE('',#832,#833,#345,.T.);
+#1019=EDGE_CURVE('',#833,#834,#710,.T.);
+#1020=EDGE_CURVE('',#834,#835,#346,.T.);
+#1021=EDGE_CURVE('',#835,#836,#711,.T.);
+#1022=EDGE_CURVE('',#836,#837,#347,.T.);
+#1023=EDGE_CURVE('',#837,#838,#712,.T.);
+#1024=EDGE_CURVE('',#838,#839,#348,.T.);
+#1025=EDGE_CURVE('',#839,#832,#713,.T.);
+#1026=EDGE_CURVE('',#840,#841,#349,.T.);
+#1027=EDGE_CURVE('',#841,#842,#714,.T.);
+#1028=EDGE_CURVE('',#842,#843,#350,.T.);
+#1029=EDGE_CURVE('',#843,#844,#715,.T.);
+#1030=EDGE_CURVE('',#844,#845,#351,.T.);
+#1031=EDGE_CURVE('',#845,#846,#716,.T.);
+#1032=EDGE_CURVE('',#846,#847,#352,.T.);
+#1033=EDGE_CURVE('',#847,#840,#717,.T.);
+#1034=EDGE_CURVE('',#848,#849,#353,.T.);
+#1035=EDGE_CURVE('',#849,#850,#718,.T.);
+#1036=EDGE_CURVE('',#850,#851,#354,.T.);
+#1037=EDGE_CURVE('',#851,#852,#719,.T.);
+#1038=EDGE_CURVE('',#852,#853,#355,.T.);
+#1039=EDGE_CURVE('',#853,#854,#720,.T.);
+#1040=EDGE_CURVE('',#854,#855,#356,.T.);
+#1041=EDGE_CURVE('',#855,#848,#721,.T.);
+#1042=EDGE_CURVE('',#856,#857,#357,.T.);
+#1043=EDGE_CURVE('',#857,#858,#722,.T.);
+#1044=EDGE_CURVE('',#858,#859,#358,.T.);
+#1045=EDGE_CURVE('',#859,#860,#723,.T.);
+#1046=EDGE_CURVE('',#860,#861,#359,.T.);
+#1047=EDGE_CURVE('',#861,#862,#724,.T.);
+#1048=EDGE_CURVE('',#862,#863,#360,.T.);
+#1049=EDGE_CURVE('',#863,#856,#725,.T.);
+#1050=EDGE_CURVE('',#864,#864,#726,.T.);
+#1051=EDGE_CURVE('',#865,#865,#727,.T.);
+#1052=EDGE_CURVE('',#866,#866,#728,.T.);
+#1053=EDGE_CURVE('',#867,#867,#729,.T.);
+#1054=EDGE_CURVE('',#868,#869,#730,.T.);
+#1055=EDGE_CURVE('',#869,#780,#361,.T.);
+#1056=EDGE_CURVE('',#779,#868,#362,.T.);
+#1057=EDGE_CURVE('',#870,#869,#363,.T.);
+#1058=EDGE_CURVE('',#781,#870,#364,.T.);
+#1059=EDGE_CURVE('',#870,#871,#731,.T.);
+#1060=EDGE_CURVE('',#871,#782,#365,.T.);
+#1061=EDGE_CURVE('',#872,#873,#732,.T.);
+#1062=EDGE_CURVE('',#873,#784,#366,.T.);
+#1063=EDGE_CURVE('',#783,#872,#367,.T.);
+#1064=EDGE_CURVE('',#874,#873,#368,.T.);
+#1065=EDGE_CURVE('',#785,#874,#369,.T.);
+#1066=EDGE_CURVE('',#875,#875,#733,.T.);
+#1067=EDGE_CURVE('',#875,#867,#370,.T.);
+#1068=EDGE_CURVE('',#876,#876,#734,.T.);
+#1069=EDGE_CURVE('',#876,#866,#371,.T.);
+#1070=EDGE_CURVE('',#877,#877,#735,.T.);
+#1071=EDGE_CURVE('',#877,#865,#372,.T.);
+#1072=EDGE_CURVE('',#878,#878,#736,.T.);
+#1073=EDGE_CURVE('',#878,#864,#373,.T.);
+#1074=EDGE_CURVE('',#857,#879,#374,.T.);
+#1075=EDGE_CURVE('',#880,#879,#737,.T.);
+#1076=EDGE_CURVE('',#858,#880,#375,.T.);
+#1077=EDGE_CURVE('',#881,#880,#376,.T.);
+#1078=EDGE_CURVE('',#859,#881,#377,.T.);
+#1079=EDGE_CURVE('',#882,#881,#738,.T.);
+#1080=EDGE_CURVE('',#860,#882,#378,.T.);
+#1081=EDGE_CURVE('',#883,#882,#379,.T.);
+#1082=EDGE_CURVE('',#861,#883,#380,.T.);
+#1083=EDGE_CURVE('',#884,#883,#739,.T.);
+#1084=EDGE_CURVE('',#862,#884,#381,.T.);
+#1085=EDGE_CURVE('',#885,#884,#382,.T.);
+#1086=EDGE_CURVE('',#863,#885,#383,.T.);
+#1087=EDGE_CURVE('',#886,#885,#740,.T.);
+#1088=EDGE_CURVE('',#856,#886,#384,.T.);
+#1089=EDGE_CURVE('',#879,#886,#385,.T.);
+#1090=EDGE_CURVE('',#849,#887,#386,.T.);
+#1091=EDGE_CURVE('',#888,#887,#741,.T.);
+#1092=EDGE_CURVE('',#850,#888,#387,.T.);
+#1093=EDGE_CURVE('',#889,#888,#388,.T.);
+#1094=EDGE_CURVE('',#851,#889,#389,.T.);
+#1095=EDGE_CURVE('',#890,#889,#742,.T.);
+#1096=EDGE_CURVE('',#852,#890,#390,.T.);
+#1097=EDGE_CURVE('',#891,#890,#391,.T.);
+#1098=EDGE_CURVE('',#853,#891,#392,.T.);
+#1099=EDGE_CURVE('',#892,#891,#743,.T.);
+#1100=EDGE_CURVE('',#854,#892,#393,.T.);
+#1101=EDGE_CURVE('',#893,#892,#394,.T.);
+#1102=EDGE_CURVE('',#855,#893,#395,.T.);
+#1103=EDGE_CURVE('',#894,#893,#744,.T.);
+#1104=EDGE_CURVE('',#848,#894,#396,.T.);
+#1105=EDGE_CURVE('',#887,#894,#397,.T.);
+#1106=EDGE_CURVE('',#841,#895,#398,.T.);
+#1107=EDGE_CURVE('',#896,#895,#745,.T.);
+#1108=EDGE_CURVE('',#842,#896,#399,.T.);
+#1109=EDGE_CURVE('',#897,#896,#400,.T.);
+#1110=EDGE_CURVE('',#843,#897,#401,.T.);
+#1111=EDGE_CURVE('',#898,#897,#746,.T.);
+#1112=EDGE_CURVE('',#844,#898,#402,.T.);
+#1113=EDGE_CURVE('',#899,#898,#403,.T.);
+#1114=EDGE_CURVE('',#845,#899,#404,.T.);
+#1115=EDGE_CURVE('',#900,#899,#747,.T.);
+#1116=EDGE_CURVE('',#846,#900,#405,.T.);
+#1117=EDGE_CURVE('',#901,#900,#406,.T.);
+#1118=EDGE_CURVE('',#847,#901,#407,.T.);
+#1119=EDGE_CURVE('',#902,#901,#748,.T.);
+#1120=EDGE_CURVE('',#840,#902,#408,.T.);
+#1121=EDGE_CURVE('',#895,#902,#409,.T.);
+#1122=EDGE_CURVE('',#833,#903,#410,.T.);
+#1123=EDGE_CURVE('',#904,#903,#749,.T.);
+#1124=EDGE_CURVE('',#834,#904,#411,.T.);
+#1125=EDGE_CURVE('',#905,#904,#412,.T.);
+#1126=EDGE_CURVE('',#835,#905,#413,.T.);
+#1127=EDGE_CURVE('',#906,#905,#750,.T.);
+#1128=EDGE_CURVE('',#836,#906,#414,.T.);
+#1129=EDGE_CURVE('',#907,#906,#415,.T.);
+#1130=EDGE_CURVE('',#837,#907,#416,.T.);
+#1131=EDGE_CURVE('',#908,#907,#751,.T.);
+#1132=EDGE_CURVE('',#838,#908,#417,.T.);
+#1133=EDGE_CURVE('',#909,#908,#418,.T.);
+#1134=EDGE_CURVE('',#839,#909,#419,.T.);
+#1135=EDGE_CURVE('',#910,#909,#752,.T.);
+#1136=EDGE_CURVE('',#832,#910,#420,.T.);
+#1137=EDGE_CURVE('',#903,#910,#421,.T.);
+#1138=EDGE_CURVE('',#825,#911,#422,.T.);
+#1139=EDGE_CURVE('',#912,#911,#753,.T.);
+#1140=EDGE_CURVE('',#826,#912,#423,.T.);
+#1141=EDGE_CURVE('',#913,#912,#424,.T.);
+#1142=EDGE_CURVE('',#827,#913,#425,.T.);
+#1143=EDGE_CURVE('',#914,#913,#754,.T.);
+#1144=EDGE_CURVE('',#828,#914,#426,.T.);
+#1145=EDGE_CURVE('',#915,#914,#427,.T.);
+#1146=EDGE_CURVE('',#829,#915,#428,.T.);
+#1147=EDGE_CURVE('',#916,#915,#755,.T.);
+#1148=EDGE_CURVE('',#830,#916,#429,.T.);
+#1149=EDGE_CURVE('',#917,#916,#430,.T.);
+#1150=EDGE_CURVE('',#831,#917,#431,.T.);
+#1151=EDGE_CURVE('',#918,#917,#756,.T.);
+#1152=EDGE_CURVE('',#824,#918,#432,.T.);
+#1153=EDGE_CURVE('',#911,#918,#433,.T.);
+#1154=EDGE_CURVE('',#817,#919,#434,.T.);
+#1155=EDGE_CURVE('',#920,#919,#757,.T.);
+#1156=EDGE_CURVE('',#818,#920,#435,.T.);
+#1157=EDGE_CURVE('',#921,#920,#436,.T.);
+#1158=EDGE_CURVE('',#819,#921,#437,.T.);
+#1159=EDGE_CURVE('',#922,#921,#758,.T.);
+#1160=EDGE_CURVE('',#820,#922,#438,.T.);
+#1161=EDGE_CURVE('',#923,#922,#439,.T.);
+#1162=EDGE_CURVE('',#821,#923,#440,.T.);
+#1163=EDGE_CURVE('',#924,#923,#759,.T.);
+#1164=EDGE_CURVE('',#822,#924,#441,.T.);
+#1165=EDGE_CURVE('',#925,#924,#442,.T.);
+#1166=EDGE_CURVE('',#823,#925,#443,.T.);
+#1167=EDGE_CURVE('',#926,#925,#760,.T.);
+#1168=EDGE_CURVE('',#816,#926,#444,.T.);
+#1169=EDGE_CURVE('',#919,#926,#445,.T.);
+#1170=EDGE_CURVE('',#809,#927,#446,.T.);
+#1171=EDGE_CURVE('',#928,#927,#761,.T.);
+#1172=EDGE_CURVE('',#810,#928,#447,.T.);
+#1173=EDGE_CURVE('',#929,#928,#448,.T.);
+#1174=EDGE_CURVE('',#811,#929,#449,.T.);
+#1175=EDGE_CURVE('',#930,#929,#762,.T.);
+#1176=EDGE_CURVE('',#812,#930,#450,.T.);
+#1177=EDGE_CURVE('',#931,#930,#451,.T.);
+#1178=EDGE_CURVE('',#813,#931,#452,.T.);
+#1179=EDGE_CURVE('',#932,#931,#763,.T.);
+#1180=EDGE_CURVE('',#814,#932,#453,.T.);
+#1181=EDGE_CURVE('',#933,#932,#454,.T.);
+#1182=EDGE_CURVE('',#815,#933,#455,.T.);
+#1183=EDGE_CURVE('',#934,#933,#764,.T.);
+#1184=EDGE_CURVE('',#808,#934,#456,.T.);
+#1185=EDGE_CURVE('',#927,#934,#457,.T.);
+#1186=EDGE_CURVE('',#801,#935,#458,.T.);
+#1187=EDGE_CURVE('',#936,#935,#765,.T.);
+#1188=EDGE_CURVE('',#802,#936,#459,.T.);
+#1189=EDGE_CURVE('',#937,#936,#460,.T.);
+#1190=EDGE_CURVE('',#803,#937,#461,.T.);
+#1191=EDGE_CURVE('',#938,#937,#766,.T.);
+#1192=EDGE_CURVE('',#804,#938,#462,.T.);
+#1193=EDGE_CURVE('',#939,#938,#463,.T.);
+#1194=EDGE_CURVE('',#805,#939,#464,.T.);
+#1195=EDGE_CURVE('',#940,#939,#767,.T.);
+#1196=EDGE_CURVE('',#806,#940,#465,.T.);
+#1197=EDGE_CURVE('',#941,#940,#466,.T.);
+#1198=EDGE_CURVE('',#807,#941,#467,.T.);
+#1199=EDGE_CURVE('',#942,#941,#768,.T.);
+#1200=EDGE_CURVE('',#800,#942,#468,.T.);
+#1201=EDGE_CURVE('',#935,#942,#469,.T.);
+#1202=EDGE_CURVE('',#793,#943,#470,.T.);
+#1203=EDGE_CURVE('',#944,#943,#769,.T.);
+#1204=EDGE_CURVE('',#794,#944,#471,.T.);
+#1205=EDGE_CURVE('',#945,#944,#472,.T.);
+#1206=EDGE_CURVE('',#795,#945,#473,.T.);
+#1207=EDGE_CURVE('',#946,#945,#770,.T.);
+#1208=EDGE_CURVE('',#796,#946,#474,.T.);
+#1209=EDGE_CURVE('',#947,#946,#475,.T.);
+#1210=EDGE_CURVE('',#797,#947,#476,.T.);
+#1211=EDGE_CURVE('',#948,#947,#771,.T.);
+#1212=EDGE_CURVE('',#798,#948,#477,.T.);
+#1213=EDGE_CURVE('',#949,#948,#478,.T.);
+#1214=EDGE_CURVE('',#799,#949,#479,.T.);
+#1215=EDGE_CURVE('',#950,#949,#772,.T.);
+#1216=EDGE_CURVE('',#792,#950,#480,.T.);
+#1217=EDGE_CURVE('',#943,#950,#481,.T.);
+#1218=EDGE_CURVE('',#789,#951,#482,.T.);
+#1219=EDGE_CURVE('',#952,#951,#483,.T.);
+#1220=EDGE_CURVE('',#790,#952,#484,.T.);
+#1221=EDGE_CURVE('',#953,#952,#485,.T.);
+#1222=EDGE_CURVE('',#791,#953,#486,.T.);
+#1223=EDGE_CURVE('',#954,#953,#487,.T.);
+#1224=EDGE_CURVE('',#788,#954,#488,.T.);
+#1225=EDGE_CURVE('',#951,#954,#489,.T.);
+#1226=EDGE_CURVE('',#786,#955,#490,.T.);
+#1227=EDGE_CURVE('',#956,#955,#491,.T.);
+#1228=EDGE_CURVE('',#787,#956,#492,.T.);
+#1229=EDGE_CURVE('',#778,#956,#493,.T.);
+#1230=EDGE_CURVE('',#868,#774,#494,.T.);
+#1231=EDGE_CURVE('',#872,#871,#495,.T.);
+#1232=EDGE_CURVE('',#955,#874,#496,.T.);
+#1233=ORIENTED_EDGE('',*,*,#957,.T.);
+#1234=ORIENTED_EDGE('',*,*,#958,.T.);
+#1235=ORIENTED_EDGE('',*,*,#959,.T.);
+#1236=ORIENTED_EDGE('',*,*,#960,.T.);
+#1237=ORIENTED_EDGE('',*,*,#960,.F.);
+#1238=ORIENTED_EDGE('',*,*,#961,.F.);
+#1239=ORIENTED_EDGE('',*,*,#962,.T.);
+#1240=ORIENTED_EDGE('',*,*,#963,.F.);
+#1241=ORIENTED_EDGE('',*,*,#959,.F.);
+#1242=ORIENTED_EDGE('',*,*,#964,.T.);
+#1243=ORIENTED_EDGE('',*,*,#965,.F.);
+#1244=ORIENTED_EDGE('',*,*,#966,.T.);
+#1245=ORIENTED_EDGE('',*,*,#967,.F.);
+#1246=ORIENTED_EDGE('',*,*,#968,.T.);
+#1247=ORIENTED_EDGE('',*,*,#969,.F.);
+#1248=ORIENTED_EDGE('',*,*,#970,.T.);
+#1249=ORIENTED_EDGE('',*,*,#971,.T.);
+#1250=ORIENTED_EDGE('',*,*,#972,.T.);
+#1251=ORIENTED_EDGE('',*,*,#973,.T.);
+#1252=ORIENTED_EDGE('',*,*,#961,.T.);
+#1253=ORIENTED_EDGE('',*,*,#974,.T.);
+#1254=ORIENTED_EDGE('',*,*,#975,.T.);
+#1255=ORIENTED_EDGE('',*,*,#976,.T.);
+#1256=ORIENTED_EDGE('',*,*,#977,.T.);
+#1257=ORIENTED_EDGE('',*,*,#978,.T.);
+#1258=ORIENTED_EDGE('',*,*,#979,.T.);
+#1259=ORIENTED_EDGE('',*,*,#980,.T.);
+#1260=ORIENTED_EDGE('',*,*,#981,.T.);
+#1261=ORIENTED_EDGE('',*,*,#982,.T.);
+#1262=ORIENTED_EDGE('',*,*,#983,.T.);
+#1263=ORIENTED_EDGE('',*,*,#984,.T.);
+#1264=ORIENTED_EDGE('',*,*,#985,.T.);
+#1265=ORIENTED_EDGE('',*,*,#986,.T.);
+#1266=ORIENTED_EDGE('',*,*,#987,.T.);
+#1267=ORIENTED_EDGE('',*,*,#988,.T.);
+#1268=ORIENTED_EDGE('',*,*,#989,.T.);
+#1269=ORIENTED_EDGE('',*,*,#990,.T.);
+#1270=ORIENTED_EDGE('',*,*,#991,.T.);
+#1271=ORIENTED_EDGE('',*,*,#992,.T.);
+#1272=ORIENTED_EDGE('',*,*,#993,.T.);
+#1273=ORIENTED_EDGE('',*,*,#994,.T.);
+#1274=ORIENTED_EDGE('',*,*,#995,.T.);
+#1275=ORIENTED_EDGE('',*,*,#996,.T.);
+#1276=ORIENTED_EDGE('',*,*,#997,.T.);
+#1277=ORIENTED_EDGE('',*,*,#998,.T.);
+#1278=ORIENTED_EDGE('',*,*,#999,.T.);
+#1279=ORIENTED_EDGE('',*,*,#1000,.T.);
+#1280=ORIENTED_EDGE('',*,*,#1001,.T.);
+#1281=ORIENTED_EDGE('',*,*,#1002,.T.);
+#1282=ORIENTED_EDGE('',*,*,#1003,.T.);
+#1283=ORIENTED_EDGE('',*,*,#1004,.T.);
+#1284=ORIENTED_EDGE('',*,*,#1005,.T.);
+#1285=ORIENTED_EDGE('',*,*,#1006,.T.);
+#1286=ORIENTED_EDGE('',*,*,#1007,.T.);
+#1287=ORIENTED_EDGE('',*,*,#1008,.T.);
+#1288=ORIENTED_EDGE('',*,*,#1009,.T.);
+#1289=ORIENTED_EDGE('',*,*,#1010,.T.);
+#1290=ORIENTED_EDGE('',*,*,#1011,.T.);
+#1291=ORIENTED_EDGE('',*,*,#1012,.T.);
+#1292=ORIENTED_EDGE('',*,*,#1013,.T.);
+#1293=ORIENTED_EDGE('',*,*,#1014,.T.);
+#1294=ORIENTED_EDGE('',*,*,#1015,.T.);
+#1295=ORIENTED_EDGE('',*,*,#1016,.T.);
+#1296=ORIENTED_EDGE('',*,*,#1017,.T.);
+#1297=ORIENTED_EDGE('',*,*,#1018,.T.);
+#1298=ORIENTED_EDGE('',*,*,#1019,.T.);
+#1299=ORIENTED_EDGE('',*,*,#1020,.T.);
+#1300=ORIENTED_EDGE('',*,*,#1021,.T.);
+#1301=ORIENTED_EDGE('',*,*,#1022,.T.);
+#1302=ORIENTED_EDGE('',*,*,#1023,.T.);
+#1303=ORIENTED_EDGE('',*,*,#1024,.T.);
+#1304=ORIENTED_EDGE('',*,*,#1025,.T.);
+#1305=ORIENTED_EDGE('',*,*,#1026,.T.);
+#1306=ORIENTED_EDGE('',*,*,#1027,.T.);
+#1307=ORIENTED_EDGE('',*,*,#1028,.T.);
+#1308=ORIENTED_EDGE('',*,*,#1029,.T.);
+#1309=ORIENTED_EDGE('',*,*,#1030,.T.);
+#1310=ORIENTED_EDGE('',*,*,#1031,.T.);
+#1311=ORIENTED_EDGE('',*,*,#1032,.T.);
+#1312=ORIENTED_EDGE('',*,*,#1033,.T.);
+#1313=ORIENTED_EDGE('',*,*,#1034,.T.);
+#1314=ORIENTED_EDGE('',*,*,#1035,.T.);
+#1315=ORIENTED_EDGE('',*,*,#1036,.T.);
+#1316=ORIENTED_EDGE('',*,*,#1037,.T.);
+#1317=ORIENTED_EDGE('',*,*,#1038,.T.);
+#1318=ORIENTED_EDGE('',*,*,#1039,.T.);
+#1319=ORIENTED_EDGE('',*,*,#1040,.T.);
+#1320=ORIENTED_EDGE('',*,*,#1041,.T.);
+#1321=ORIENTED_EDGE('',*,*,#1042,.T.);
+#1322=ORIENTED_EDGE('',*,*,#1043,.T.);
+#1323=ORIENTED_EDGE('',*,*,#1044,.T.);
+#1324=ORIENTED_EDGE('',*,*,#1045,.T.);
+#1325=ORIENTED_EDGE('',*,*,#1046,.T.);
+#1326=ORIENTED_EDGE('',*,*,#1047,.T.);
+#1327=ORIENTED_EDGE('',*,*,#1048,.T.);
+#1328=ORIENTED_EDGE('',*,*,#1049,.T.);
+#1329=ORIENTED_EDGE('',*,*,#1050,.T.);
+#1330=ORIENTED_EDGE('',*,*,#1051,.T.);
+#1331=ORIENTED_EDGE('',*,*,#1052,.T.);
+#1332=ORIENTED_EDGE('',*,*,#1053,.T.);
+#1333=ORIENTED_EDGE('',*,*,#1054,.T.);
+#1334=ORIENTED_EDGE('',*,*,#1055,.T.);
+#1335=ORIENTED_EDGE('',*,*,#965,.T.);
+#1336=ORIENTED_EDGE('',*,*,#1056,.T.);
+#1337=ORIENTED_EDGE('',*,*,#1055,.F.);
+#1338=ORIENTED_EDGE('',*,*,#1057,.F.);
+#1339=ORIENTED_EDGE('',*,*,#1058,.F.);
+#1340=ORIENTED_EDGE('',*,*,#966,.F.);
+#1341=ORIENTED_EDGE('',*,*,#1059,.T.);
+#1342=ORIENTED_EDGE('',*,*,#1060,.T.);
+#1343=ORIENTED_EDGE('',*,*,#967,.T.);
+#1344=ORIENTED_EDGE('',*,*,#1058,.T.);
+#1345=ORIENTED_EDGE('',*,*,#1061,.T.);
+#1346=ORIENTED_EDGE('',*,*,#1062,.T.);
+#1347=ORIENTED_EDGE('',*,*,#969,.T.);
+#1348=ORIENTED_EDGE('',*,*,#1063,.T.);
+#1349=ORIENTED_EDGE('',*,*,#1062,.F.);
+#1350=ORIENTED_EDGE('',*,*,#1064,.F.);
+#1351=ORIENTED_EDGE('',*,*,#1065,.F.);
+#1352=ORIENTED_EDGE('',*,*,#970,.F.);
+#1353=ORIENTED_EDGE('',*,*,#1066,.F.);
+#1354=ORIENTED_EDGE('',*,*,#1067,.T.);
+#1355=ORIENTED_EDGE('',*,*,#1053,.F.);
+#1356=ORIENTED_EDGE('',*,*,#1067,.F.);
+#1357=ORIENTED_EDGE('',*,*,#1068,.F.);
+#1358=ORIENTED_EDGE('',*,*,#1069,.T.);
+#1359=ORIENTED_EDGE('',*,*,#1052,.F.);
+#1360=ORIENTED_EDGE('',*,*,#1069,.F.);
+#1361=ORIENTED_EDGE('',*,*,#1070,.F.);
+#1362=ORIENTED_EDGE('',*,*,#1071,.T.);
+#1363=ORIENTED_EDGE('',*,*,#1051,.F.);
+#1364=ORIENTED_EDGE('',*,*,#1071,.F.);
+#1365=ORIENTED_EDGE('',*,*,#1072,.F.);
+#1366=ORIENTED_EDGE('',*,*,#1073,.T.);
+#1367=ORIENTED_EDGE('',*,*,#1050,.F.);
+#1368=ORIENTED_EDGE('',*,*,#1073,.F.);
+#1369=ORIENTED_EDGE('',*,*,#1043,.F.);
+#1370=ORIENTED_EDGE('',*,*,#1074,.T.);
+#1371=ORIENTED_EDGE('',*,*,#1075,.F.);
+#1372=ORIENTED_EDGE('',*,*,#1076,.F.);
+#1373=ORIENTED_EDGE('',*,*,#1044,.F.);
+#1374=ORIENTED_EDGE('',*,*,#1076,.T.);
+#1375=ORIENTED_EDGE('',*,*,#1077,.F.);
+#1376=ORIENTED_EDGE('',*,*,#1078,.F.);
+#1377=ORIENTED_EDGE('',*,*,#1045,.F.);
+#1378=ORIENTED_EDGE('',*,*,#1078,.T.);
+#1379=ORIENTED_EDGE('',*,*,#1079,.F.);
+#1380=ORIENTED_EDGE('',*,*,#1080,.F.);
+#1381=ORIENTED_EDGE('',*,*,#1046,.F.);
+#1382=ORIENTED_EDGE('',*,*,#1080,.T.);
+#1383=ORIENTED_EDGE('',*,*,#1081,.F.);
+#1384=ORIENTED_EDGE('',*,*,#1082,.F.);
+#1385=ORIENTED_EDGE('',*,*,#1047,.F.);
+#1386=ORIENTED_EDGE('',*,*,#1082,.T.);
+#1387=ORIENTED_EDGE('',*,*,#1083,.F.);
+#1388=ORIENTED_EDGE('',*,*,#1084,.F.);
+#1389=ORIENTED_EDGE('',*,*,#1048,.F.);
+#1390=ORIENTED_EDGE('',*,*,#1084,.T.);
+#1391=ORIENTED_EDGE('',*,*,#1085,.F.);
+#1392=ORIENTED_EDGE('',*,*,#1086,.F.);
+#1393=ORIENTED_EDGE('',*,*,#1049,.F.);
+#1394=ORIENTED_EDGE('',*,*,#1086,.T.);
+#1395=ORIENTED_EDGE('',*,*,#1087,.F.);
+#1396=ORIENTED_EDGE('',*,*,#1088,.F.);
+#1397=ORIENTED_EDGE('',*,*,#1042,.F.);
+#1398=ORIENTED_EDGE('',*,*,#1088,.T.);
+#1399=ORIENTED_EDGE('',*,*,#1089,.F.);
+#1400=ORIENTED_EDGE('',*,*,#1074,.F.);
+#1401=ORIENTED_EDGE('',*,*,#1035,.F.);
+#1402=ORIENTED_EDGE('',*,*,#1090,.T.);
+#1403=ORIENTED_EDGE('',*,*,#1091,.F.);
+#1404=ORIENTED_EDGE('',*,*,#1092,.F.);
+#1405=ORIENTED_EDGE('',*,*,#1036,.F.);
+#1406=ORIENTED_EDGE('',*,*,#1092,.T.);
+#1407=ORIENTED_EDGE('',*,*,#1093,.F.);
+#1408=ORIENTED_EDGE('',*,*,#1094,.F.);
+#1409=ORIENTED_EDGE('',*,*,#1037,.F.);
+#1410=ORIENTED_EDGE('',*,*,#1094,.T.);
+#1411=ORIENTED_EDGE('',*,*,#1095,.F.);
+#1412=ORIENTED_EDGE('',*,*,#1096,.F.);
+#1413=ORIENTED_EDGE('',*,*,#1038,.F.);
+#1414=ORIENTED_EDGE('',*,*,#1096,.T.);
+#1415=ORIENTED_EDGE('',*,*,#1097,.F.);
+#1416=ORIENTED_EDGE('',*,*,#1098,.F.);
+#1417=ORIENTED_EDGE('',*,*,#1039,.F.);
+#1418=ORIENTED_EDGE('',*,*,#1098,.T.);
+#1419=ORIENTED_EDGE('',*,*,#1099,.F.);
+#1420=ORIENTED_EDGE('',*,*,#1100,.F.);
+#1421=ORIENTED_EDGE('',*,*,#1040,.F.);
+#1422=ORIENTED_EDGE('',*,*,#1100,.T.);
+#1423=ORIENTED_EDGE('',*,*,#1101,.F.);
+#1424=ORIENTED_EDGE('',*,*,#1102,.F.);
+#1425=ORIENTED_EDGE('',*,*,#1041,.F.);
+#1426=ORIENTED_EDGE('',*,*,#1102,.T.);
+#1427=ORIENTED_EDGE('',*,*,#1103,.F.);
+#1428=ORIENTED_EDGE('',*,*,#1104,.F.);
+#1429=ORIENTED_EDGE('',*,*,#1034,.F.);
+#1430=ORIENTED_EDGE('',*,*,#1104,.T.);
+#1431=ORIENTED_EDGE('',*,*,#1105,.F.);
+#1432=ORIENTED_EDGE('',*,*,#1090,.F.);
+#1433=ORIENTED_EDGE('',*,*,#1027,.F.);
+#1434=ORIENTED_EDGE('',*,*,#1106,.T.);
+#1435=ORIENTED_EDGE('',*,*,#1107,.F.);
+#1436=ORIENTED_EDGE('',*,*,#1108,.F.);
+#1437=ORIENTED_EDGE('',*,*,#1028,.F.);
+#1438=ORIENTED_EDGE('',*,*,#1108,.T.);
+#1439=ORIENTED_EDGE('',*,*,#1109,.F.);
+#1440=ORIENTED_EDGE('',*,*,#1110,.F.);
+#1441=ORIENTED_EDGE('',*,*,#1029,.F.);
+#1442=ORIENTED_EDGE('',*,*,#1110,.T.);
+#1443=ORIENTED_EDGE('',*,*,#1111,.F.);
+#1444=ORIENTED_EDGE('',*,*,#1112,.F.);
+#1445=ORIENTED_EDGE('',*,*,#1030,.F.);
+#1446=ORIENTED_EDGE('',*,*,#1112,.T.);
+#1447=ORIENTED_EDGE('',*,*,#1113,.F.);
+#1448=ORIENTED_EDGE('',*,*,#1114,.F.);
+#1449=ORIENTED_EDGE('',*,*,#1031,.F.);
+#1450=ORIENTED_EDGE('',*,*,#1114,.T.);
+#1451=ORIENTED_EDGE('',*,*,#1115,.F.);
+#1452=ORIENTED_EDGE('',*,*,#1116,.F.);
+#1453=ORIENTED_EDGE('',*,*,#1032,.F.);
+#1454=ORIENTED_EDGE('',*,*,#1116,.T.);
+#1455=ORIENTED_EDGE('',*,*,#1117,.F.);
+#1456=ORIENTED_EDGE('',*,*,#1118,.F.);
+#1457=ORIENTED_EDGE('',*,*,#1033,.F.);
+#1458=ORIENTED_EDGE('',*,*,#1118,.T.);
+#1459=ORIENTED_EDGE('',*,*,#1119,.F.);
+#1460=ORIENTED_EDGE('',*,*,#1120,.F.);
+#1461=ORIENTED_EDGE('',*,*,#1026,.F.);
+#1462=ORIENTED_EDGE('',*,*,#1120,.T.);
+#1463=ORIENTED_EDGE('',*,*,#1121,.F.);
+#1464=ORIENTED_EDGE('',*,*,#1106,.F.);
+#1465=ORIENTED_EDGE('',*,*,#1019,.F.);
+#1466=ORIENTED_EDGE('',*,*,#1122,.T.);
+#1467=ORIENTED_EDGE('',*,*,#1123,.F.);
+#1468=ORIENTED_EDGE('',*,*,#1124,.F.);
+#1469=ORIENTED_EDGE('',*,*,#1020,.F.);
+#1470=ORIENTED_EDGE('',*,*,#1124,.T.);
+#1471=ORIENTED_EDGE('',*,*,#1125,.F.);
+#1472=ORIENTED_EDGE('',*,*,#1126,.F.);
+#1473=ORIENTED_EDGE('',*,*,#1021,.F.);
+#1474=ORIENTED_EDGE('',*,*,#1126,.T.);
+#1475=ORIENTED_EDGE('',*,*,#1127,.F.);
+#1476=ORIENTED_EDGE('',*,*,#1128,.F.);
+#1477=ORIENTED_EDGE('',*,*,#1022,.F.);
+#1478=ORIENTED_EDGE('',*,*,#1128,.T.);
+#1479=ORIENTED_EDGE('',*,*,#1129,.F.);
+#1480=ORIENTED_EDGE('',*,*,#1130,.F.);
+#1481=ORIENTED_EDGE('',*,*,#1023,.F.);
+#1482=ORIENTED_EDGE('',*,*,#1130,.T.);
+#1483=ORIENTED_EDGE('',*,*,#1131,.F.);
+#1484=ORIENTED_EDGE('',*,*,#1132,.F.);
+#1485=ORIENTED_EDGE('',*,*,#1024,.F.);
+#1486=ORIENTED_EDGE('',*,*,#1132,.T.);
+#1487=ORIENTED_EDGE('',*,*,#1133,.F.);
+#1488=ORIENTED_EDGE('',*,*,#1134,.F.);
+#1489=ORIENTED_EDGE('',*,*,#1025,.F.);
+#1490=ORIENTED_EDGE('',*,*,#1134,.T.);
+#1491=ORIENTED_EDGE('',*,*,#1135,.F.);
+#1492=ORIENTED_EDGE('',*,*,#1136,.F.);
+#1493=ORIENTED_EDGE('',*,*,#1018,.F.);
+#1494=ORIENTED_EDGE('',*,*,#1136,.T.);
+#1495=ORIENTED_EDGE('',*,*,#1137,.F.);
+#1496=ORIENTED_EDGE('',*,*,#1122,.F.);
+#1497=ORIENTED_EDGE('',*,*,#1011,.F.);
+#1498=ORIENTED_EDGE('',*,*,#1138,.T.);
+#1499=ORIENTED_EDGE('',*,*,#1139,.F.);
+#1500=ORIENTED_EDGE('',*,*,#1140,.F.);
+#1501=ORIENTED_EDGE('',*,*,#1012,.F.);
+#1502=ORIENTED_EDGE('',*,*,#1140,.T.);
+#1503=ORIENTED_EDGE('',*,*,#1141,.F.);
+#1504=ORIENTED_EDGE('',*,*,#1142,.F.);
+#1505=ORIENTED_EDGE('',*,*,#1013,.F.);
+#1506=ORIENTED_EDGE('',*,*,#1142,.T.);
+#1507=ORIENTED_EDGE('',*,*,#1143,.F.);
+#1508=ORIENTED_EDGE('',*,*,#1144,.F.);
+#1509=ORIENTED_EDGE('',*,*,#1014,.F.);
+#1510=ORIENTED_EDGE('',*,*,#1144,.T.);
+#1511=ORIENTED_EDGE('',*,*,#1145,.F.);
+#1512=ORIENTED_EDGE('',*,*,#1146,.F.);
+#1513=ORIENTED_EDGE('',*,*,#1015,.F.);
+#1514=ORIENTED_EDGE('',*,*,#1146,.T.);
+#1515=ORIENTED_EDGE('',*,*,#1147,.F.);
+#1516=ORIENTED_EDGE('',*,*,#1148,.F.);
+#1517=ORIENTED_EDGE('',*,*,#1016,.F.);
+#1518=ORIENTED_EDGE('',*,*,#1148,.T.);
+#1519=ORIENTED_EDGE('',*,*,#1149,.F.);
+#1520=ORIENTED_EDGE('',*,*,#1150,.F.);
+#1521=ORIENTED_EDGE('',*,*,#1017,.F.);
+#1522=ORIENTED_EDGE('',*,*,#1150,.T.);
+#1523=ORIENTED_EDGE('',*,*,#1151,.F.);
+#1524=ORIENTED_EDGE('',*,*,#1152,.F.);
+#1525=ORIENTED_EDGE('',*,*,#1010,.F.);
+#1526=ORIENTED_EDGE('',*,*,#1152,.T.);
+#1527=ORIENTED_EDGE('',*,*,#1153,.F.);
+#1528=ORIENTED_EDGE('',*,*,#1138,.F.);
+#1529=ORIENTED_EDGE('',*,*,#1003,.F.);
+#1530=ORIENTED_EDGE('',*,*,#1154,.T.);
+#1531=ORIENTED_EDGE('',*,*,#1155,.F.);
+#1532=ORIENTED_EDGE('',*,*,#1156,.F.);
+#1533=ORIENTED_EDGE('',*,*,#1004,.F.);
+#1534=ORIENTED_EDGE('',*,*,#1156,.T.);
+#1535=ORIENTED_EDGE('',*,*,#1157,.F.);
+#1536=ORIENTED_EDGE('',*,*,#1158,.F.);
+#1537=ORIENTED_EDGE('',*,*,#1005,.F.);
+#1538=ORIENTED_EDGE('',*,*,#1158,.T.);
+#1539=ORIENTED_EDGE('',*,*,#1159,.F.);
+#1540=ORIENTED_EDGE('',*,*,#1160,.F.);
+#1541=ORIENTED_EDGE('',*,*,#1006,.F.);
+#1542=ORIENTED_EDGE('',*,*,#1160,.T.);
+#1543=ORIENTED_EDGE('',*,*,#1161,.F.);
+#1544=ORIENTED_EDGE('',*,*,#1162,.F.);
+#1545=ORIENTED_EDGE('',*,*,#1007,.F.);
+#1546=ORIENTED_EDGE('',*,*,#1162,.T.);
+#1547=ORIENTED_EDGE('',*,*,#1163,.F.);
+#1548=ORIENTED_EDGE('',*,*,#1164,.F.);
+#1549=ORIENTED_EDGE('',*,*,#1008,.F.);
+#1550=ORIENTED_EDGE('',*,*,#1164,.T.);
+#1551=ORIENTED_EDGE('',*,*,#1165,.F.);
+#1552=ORIENTED_EDGE('',*,*,#1166,.F.);
+#1553=ORIENTED_EDGE('',*,*,#1009,.F.);
+#1554=ORIENTED_EDGE('',*,*,#1166,.T.);
+#1555=ORIENTED_EDGE('',*,*,#1167,.F.);
+#1556=ORIENTED_EDGE('',*,*,#1168,.F.);
+#1557=ORIENTED_EDGE('',*,*,#1002,.F.);
+#1558=ORIENTED_EDGE('',*,*,#1168,.T.);
+#1559=ORIENTED_EDGE('',*,*,#1169,.F.);
+#1560=ORIENTED_EDGE('',*,*,#1154,.F.);
+#1561=ORIENTED_EDGE('',*,*,#995,.F.);
+#1562=ORIENTED_EDGE('',*,*,#1170,.T.);
+#1563=ORIENTED_EDGE('',*,*,#1171,.F.);
+#1564=ORIENTED_EDGE('',*,*,#1172,.F.);
+#1565=ORIENTED_EDGE('',*,*,#996,.F.);
+#1566=ORIENTED_EDGE('',*,*,#1172,.T.);
+#1567=ORIENTED_EDGE('',*,*,#1173,.F.);
+#1568=ORIENTED_EDGE('',*,*,#1174,.F.);
+#1569=ORIENTED_EDGE('',*,*,#997,.F.);
+#1570=ORIENTED_EDGE('',*,*,#1174,.T.);
+#1571=ORIENTED_EDGE('',*,*,#1175,.F.);
+#1572=ORIENTED_EDGE('',*,*,#1176,.F.);
+#1573=ORIENTED_EDGE('',*,*,#998,.F.);
+#1574=ORIENTED_EDGE('',*,*,#1176,.T.);
+#1575=ORIENTED_EDGE('',*,*,#1177,.F.);
+#1576=ORIENTED_EDGE('',*,*,#1178,.F.);
+#1577=ORIENTED_EDGE('',*,*,#999,.F.);
+#1578=ORIENTED_EDGE('',*,*,#1178,.T.);
+#1579=ORIENTED_EDGE('',*,*,#1179,.F.);
+#1580=ORIENTED_EDGE('',*,*,#1180,.F.);
+#1581=ORIENTED_EDGE('',*,*,#1000,.F.);
+#1582=ORIENTED_EDGE('',*,*,#1180,.T.);
+#1583=ORIENTED_EDGE('',*,*,#1181,.F.);
+#1584=ORIENTED_EDGE('',*,*,#1182,.F.);
+#1585=ORIENTED_EDGE('',*,*,#1001,.F.);
+#1586=ORIENTED_EDGE('',*,*,#1182,.T.);
+#1587=ORIENTED_EDGE('',*,*,#1183,.F.);
+#1588=ORIENTED_EDGE('',*,*,#1184,.F.);
+#1589=ORIENTED_EDGE('',*,*,#994,.F.);
+#1590=ORIENTED_EDGE('',*,*,#1184,.T.);
+#1591=ORIENTED_EDGE('',*,*,#1185,.F.);
+#1592=ORIENTED_EDGE('',*,*,#1170,.F.);
+#1593=ORIENTED_EDGE('',*,*,#987,.F.);
+#1594=ORIENTED_EDGE('',*,*,#1186,.T.);
+#1595=ORIENTED_EDGE('',*,*,#1187,.F.);
+#1596=ORIENTED_EDGE('',*,*,#1188,.F.);
+#1597=ORIENTED_EDGE('',*,*,#988,.F.);
+#1598=ORIENTED_EDGE('',*,*,#1188,.T.);
+#1599=ORIENTED_EDGE('',*,*,#1189,.F.);
+#1600=ORIENTED_EDGE('',*,*,#1190,.F.);
+#1601=ORIENTED_EDGE('',*,*,#989,.F.);
+#1602=ORIENTED_EDGE('',*,*,#1190,.T.);
+#1603=ORIENTED_EDGE('',*,*,#1191,.F.);
+#1604=ORIENTED_EDGE('',*,*,#1192,.F.);
+#1605=ORIENTED_EDGE('',*,*,#990,.F.);
+#1606=ORIENTED_EDGE('',*,*,#1192,.T.);
+#1607=ORIENTED_EDGE('',*,*,#1193,.F.);
+#1608=ORIENTED_EDGE('',*,*,#1194,.F.);
+#1609=ORIENTED_EDGE('',*,*,#991,.F.);
+#1610=ORIENTED_EDGE('',*,*,#1194,.T.);
+#1611=ORIENTED_EDGE('',*,*,#1195,.F.);
+#1612=ORIENTED_EDGE('',*,*,#1196,.F.);
+#1613=ORIENTED_EDGE('',*,*,#992,.F.);
+#1614=ORIENTED_EDGE('',*,*,#1196,.T.);
+#1615=ORIENTED_EDGE('',*,*,#1197,.F.);
+#1616=ORIENTED_EDGE('',*,*,#1198,.F.);
+#1617=ORIENTED_EDGE('',*,*,#993,.F.);
+#1618=ORIENTED_EDGE('',*,*,#1198,.T.);
+#1619=ORIENTED_EDGE('',*,*,#1199,.F.);
+#1620=ORIENTED_EDGE('',*,*,#1200,.F.);
+#1621=ORIENTED_EDGE('',*,*,#986,.F.);
+#1622=ORIENTED_EDGE('',*,*,#1200,.T.);
+#1623=ORIENTED_EDGE('',*,*,#1201,.F.);
+#1624=ORIENTED_EDGE('',*,*,#1186,.F.);
+#1625=ORIENTED_EDGE('',*,*,#979,.F.);
+#1626=ORIENTED_EDGE('',*,*,#1202,.T.);
+#1627=ORIENTED_EDGE('',*,*,#1203,.F.);
+#1628=ORIENTED_EDGE('',*,*,#1204,.F.);
+#1629=ORIENTED_EDGE('',*,*,#980,.F.);
+#1630=ORIENTED_EDGE('',*,*,#1204,.T.);
+#1631=ORIENTED_EDGE('',*,*,#1205,.F.);
+#1632=ORIENTED_EDGE('',*,*,#1206,.F.);
+#1633=ORIENTED_EDGE('',*,*,#981,.F.);
+#1634=ORIENTED_EDGE('',*,*,#1206,.T.);
+#1635=ORIENTED_EDGE('',*,*,#1207,.F.);
+#1636=ORIENTED_EDGE('',*,*,#1208,.F.);
+#1637=ORIENTED_EDGE('',*,*,#982,.F.);
+#1638=ORIENTED_EDGE('',*,*,#1208,.T.);
+#1639=ORIENTED_EDGE('',*,*,#1209,.F.);
+#1640=ORIENTED_EDGE('',*,*,#1210,.F.);
+#1641=ORIENTED_EDGE('',*,*,#983,.F.);
+#1642=ORIENTED_EDGE('',*,*,#1210,.T.);
+#1643=ORIENTED_EDGE('',*,*,#1211,.F.);
+#1644=ORIENTED_EDGE('',*,*,#1212,.F.);
+#1645=ORIENTED_EDGE('',*,*,#984,.F.);
+#1646=ORIENTED_EDGE('',*,*,#1212,.T.);
+#1647=ORIENTED_EDGE('',*,*,#1213,.F.);
+#1648=ORIENTED_EDGE('',*,*,#1214,.F.);
+#1649=ORIENTED_EDGE('',*,*,#985,.F.);
+#1650=ORIENTED_EDGE('',*,*,#1214,.T.);
+#1651=ORIENTED_EDGE('',*,*,#1215,.F.);
+#1652=ORIENTED_EDGE('',*,*,#1216,.F.);
+#1653=ORIENTED_EDGE('',*,*,#978,.F.);
+#1654=ORIENTED_EDGE('',*,*,#1216,.T.);
+#1655=ORIENTED_EDGE('',*,*,#1217,.F.);
+#1656=ORIENTED_EDGE('',*,*,#1202,.F.);
+#1657=ORIENTED_EDGE('',*,*,#975,.F.);
+#1658=ORIENTED_EDGE('',*,*,#1218,.T.);
+#1659=ORIENTED_EDGE('',*,*,#1219,.F.);
+#1660=ORIENTED_EDGE('',*,*,#1220,.F.);
+#1661=ORIENTED_EDGE('',*,*,#976,.F.);
+#1662=ORIENTED_EDGE('',*,*,#1220,.T.);
+#1663=ORIENTED_EDGE('',*,*,#1221,.F.);
+#1664=ORIENTED_EDGE('',*,*,#1222,.F.);
+#1665=ORIENTED_EDGE('',*,*,#977,.F.);
+#1666=ORIENTED_EDGE('',*,*,#1222,.T.);
+#1667=ORIENTED_EDGE('',*,*,#1223,.F.);
+#1668=ORIENTED_EDGE('',*,*,#1224,.F.);
+#1669=ORIENTED_EDGE('',*,*,#974,.F.);
+#1670=ORIENTED_EDGE('',*,*,#1224,.T.);
+#1671=ORIENTED_EDGE('',*,*,#1225,.F.);
+#1672=ORIENTED_EDGE('',*,*,#1218,.F.);
+#1673=ORIENTED_EDGE('',*,*,#972,.F.);
+#1674=ORIENTED_EDGE('',*,*,#1226,.T.);
+#1675=ORIENTED_EDGE('',*,*,#1227,.F.);
+#1676=ORIENTED_EDGE('',*,*,#1228,.F.);
+#1677=ORIENTED_EDGE('',*,*,#973,.F.);
+#1678=ORIENTED_EDGE('',*,*,#1228,.T.);
+#1679=ORIENTED_EDGE('',*,*,#1229,.F.);
+#1680=ORIENTED_EDGE('',*,*,#962,.F.);
+#1681=ORIENTED_EDGE('',*,*,#958,.F.);
+#1682=ORIENTED_EDGE('',*,*,#1230,.F.);
+#1683=ORIENTED_EDGE('',*,*,#1056,.F.);
+#1684=ORIENTED_EDGE('',*,*,#964,.F.);
+#1685=ORIENTED_EDGE('',*,*,#1060,.F.);
+#1686=ORIENTED_EDGE('',*,*,#1231,.F.);
+#1687=ORIENTED_EDGE('',*,*,#1063,.F.);
+#1688=ORIENTED_EDGE('',*,*,#968,.F.);
+#1689=ORIENTED_EDGE('',*,*,#971,.F.);
+#1690=ORIENTED_EDGE('',*,*,#1065,.T.);
+#1691=ORIENTED_EDGE('',*,*,#1232,.F.);
+#1692=ORIENTED_EDGE('',*,*,#1226,.F.);
+#1693=ORIENTED_EDGE('',*,*,#957,.F.);
+#1694=ORIENTED_EDGE('',*,*,#963,.T.);
+#1695=ORIENTED_EDGE('',*,*,#1229,.T.);
+#1696=ORIENTED_EDGE('',*,*,#1227,.T.);
+#1697=ORIENTED_EDGE('',*,*,#1232,.T.);
+#1698=ORIENTED_EDGE('',*,*,#1064,.T.);
+#1699=ORIENTED_EDGE('',*,*,#1061,.F.);
+#1700=ORIENTED_EDGE('',*,*,#1231,.T.);
+#1701=ORIENTED_EDGE('',*,*,#1059,.F.);
+#1702=ORIENTED_EDGE('',*,*,#1057,.T.);
+#1703=ORIENTED_EDGE('',*,*,#1054,.F.);
+#1704=ORIENTED_EDGE('',*,*,#1230,.T.);
+#1705=ORIENTED_EDGE('',*,*,#1225,.T.);
+#1706=ORIENTED_EDGE('',*,*,#1223,.T.);
+#1707=ORIENTED_EDGE('',*,*,#1221,.T.);
+#1708=ORIENTED_EDGE('',*,*,#1219,.T.);
+#1709=ORIENTED_EDGE('',*,*,#1217,.T.);
+#1710=ORIENTED_EDGE('',*,*,#1215,.T.);
+#1711=ORIENTED_EDGE('',*,*,#1213,.T.);
+#1712=ORIENTED_EDGE('',*,*,#1211,.T.);
+#1713=ORIENTED_EDGE('',*,*,#1209,.T.);
+#1714=ORIENTED_EDGE('',*,*,#1207,.T.);
+#1715=ORIENTED_EDGE('',*,*,#1205,.T.);
+#1716=ORIENTED_EDGE('',*,*,#1203,.T.);
+#1717=ORIENTED_EDGE('',*,*,#1201,.T.);
+#1718=ORIENTED_EDGE('',*,*,#1199,.T.);
+#1719=ORIENTED_EDGE('',*,*,#1197,.T.);
+#1720=ORIENTED_EDGE('',*,*,#1195,.T.);
+#1721=ORIENTED_EDGE('',*,*,#1193,.T.);
+#1722=ORIENTED_EDGE('',*,*,#1191,.T.);
+#1723=ORIENTED_EDGE('',*,*,#1189,.T.);
+#1724=ORIENTED_EDGE('',*,*,#1187,.T.);
+#1725=ORIENTED_EDGE('',*,*,#1185,.T.);
+#1726=ORIENTED_EDGE('',*,*,#1183,.T.);
+#1727=ORIENTED_EDGE('',*,*,#1181,.T.);
+#1728=ORIENTED_EDGE('',*,*,#1179,.T.);
+#1729=ORIENTED_EDGE('',*,*,#1177,.T.);
+#1730=ORIENTED_EDGE('',*,*,#1175,.T.);
+#1731=ORIENTED_EDGE('',*,*,#1173,.T.);
+#1732=ORIENTED_EDGE('',*,*,#1171,.T.);
+#1733=ORIENTED_EDGE('',*,*,#1169,.T.);
+#1734=ORIENTED_EDGE('',*,*,#1167,.T.);
+#1735=ORIENTED_EDGE('',*,*,#1165,.T.);
+#1736=ORIENTED_EDGE('',*,*,#1163,.T.);
+#1737=ORIENTED_EDGE('',*,*,#1161,.T.);
+#1738=ORIENTED_EDGE('',*,*,#1159,.T.);
+#1739=ORIENTED_EDGE('',*,*,#1157,.T.);
+#1740=ORIENTED_EDGE('',*,*,#1155,.T.);
+#1741=ORIENTED_EDGE('',*,*,#1153,.T.);
+#1742=ORIENTED_EDGE('',*,*,#1151,.T.);
+#1743=ORIENTED_EDGE('',*,*,#1149,.T.);
+#1744=ORIENTED_EDGE('',*,*,#1147,.T.);
+#1745=ORIENTED_EDGE('',*,*,#1145,.T.);
+#1746=ORIENTED_EDGE('',*,*,#1143,.T.);
+#1747=ORIENTED_EDGE('',*,*,#1141,.T.);
+#1748=ORIENTED_EDGE('',*,*,#1139,.T.);
+#1749=ORIENTED_EDGE('',*,*,#1137,.T.);
+#1750=ORIENTED_EDGE('',*,*,#1135,.T.);
+#1751=ORIENTED_EDGE('',*,*,#1133,.T.);
+#1752=ORIENTED_EDGE('',*,*,#1131,.T.);
+#1753=ORIENTED_EDGE('',*,*,#1129,.T.);
+#1754=ORIENTED_EDGE('',*,*,#1127,.T.);
+#1755=ORIENTED_EDGE('',*,*,#1125,.T.);
+#1756=ORIENTED_EDGE('',*,*,#1123,.T.);
+#1757=ORIENTED_EDGE('',*,*,#1121,.T.);
+#1758=ORIENTED_EDGE('',*,*,#1119,.T.);
+#1759=ORIENTED_EDGE('',*,*,#1117,.T.);
+#1760=ORIENTED_EDGE('',*,*,#1115,.T.);
+#1761=ORIENTED_EDGE('',*,*,#1113,.T.);
+#1762=ORIENTED_EDGE('',*,*,#1111,.T.);
+#1763=ORIENTED_EDGE('',*,*,#1109,.T.);
+#1764=ORIENTED_EDGE('',*,*,#1107,.T.);
+#1765=ORIENTED_EDGE('',*,*,#1105,.T.);
+#1766=ORIENTED_EDGE('',*,*,#1103,.T.);
+#1767=ORIENTED_EDGE('',*,*,#1101,.T.);
+#1768=ORIENTED_EDGE('',*,*,#1099,.T.);
+#1769=ORIENTED_EDGE('',*,*,#1097,.T.);
+#1770=ORIENTED_EDGE('',*,*,#1095,.T.);
+#1771=ORIENTED_EDGE('',*,*,#1093,.T.);
+#1772=ORIENTED_EDGE('',*,*,#1091,.T.);
+#1773=ORIENTED_EDGE('',*,*,#1089,.T.);
+#1774=ORIENTED_EDGE('',*,*,#1087,.T.);
+#1775=ORIENTED_EDGE('',*,*,#1085,.T.);
+#1776=ORIENTED_EDGE('',*,*,#1083,.T.);
+#1777=ORIENTED_EDGE('',*,*,#1081,.T.);
+#1778=ORIENTED_EDGE('',*,*,#1079,.T.);
+#1779=ORIENTED_EDGE('',*,*,#1077,.T.);
+#1780=ORIENTED_EDGE('',*,*,#1075,.T.);
+#1781=ORIENTED_EDGE('',*,*,#1072,.T.);
+#1782=ORIENTED_EDGE('',*,*,#1070,.T.);
+#1783=ORIENTED_EDGE('',*,*,#1068,.T.);
+#1784=ORIENTED_EDGE('',*,*,#1066,.T.);
+#1785=CYLINDRICAL_SURFACE('',#1925,5.);
+#1786=CYLINDRICAL_SURFACE('',#1973,5.);
+#1787=CYLINDRICAL_SURFACE('',#1976,5.);
+#1788=CYLINDRICAL_SURFACE('',#1978,5.);
+#1789=CYLINDRICAL_SURFACE('',#1981,1.45);
+#1790=CYLINDRICAL_SURFACE('',#1983,1.45);
+#1791=CYLINDRICAL_SURFACE('',#1985,1.45);
+#1792=CYLINDRICAL_SURFACE('',#1987,1.45);
+#1793=CYLINDRICAL_SURFACE('',#1989,0.499999999999998);
+#1794=CYLINDRICAL_SURFACE('',#1992,0.499999999999998);
+#1795=CYLINDRICAL_SURFACE('',#1995,0.499999999999998);
+#1796=CYLINDRICAL_SURFACE('',#1998,0.499999999999989);
+#1797=CYLINDRICAL_SURFACE('',#2001,0.500000000000003);
+#1798=CYLINDRICAL_SURFACE('',#2004,0.499999999999998);
+#1799=CYLINDRICAL_SURFACE('',#2007,0.499999999999998);
+#1800=CYLINDRICAL_SURFACE('',#2010,0.499999999999998);
+#1801=CYLINDRICAL_SURFACE('',#2013,0.499999999999998);
+#1802=CYLINDRICAL_SURFACE('',#2016,0.5);
+#1803=CYLINDRICAL_SURFACE('',#2019,0.499999999999998);
+#1804=CYLINDRICAL_SURFACE('',#2022,0.499999999999998);
+#1805=CYLINDRICAL_SURFACE('',#2025,0.500000000000003);
+#1806=CYLINDRICAL_SURFACE('',#2028,0.499999999999998);
+#1807=CYLINDRICAL_SURFACE('',#2031,0.499999999999998);
+#1808=CYLINDRICAL_SURFACE('',#2034,0.499999999999998);
+#1809=CYLINDRICAL_SURFACE('',#2037,0.500000000000003);
+#1810=CYLINDRICAL_SURFACE('',#2040,0.499999999999998);
+#1811=CYLINDRICAL_SURFACE('',#2043,0.499999999999998);
+#1812=CYLINDRICAL_SURFACE('',#2046,0.499999999999989);
+#1813=CYLINDRICAL_SURFACE('',#2049,0.500000000000003);
+#1814=CYLINDRICAL_SURFACE('',#2052,0.5);
+#1815=CYLINDRICAL_SURFACE('',#2055,0.499999999999998);
+#1816=CYLINDRICAL_SURFACE('',#2058,0.499999999999998);
+#1817=CYLINDRICAL_SURFACE('',#2061,0.499999999999998);
+#1818=CYLINDRICAL_SURFACE('',#2064,0.499999999999998);
+#1819=CYLINDRICAL_SURFACE('',#2067,0.499999999999998);
+#1820=CYLINDRICAL_SURFACE('',#2070,0.499999999999998);
+#1821=CYLINDRICAL_SURFACE('',#2073,0.499999999999998);
+#1822=CYLINDRICAL_SURFACE('',#2076,0.499999999999998);
+#1823=CYLINDRICAL_SURFACE('',#2079,0.499999999999998);
+#1824=CYLINDRICAL_SURFACE('',#2082,0.499999999999998);
+#1825=CYLINDRICAL_SURFACE('',#2085,0.499999999999998);
+#1826=CYLINDRICAL_SURFACE('',#2088,0.499999999999998);
+#1827=CYLINDRICAL_SURFACE('',#2091,0.499999999999998);
+#1828=CYLINDRICAL_SURFACE('',#2094,0.499999999999989);
+#1829=ADVANCED_FACE('',(#93),#1785,.T.);
+#1830=ADVANCED_FACE('',(#94),#43,.T.);
+#1831=ADVANCED_FACE('',(#95,#15,#16,#17,#18,#19,#20,#21,#22,#23,#24,#25,
+#26,#27,#28),#44,.T.);
+#1832=ADVANCED_FACE('',(#96),#1786,.T.);
+#1833=ADVANCED_FACE('',(#97),#45,.T.);
+#1834=ADVANCED_FACE('',(#98),#1787,.T.);
+#1835=ADVANCED_FACE('',(#99),#1788,.T.);
+#1836=ADVANCED_FACE('',(#100),#46,.T.);
+#1837=ADVANCED_FACE('',(#101),#1789,.F.);
+#1838=ADVANCED_FACE('',(#102),#1790,.F.);
+#1839=ADVANCED_FACE('',(#103),#1791,.F.);
+#1840=ADVANCED_FACE('',(#104),#1792,.F.);
+#1841=ADVANCED_FACE('',(#105),#1793,.F.);
+#1842=ADVANCED_FACE('',(#106),#47,.T.);
+#1843=ADVANCED_FACE('',(#107),#1794,.F.);
+#1844=ADVANCED_FACE('',(#108),#48,.T.);
+#1845=ADVANCED_FACE('',(#109),#1795,.F.);
+#1846=ADVANCED_FACE('',(#110),#49,.T.);
+#1847=ADVANCED_FACE('',(#111),#1796,.F.);
+#1848=ADVANCED_FACE('',(#112),#50,.T.);
+#1849=ADVANCED_FACE('',(#113),#1797,.F.);
+#1850=ADVANCED_FACE('',(#114),#51,.T.);
+#1851=ADVANCED_FACE('',(#115),#1798,.F.);
+#1852=ADVANCED_FACE('',(#116),#52,.T.);
+#1853=ADVANCED_FACE('',(#117),#1799,.F.);
+#1854=ADVANCED_FACE('',(#118),#53,.T.);
+#1855=ADVANCED_FACE('',(#119),#1800,.F.);
+#1856=ADVANCED_FACE('',(#120),#54,.T.);
+#1857=ADVANCED_FACE('',(#121),#1801,.F.);
+#1858=ADVANCED_FACE('',(#122),#55,.T.);
+#1859=ADVANCED_FACE('',(#123),#1802,.F.);
+#1860=ADVANCED_FACE('',(#124),#56,.T.);
+#1861=ADVANCED_FACE('',(#125),#1803,.F.);
+#1862=ADVANCED_FACE('',(#126),#57,.T.);
+#1863=ADVANCED_FACE('',(#127),#1804,.F.);
+#1864=ADVANCED_FACE('',(#128),#58,.T.);
+#1865=ADVANCED_FACE('',(#129),#1805,.F.);
+#1866=ADVANCED_FACE('',(#130),#59,.T.);
+#1867=ADVANCED_FACE('',(#131),#1806,.F.);
+#1868=ADVANCED_FACE('',(#132),#60,.T.);
+#1869=ADVANCED_FACE('',(#133),#1807,.F.);
+#1870=ADVANCED_FACE('',(#134),#61,.T.);
+#1871=ADVANCED_FACE('',(#135),#1808,.F.);
+#1872=ADVANCED_FACE('',(#136),#62,.T.);
+#1873=ADVANCED_FACE('',(#137),#1809,.F.);
+#1874=ADVANCED_FACE('',(#138),#63,.T.);
+#1875=ADVANCED_FACE('',(#139),#1810,.F.);
+#1876=ADVANCED_FACE('',(#140),#64,.T.);
+#1877=ADVANCED_FACE('',(#141),#1811,.F.);
+#1878=ADVANCED_FACE('',(#142),#65,.T.);
+#1879=ADVANCED_FACE('',(#143),#1812,.F.);
+#1880=ADVANCED_FACE('',(#144),#66,.T.);
+#1881=ADVANCED_FACE('',(#145),#1813,.F.);
+#1882=ADVANCED_FACE('',(#146),#67,.T.);
+#1883=ADVANCED_FACE('',(#147),#1814,.F.);
+#1884=ADVANCED_FACE('',(#148),#68,.T.);
+#1885=ADVANCED_FACE('',(#149),#1815,.F.);
+#1886=ADVANCED_FACE('',(#150),#69,.T.);
+#1887=ADVANCED_FACE('',(#151),#1816,.F.);
+#1888=ADVANCED_FACE('',(#152),#70,.T.);
+#1889=ADVANCED_FACE('',(#153),#1817,.F.);
+#1890=ADVANCED_FACE('',(#154),#71,.T.);
+#1891=ADVANCED_FACE('',(#155),#1818,.F.);
+#1892=ADVANCED_FACE('',(#156),#72,.T.);
+#1893=ADVANCED_FACE('',(#157),#1819,.F.);
+#1894=ADVANCED_FACE('',(#158),#73,.T.);
+#1895=ADVANCED_FACE('',(#159),#1820,.F.);
+#1896=ADVANCED_FACE('',(#160),#74,.T.);
+#1897=ADVANCED_FACE('',(#161),#1821,.F.);
+#1898=ADVANCED_FACE('',(#162),#75,.T.);
+#1899=ADVANCED_FACE('',(#163),#1822,.F.);
+#1900=ADVANCED_FACE('',(#164),#76,.T.);
+#1901=ADVANCED_FACE('',(#165),#1823,.F.);
+#1902=ADVANCED_FACE('',(#166),#77,.T.);
+#1903=ADVANCED_FACE('',(#167),#1824,.F.);
+#1904=ADVANCED_FACE('',(#168),#78,.T.);
+#1905=ADVANCED_FACE('',(#169),#1825,.F.);
+#1906=ADVANCED_FACE('',(#170),#79,.T.);
+#1907=ADVANCED_FACE('',(#171),#1826,.F.);
+#1908=ADVANCED_FACE('',(#172),#80,.T.);
+#1909=ADVANCED_FACE('',(#173),#1827,.F.);
+#1910=ADVANCED_FACE('',(#174),#81,.T.);
+#1911=ADVANCED_FACE('',(#175),#1828,.F.);
+#1912=ADVANCED_FACE('',(#176),#82,.T.);
+#1913=ADVANCED_FACE('',(#177),#83,.T.);
+#1914=ADVANCED_FACE('',(#178),#84,.T.);
+#1915=ADVANCED_FACE('',(#179),#85,.T.);
+#1916=ADVANCED_FACE('',(#180),#86,.T.);
+#1917=ADVANCED_FACE('',(#181),#87,.T.);
+#1918=ADVANCED_FACE('',(#182),#88,.T.);
+#1919=ADVANCED_FACE('',(#183),#89,.T.);
+#1920=ADVANCED_FACE('',(#184),#90,.T.);
+#1921=ADVANCED_FACE('',(#185),#91,.T.);
+#1922=ADVANCED_FACE('',(#186,#29,#30,#31,#32,#33,#34,#35,#36,#37,#38,#39,
+#40,#41,#42),#92,.F.);
+#1923=CLOSED_SHELL('',(#1829,#1830,#1831,#1832,#1833,#1834,#1835,#1836,
+#1837,#1838,#1839,#1840,#1841,#1842,#1843,#1844,#1845,#1846,#1847,#1848,
+#1849,#1850,#1851,#1852,#1853,#1854,#1855,#1856,#1857,#1858,#1859,#1860,
+#1861,#1862,#1863,#1864,#1865,#1866,#1867,#1868,#1869,#1870,#1871,#1872,
+#1873,#1874,#1875,#1876,#1877,#1878,#1879,#1880,#1881,#1882,#1883,#1884,
+#1885,#1886,#1887,#1888,#1889,#1890,#1891,#1892,#1893,#1894,#1895,#1896,
+#1897,#1898,#1899,#1900,#1901,#1902,#1903,#1904,#1905,#1906,#1907,#1908,
+#1909,#1910,#1911,#1912,#1913,#1914,#1915,#1916,#1917,#1918,#1919,#1920,
+#1921,#1922));
+#1924=AXIS2_PLACEMENT_3D('',#2661,#2107,#2108);
+#1925=AXIS2_PLACEMENT_3D('',#2662,#2109,#2110);
+#1926=AXIS2_PLACEMENT_3D('',#2665,#2111,#2112);
+#1927=AXIS2_PLACEMENT_3D('',#2669,#2114,#2115);
+#1928=AXIS2_PLACEMENT_3D('',#2671,#2117,#2118);
+#1929=AXIS2_PLACEMENT_3D('',#2677,#2122,#2123);
+#1930=AXIS2_PLACEMENT_3D('',#2681,#2125,#2126);
+#1931=AXIS2_PLACEMENT_3D('',#2685,#2128,#2129);
+#1932=AXIS2_PLACEMENT_3D('',#2689,#2131,#2132);
+#1933=AXIS2_PLACEMENT_3D('',#2709,#2142,#2143);
+#1934=AXIS2_PLACEMENT_3D('',#2713,#2145,#2146);
+#1935=AXIS2_PLACEMENT_3D('',#2717,#2148,#2149);
+#1936=AXIS2_PLACEMENT_3D('',#2720,#2151,#2152);
+#1937=AXIS2_PLACEMENT_3D('',#2725,#2154,#2155);
+#1938=AXIS2_PLACEMENT_3D('',#2729,#2157,#2158);
+#1939=AXIS2_PLACEMENT_3D('',#2733,#2160,#2161);
+#1940=AXIS2_PLACEMENT_3D('',#2736,#2163,#2164);
+#1941=AXIS2_PLACEMENT_3D('',#2741,#2166,#2167);
+#1942=AXIS2_PLACEMENT_3D('',#2745,#2169,#2170);
+#1943=AXIS2_PLACEMENT_3D('',#2749,#2172,#2173);
+#1944=AXIS2_PLACEMENT_3D('',#2752,#2175,#2176);
+#1945=AXIS2_PLACEMENT_3D('',#2757,#2178,#2179);
+#1946=AXIS2_PLACEMENT_3D('',#2761,#2181,#2182);
+#1947=AXIS2_PLACEMENT_3D('',#2765,#2184,#2185);
+#1948=AXIS2_PLACEMENT_3D('',#2768,#2187,#2188);
+#1949=AXIS2_PLACEMENT_3D('',#2773,#2190,#2191);
+#1950=AXIS2_PLACEMENT_3D('',#2777,#2193,#2194);
+#1951=AXIS2_PLACEMENT_3D('',#2781,#2196,#2197);
+#1952=AXIS2_PLACEMENT_3D('',#2784,#2199,#2200);
+#1953=AXIS2_PLACEMENT_3D('',#2789,#2202,#2203);
+#1954=AXIS2_PLACEMENT_3D('',#2793,#2205,#2206);
+#1955=AXIS2_PLACEMENT_3D('',#2797,#2208,#2209);
+#1956=AXIS2_PLACEMENT_3D('',#2800,#2211,#2212);
+#1957=AXIS2_PLACEMENT_3D('',#2805,#2214,#2215);
+#1958=AXIS2_PLACEMENT_3D('',#2809,#2217,#2218);
+#1959=AXIS2_PLACEMENT_3D('',#2813,#2220,#2221);
+#1960=AXIS2_PLACEMENT_3D('',#2816,#2223,#2224);
+#1961=AXIS2_PLACEMENT_3D('',#2821,#2226,#2227);
+#1962=AXIS2_PLACEMENT_3D('',#2825,#2229,#2230);
+#1963=AXIS2_PLACEMENT_3D('',#2829,#2232,#2233);
+#1964=AXIS2_PLACEMENT_3D('',#2832,#2235,#2236);
+#1965=AXIS2_PLACEMENT_3D('',#2837,#2238,#2239);
+#1966=AXIS2_PLACEMENT_3D('',#2841,#2241,#2242);
+#1967=AXIS2_PLACEMENT_3D('',#2845,#2244,#2245);
+#1968=AXIS2_PLACEMENT_3D('',#2848,#2247,#2248);
+#1969=AXIS2_PLACEMENT_3D('',#2850,#2249,#2250);
+#1970=AXIS2_PLACEMENT_3D('',#2852,#2251,#2252);
+#1971=AXIS2_PLACEMENT_3D('',#2854,#2253,#2254);
+#1972=AXIS2_PLACEMENT_3D('',#2856,#2255,#2256);
+#1973=AXIS2_PLACEMENT_3D('',#2857,#2257,#2258);
+#1974=AXIS2_PLACEMENT_3D('',#2860,#2259,#2260);
+#1975=AXIS2_PLACEMENT_3D('',#2863,#2263,#2264);
+#1976=AXIS2_PLACEMENT_3D('',#2867,#2267,#2268);
+#1977=AXIS2_PLACEMENT_3D('',#2869,#2269,#2270);
+#1978=AXIS2_PLACEMENT_3D('',#2871,#2272,#2273);
+#1979=AXIS2_PLACEMENT_3D('',#2874,#2274,#2275);
+#1980=AXIS2_PLACEMENT_3D('',#2877,#2278,#2279);
+#1981=AXIS2_PLACEMENT_3D('',#2881,#2282,#2283);
+#1982=AXIS2_PLACEMENT_3D('',#2883,#2284,#2285);
+#1983=AXIS2_PLACEMENT_3D('',#2885,#2287,#2288);
+#1984=AXIS2_PLACEMENT_3D('',#2887,#2289,#2290);
+#1985=AXIS2_PLACEMENT_3D('',#2889,#2292,#2293);
+#1986=AXIS2_PLACEMENT_3D('',#2891,#2294,#2295);
+#1987=AXIS2_PLACEMENT_3D('',#2893,#2297,#2298);
+#1988=AXIS2_PLACEMENT_3D('',#2895,#2299,#2300);
+#1989=AXIS2_PLACEMENT_3D('',#2897,#2302,#2303);
+#1990=AXIS2_PLACEMENT_3D('',#2901,#2305,#2306);
+#1991=AXIS2_PLACEMENT_3D('',#2903,#2308,#2309);
+#1992=AXIS2_PLACEMENT_3D('',#2907,#2312,#2313);
+#1993=AXIS2_PLACEMENT_3D('',#2909,#2314,#2315);
+#1994=AXIS2_PLACEMENT_3D('',#2911,#2317,#2318);
+#1995=AXIS2_PLACEMENT_3D('',#2915,#2321,#2322);
+#1996=AXIS2_PLACEMENT_3D('',#2917,#2323,#2324);
+#1997=AXIS2_PLACEMENT_3D('',#2919,#2326,#2327);
+#1998=AXIS2_PLACEMENT_3D('',#2923,#2330,#2331);
+#1999=AXIS2_PLACEMENT_3D('',#2925,#2332,#2333);
+#2000=AXIS2_PLACEMENT_3D('',#2927,#2335,#2336);
+#2001=AXIS2_PLACEMENT_3D('',#2929,#2338,#2339);
+#2002=AXIS2_PLACEMENT_3D('',#2933,#2341,#2342);
+#2003=AXIS2_PLACEMENT_3D('',#2935,#2344,#2345);
+#2004=AXIS2_PLACEMENT_3D('',#2939,#2348,#2349);
+#2005=AXIS2_PLACEMENT_3D('',#2941,#2350,#2351);
+#2006=AXIS2_PLACEMENT_3D('',#2943,#2353,#2354);
+#2007=AXIS2_PLACEMENT_3D('',#2947,#2357,#2358);
+#2008=AXIS2_PLACEMENT_3D('',#2949,#2359,#2360);
+#2009=AXIS2_PLACEMENT_3D('',#2951,#2362,#2363);
+#2010=AXIS2_PLACEMENT_3D('',#2955,#2366,#2367);
+#2011=AXIS2_PLACEMENT_3D('',#2957,#2368,#2369);
+#2012=AXIS2_PLACEMENT_3D('',#2959,#2371,#2372);
+#2013=AXIS2_PLACEMENT_3D('',#2961,#2374,#2375);
+#2014=AXIS2_PLACEMENT_3D('',#2965,#2377,#2378);
+#2015=AXIS2_PLACEMENT_3D('',#2967,#2380,#2381);
+#2016=AXIS2_PLACEMENT_3D('',#2971,#2384,#2385);
+#2017=AXIS2_PLACEMENT_3D('',#2973,#2386,#2387);
+#2018=AXIS2_PLACEMENT_3D('',#2975,#2389,#2390);
+#2019=AXIS2_PLACEMENT_3D('',#2979,#2393,#2394);
+#2020=AXIS2_PLACEMENT_3D('',#2981,#2395,#2396);
+#2021=AXIS2_PLACEMENT_3D('',#2983,#2398,#2399);
+#2022=AXIS2_PLACEMENT_3D('',#2987,#2402,#2403);
+#2023=AXIS2_PLACEMENT_3D('',#2989,#2404,#2405);
+#2024=AXIS2_PLACEMENT_3D('',#2991,#2407,#2408);
+#2025=AXIS2_PLACEMENT_3D('',#2993,#2410,#2411);
+#2026=AXIS2_PLACEMENT_3D('',#2997,#2413,#2414);
+#2027=AXIS2_PLACEMENT_3D('',#2999,#2416,#2417);
+#2028=AXIS2_PLACEMENT_3D('',#3003,#2420,#2421);
+#2029=AXIS2_PLACEMENT_3D('',#3005,#2422,#2423);
+#2030=AXIS2_PLACEMENT_3D('',#3007,#2425,#2426);
+#2031=AXIS2_PLACEMENT_3D('',#3011,#2429,#2430);
+#2032=AXIS2_PLACEMENT_3D('',#3013,#2431,#2432);
+#2033=AXIS2_PLACEMENT_3D('',#3015,#2434,#2435);
+#2034=AXIS2_PLACEMENT_3D('',#3019,#2438,#2439);
+#2035=AXIS2_PLACEMENT_3D('',#3021,#2440,#2441);
+#2036=AXIS2_PLACEMENT_3D('',#3023,#2443,#2444);
+#2037=AXIS2_PLACEMENT_3D('',#3025,#2446,#2447);
+#2038=AXIS2_PLACEMENT_3D('',#3029,#2449,#2450);
+#2039=AXIS2_PLACEMENT_3D('',#3031,#2452,#2453);
+#2040=AXIS2_PLACEMENT_3D('',#3035,#2456,#2457);
+#2041=AXIS2_PLACEMENT_3D('',#3037,#2458,#2459);
+#2042=AXIS2_PLACEMENT_3D('',#3039,#2461,#2462);
+#2043=AXIS2_PLACEMENT_3D('',#3043,#2465,#2466);
+#2044=AXIS2_PLACEMENT_3D('',#3045,#2467,#2468);
+#2045=AXIS2_PLACEMENT_3D('',#3047,#2470,#2471);
+#2046=AXIS2_PLACEMENT_3D('',#3051,#2474,#2475);
+#2047=AXIS2_PLACEMENT_3D('',#3053,#2476,#2477);
+#2048=AXIS2_PLACEMENT_3D('',#3055,#2479,#2480);
+#2049=AXIS2_PLACEMENT_3D('',#3057,#2482,#2483);
+#2050=AXIS2_PLACEMENT_3D('',#3061,#2485,#2486);
+#2051=AXIS2_PLACEMENT_3D('',#3063,#2488,#2489);
+#2052=AXIS2_PLACEMENT_3D('',#3067,#2492,#2493);
+#2053=AXIS2_PLACEMENT_3D('',#3069,#2494,#2495);
+#2054=AXIS2_PLACEMENT_3D('',#3071,#2497,#2498);
+#2055=AXIS2_PLACEMENT_3D('',#3075,#2501,#2502);
+#2056=AXIS2_PLACEMENT_3D('',#3077,#2503,#2504);
+#2057=AXIS2_PLACEMENT_3D('',#3079,#2506,#2507);
+#2058=AXIS2_PLACEMENT_3D('',#3083,#2510,#2511);
+#2059=AXIS2_PLACEMENT_3D('',#3085,#2512,#2513);
+#2060=AXIS2_PLACEMENT_3D('',#3087,#2515,#2516);
+#2061=AXIS2_PLACEMENT_3D('',#3089,#2518,#2519);
+#2062=AXIS2_PLACEMENT_3D('',#3093,#2521,#2522);
+#2063=AXIS2_PLACEMENT_3D('',#3095,#2524,#2525);
+#2064=AXIS2_PLACEMENT_3D('',#3099,#2528,#2529);
+#2065=AXIS2_PLACEMENT_3D('',#3101,#2530,#2531);
+#2066=AXIS2_PLACEMENT_3D('',#3103,#2533,#2534);
+#2067=AXIS2_PLACEMENT_3D('',#3107,#2537,#2538);
+#2068=AXIS2_PLACEMENT_3D('',#3109,#2539,#2540);
+#2069=AXIS2_PLACEMENT_3D('',#3111,#2542,#2543);
+#2070=AXIS2_PLACEMENT_3D('',#3115,#2546,#2547);
+#2071=AXIS2_PLACEMENT_3D('',#3117,#2548,#2549);
+#2072=AXIS2_PLACEMENT_3D('',#3119,#2551,#2552);
+#2073=AXIS2_PLACEMENT_3D('',#3121,#2554,#2555);
+#2074=AXIS2_PLACEMENT_3D('',#3125,#2557,#2558);
+#2075=AXIS2_PLACEMENT_3D('',#3127,#2560,#2561);
+#2076=AXIS2_PLACEMENT_3D('',#3131,#2564,#2565);
+#2077=AXIS2_PLACEMENT_3D('',#3133,#2566,#2567);
+#2078=AXIS2_PLACEMENT_3D('',#3135,#2569,#2570);
+#2079=AXIS2_PLACEMENT_3D('',#3139,#2573,#2574);
+#2080=AXIS2_PLACEMENT_3D('',#3141,#2575,#2576);
+#2081=AXIS2_PLACEMENT_3D('',#3143,#2578,#2579);
+#2082=AXIS2_PLACEMENT_3D('',#3147,#2582,#2583);
+#2083=AXIS2_PLACEMENT_3D('',#3149,#2584,#2585);
+#2084=AXIS2_PLACEMENT_3D('',#3151,#2587,#2588);
+#2085=AXIS2_PLACEMENT_3D('',#3153,#2590,#2591);
+#2086=AXIS2_PLACEMENT_3D('',#3157,#2593,#2594);
+#2087=AXIS2_PLACEMENT_3D('',#3159,#2596,#2597);
+#2088=AXIS2_PLACEMENT_3D('',#3163,#2600,#2601);
+#2089=AXIS2_PLACEMENT_3D('',#3165,#2602,#2603);
+#2090=AXIS2_PLACEMENT_3D('',#3167,#2605,#2606);
+#2091=AXIS2_PLACEMENT_3D('',#3171,#2609,#2610);
+#2092=AXIS2_PLACEMENT_3D('',#3173,#2611,#2612);
+#2093=AXIS2_PLACEMENT_3D('',#3175,#2614,#2615);
+#2094=AXIS2_PLACEMENT_3D('',#3179,#2618,#2619);
+#2095=AXIS2_PLACEMENT_3D('',#3181,#2620,#2621);
+#2096=AXIS2_PLACEMENT_3D('',#3183,#2623,#2624);
+#2097=AXIS2_PLACEMENT_3D('',#3185,#2626,#2627);
+#2098=AXIS2_PLACEMENT_3D('',#3191,#2631,#2632);
+#2099=AXIS2_PLACEMENT_3D('',#3195,#2635,#2636);
+#2100=AXIS2_PLACEMENT_3D('',#3199,#2639,#2640);
+#2101=AXIS2_PLACEMENT_3D('',#3201,#2642,#2643);
+#2102=AXIS2_PLACEMENT_3D('',#3207,#2647,#2648);
+#2103=AXIS2_PLACEMENT_3D('',#3209,#2650,#2651);
+#2104=AXIS2_PLACEMENT_3D('',#3211,#2653,#2654);
+#2105=AXIS2_PLACEMENT_3D('',#3213,#2656,#2657);
+#2106=AXIS2_PLACEMENT_3D('',#3215,#2659,#2660);
+#2107=DIRECTION('axis',(0.,0.,1.));
+#2108=DIRECTION('refdir',(1.,0.,0.));
+#2109=DIRECTION('center_axis',(0.,0.,-1.));
+#2110=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#2111=DIRECTION('center_axis',(0.,0.,1.));
+#2112=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#2113=DIRECTION('',(0.,0.,1.));
+#2114=DIRECTION('center_axis',(0.,0.,-1.));
+#2115=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#2116=DIRECTION('',(0.,0.,-1.));
+#2117=DIRECTION('center_axis',(0.,1.,0.));
+#2118=DIRECTION('ref_axis',(1.,0.,0.));
+#2119=DIRECTION('',(-1.,0.,0.));
+#2120=DIRECTION('',(0.,0.,-1.));
+#2121=DIRECTION('',(1.,0.,0.));
+#2122=DIRECTION('center_axis',(0.,0.,1.));
+#2123=DIRECTION('ref_axis',(1.,0.,0.));
+#2124=DIRECTION('',(0.,-1.,0.));
+#2125=DIRECTION('center_axis',(0.,0.,-1.));
+#2126=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
+#2127=DIRECTION('',(1.,4.8472887907141E-17,0.));
+#2128=DIRECTION('center_axis',(0.,0.,-1.));
+#2129=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#2130=DIRECTION('',(0.,1.,0.));
+#2131=DIRECTION('center_axis',(0.,0.,-1.));
+#2132=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#2133=DIRECTION('',(-1.,0.,0.));
+#2134=DIRECTION('',(-0.00211883867751913,-0.99999775525881,0.));
+#2135=DIRECTION('',(-0.99999775525881,0.00211883867752521,0.));
+#2136=DIRECTION('',(0.00211883867752538,0.99999775525881,0.));
+#2137=DIRECTION('',(0.,-1.,0.));
+#2138=DIRECTION('',(-1.,0.,0.));
+#2139=DIRECTION('',(0.,1.,0.));
+#2140=DIRECTION('',(1.,0.,0.));
+#2141=DIRECTION('',(0.,-1.,0.));
+#2142=DIRECTION('center_axis',(0.,0.,-1.));
+#2143=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#2144=DIRECTION('',(-1.,0.,0.));
+#2145=DIRECTION('center_axis',(0.,0.,-1.));
+#2146=DIRECTION('ref_axis',(-1.,0.,0.));
+#2147=DIRECTION('',(0.,1.,0.));
+#2148=DIRECTION('center_axis',(0.,0.,-1.));
+#2149=DIRECTION('ref_axis',(0.,1.,0.));
+#2150=DIRECTION('',(1.,0.,0.));
+#2151=DIRECTION('center_axis',(0.,0.,-1.));
+#2152=DIRECTION('ref_axis',(1.,0.,0.));
+#2153=DIRECTION('',(0.,-1.,0.));
+#2154=DIRECTION('center_axis',(0.,0.,-1.));
+#2155=DIRECTION('ref_axis',(0.,-1.,0.));
+#2156=DIRECTION('',(-1.,0.,0.));
+#2157=DIRECTION('center_axis',(0.,0.,-1.));
+#2158=DIRECTION('ref_axis',(-1.,0.,0.));
+#2159=DIRECTION('',(0.,1.,0.));
+#2160=DIRECTION('center_axis',(0.,0.,-1.));
+#2161=DIRECTION('ref_axis',(0.,1.,0.));
+#2162=DIRECTION('',(1.,0.,0.));
+#2163=DIRECTION('center_axis',(0.,0.,-1.));
+#2164=DIRECTION('ref_axis',(1.,0.,0.));
+#2165=DIRECTION('',(0.,-1.,0.));
+#2166=DIRECTION('center_axis',(0.,0.,-1.));
+#2167=DIRECTION('ref_axis',(-8.88178419700128E-15,-1.,0.));
+#2168=DIRECTION('',(-1.,0.,0.));
+#2169=DIRECTION('center_axis',(0.,0.,-1.));
+#2170=DIRECTION('ref_axis',(-1.,0.,0.));
+#2171=DIRECTION('',(0.,1.,0.));
+#2172=DIRECTION('center_axis',(0.,0.,-1.));
+#2173=DIRECTION('ref_axis',(0.,1.,0.));
+#2174=DIRECTION('',(1.,0.,0.));
+#2175=DIRECTION('center_axis',(0.,0.,-1.));
+#2176=DIRECTION('ref_axis',(1.,0.,0.));
+#2177=DIRECTION('',(0.,-1.,0.));
+#2178=DIRECTION('center_axis',(0.,0.,-1.));
+#2179=DIRECTION('ref_axis',(0.,-1.,0.));
+#2180=DIRECTION('',(-1.,0.,0.));
+#2181=DIRECTION('center_axis',(0.,0.,-1.));
+#2182=DIRECTION('ref_axis',(-1.,0.,0.));
+#2183=DIRECTION('',(0.,1.,0.));
+#2184=DIRECTION('center_axis',(0.,0.,-1.));
+#2185=DIRECTION('ref_axis',(0.,1.,0.));
+#2186=DIRECTION('',(1.,0.,0.));
+#2187=DIRECTION('center_axis',(0.,0.,-1.));
+#2188=DIRECTION('ref_axis',(1.,0.,0.));
+#2189=DIRECTION('',(0.,-1.,0.));
+#2190=DIRECTION('center_axis',(0.,0.,-1.));
+#2191=DIRECTION('ref_axis',(3.55271367880048E-14,-1.,0.));
+#2192=DIRECTION('',(-1.,0.,0.));
+#2193=DIRECTION('center_axis',(0.,0.,-1.));
+#2194=DIRECTION('ref_axis',(-1.,0.,0.));
+#2195=DIRECTION('',(0.,1.,0.));
+#2196=DIRECTION('center_axis',(0.,0.,-1.));
+#2197=DIRECTION('ref_axis',(0.,1.,0.));
+#2198=DIRECTION('',(1.,0.,0.));
+#2199=DIRECTION('center_axis',(0.,0.,-1.));
+#2200=DIRECTION('ref_axis',(1.,0.,0.));
+#2201=DIRECTION('',(0.,-1.,0.));
+#2202=DIRECTION('center_axis',(0.,0.,-1.));
+#2203=DIRECTION('ref_axis',(0.,-1.,0.));
+#2204=DIRECTION('',(-1.,0.,0.));
+#2205=DIRECTION('center_axis',(0.,0.,-1.));
+#2206=DIRECTION('ref_axis',(-1.,0.,0.));
+#2207=DIRECTION('',(0.,1.,0.));
+#2208=DIRECTION('center_axis',(0.,0.,-1.));
+#2209=DIRECTION('ref_axis',(0.,1.,0.));
+#2210=DIRECTION('',(1.,0.,0.));
+#2211=DIRECTION('center_axis',(0.,0.,-1.));
+#2212=DIRECTION('ref_axis',(1.,0.,0.));
+#2213=DIRECTION('',(0.,-1.,0.));
+#2214=DIRECTION('center_axis',(0.,0.,-1.));
+#2215=DIRECTION('ref_axis',(0.,-1.,0.));
+#2216=DIRECTION('',(-1.,0.,0.));
+#2217=DIRECTION('center_axis',(0.,0.,-1.));
+#2218=DIRECTION('ref_axis',(-1.,0.,0.));
+#2219=DIRECTION('',(0.,1.,0.));
+#2220=DIRECTION('center_axis',(0.,0.,-1.));
+#2221=DIRECTION('ref_axis',(0.,1.,0.));
+#2222=DIRECTION('',(1.,0.,0.));
+#2223=DIRECTION('center_axis',(0.,0.,-1.));
+#2224=DIRECTION('ref_axis',(1.,0.,0.));
+#2225=DIRECTION('',(0.,-1.,0.));
+#2226=DIRECTION('center_axis',(0.,0.,-1.));
+#2227=DIRECTION('ref_axis',(-8.8817841970012E-15,-1.,0.));
+#2228=DIRECTION('',(-1.,0.,0.));
+#2229=DIRECTION('center_axis',(0.,0.,-1.));
+#2230=DIRECTION('ref_axis',(-1.,0.,0.));
+#2231=DIRECTION('',(0.,1.,0.));
+#2232=DIRECTION('center_axis',(0.,0.,-1.));
+#2233=DIRECTION('ref_axis',(0.,1.,0.));
+#2234=DIRECTION('',(1.,0.,0.));
+#2235=DIRECTION('center_axis',(0.,0.,-1.));
+#2236=DIRECTION('ref_axis',(1.,0.,0.));
+#2237=DIRECTION('',(0.,-1.,0.));
+#2238=DIRECTION('center_axis',(0.,0.,-1.));
+#2239=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#2240=DIRECTION('',(-1.,0.,0.));
+#2241=DIRECTION('center_axis',(0.,0.,-1.));
+#2242=DIRECTION('ref_axis',(-1.,0.,0.));
+#2243=DIRECTION('',(0.,1.,0.));
+#2244=DIRECTION('center_axis',(0.,0.,-1.));
+#2245=DIRECTION('ref_axis',(0.,1.,0.));
+#2246=DIRECTION('',(1.,0.,0.));
+#2247=DIRECTION('center_axis',(0.,0.,-1.));
+#2248=DIRECTION('ref_axis',(1.,0.,0.));
+#2249=DIRECTION('center_axis',(0.,0.,-1.));
+#2250=DIRECTION('ref_axis',(1.,0.,0.));
+#2251=DIRECTION('center_axis',(0.,0.,-1.));
+#2252=DIRECTION('ref_axis',(1.,0.,0.));
+#2253=DIRECTION('center_axis',(0.,0.,-1.));
+#2254=DIRECTION('ref_axis',(1.,0.,0.));
+#2255=DIRECTION('center_axis',(0.,0.,-1.));
+#2256=DIRECTION('ref_axis',(1.,0.,0.));
+#2257=DIRECTION('center_axis',(0.,0.,-1.));
+#2258=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
+#2259=DIRECTION('center_axis',(0.,0.,1.));
+#2260=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
+#2261=DIRECTION('',(0.,0.,1.));
+#2262=DIRECTION('',(0.,0.,-1.));
+#2263=DIRECTION('center_axis',(4.8472887907141E-17,-1.,0.));
+#2264=DIRECTION('ref_axis',(-1.,-4.8472887907141E-17,0.));
+#2265=DIRECTION('',(-1.,-4.8472887907141E-17,0.));
+#2266=DIRECTION('',(0.,0.,-1.));
+#2267=DIRECTION('center_axis',(0.,0.,-1.));
+#2268=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#2269=DIRECTION('center_axis',(0.,0.,1.));
+#2270=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#2271=DIRECTION('',(0.,0.,1.));
+#2272=DIRECTION('center_axis',(0.,0.,-1.));
+#2273=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#2274=DIRECTION('center_axis',(0.,0.,1.));
+#2275=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#2276=DIRECTION('',(0.,0.,1.));
+#2277=DIRECTION('',(0.,0.,-1.));
+#2278=DIRECTION('center_axis',(0.,1.,0.));
+#2279=DIRECTION('ref_axis',(1.,0.,0.));
+#2280=DIRECTION('',(1.,0.,0.));
+#2281=DIRECTION('',(0.,0.,-1.));
+#2282=DIRECTION('center_axis',(0.,0.,-1.));
+#2283=DIRECTION('ref_axis',(1.,0.,0.));
+#2284=DIRECTION('center_axis',(0.,0.,1.));
+#2285=DIRECTION('ref_axis',(1.,0.,0.));
+#2286=DIRECTION('',(0.,0.,1.));
+#2287=DIRECTION('center_axis',(0.,0.,-1.));
+#2288=DIRECTION('ref_axis',(1.,0.,0.));
+#2289=DIRECTION('center_axis',(0.,0.,1.));
+#2290=DIRECTION('ref_axis',(1.,0.,0.));
+#2291=DIRECTION('',(0.,0.,1.));
+#2292=DIRECTION('center_axis',(0.,0.,-1.));
+#2293=DIRECTION('ref_axis',(1.,0.,0.));
+#2294=DIRECTION('center_axis',(0.,0.,1.));
+#2295=DIRECTION('ref_axis',(1.,0.,0.));
+#2296=DIRECTION('',(0.,0.,1.));
+#2297=DIRECTION('center_axis',(0.,0.,-1.));
+#2298=DIRECTION('ref_axis',(1.,0.,0.));
+#2299=DIRECTION('center_axis',(0.,0.,1.));
+#2300=DIRECTION('ref_axis',(1.,0.,0.));
+#2301=DIRECTION('',(0.,0.,1.));
+#2302=DIRECTION('center_axis',(0.,0.,-1.));
+#2303=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#2304=DIRECTION('',(0.,0.,-1.));
+#2305=DIRECTION('center_axis',(0.,0.,1.));
+#2306=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#2307=DIRECTION('',(0.,0.,-1.));
+#2308=DIRECTION('center_axis',(0.,1.,0.));
+#2309=DIRECTION('ref_axis',(1.,0.,0.));
+#2310=DIRECTION('',(1.,0.,0.));
+#2311=DIRECTION('',(0.,0.,-1.));
+#2312=DIRECTION('center_axis',(0.,0.,-1.));
+#2313=DIRECTION('ref_axis',(-1.,0.,0.));
+#2314=DIRECTION('center_axis',(0.,0.,1.));
+#2315=DIRECTION('ref_axis',(-1.,0.,0.));
+#2316=DIRECTION('',(0.,0.,-1.));
+#2317=DIRECTION('center_axis',(1.,0.,0.));
+#2318=DIRECTION('ref_axis',(0.,-1.,0.));
+#2319=DIRECTION('',(0.,-1.,0.));
+#2320=DIRECTION('',(0.,0.,-1.));
+#2321=DIRECTION('center_axis',(0.,0.,-1.));
+#2322=DIRECTION('ref_axis',(0.,1.,0.));
+#2323=DIRECTION('center_axis',(0.,0.,1.));
+#2324=DIRECTION('ref_axis',(0.,1.,0.));
+#2325=DIRECTION('',(0.,0.,-1.));
+#2326=DIRECTION('center_axis',(0.,-1.,0.));
+#2327=DIRECTION('ref_axis',(-1.,0.,0.));
+#2328=DIRECTION('',(-1.,0.,0.));
+#2329=DIRECTION('',(0.,0.,-1.));
+#2330=DIRECTION('center_axis',(0.,0.,-1.));
+#2331=DIRECTION('ref_axis',(1.,0.,0.));
+#2332=DIRECTION('center_axis',(0.,0.,1.));
+#2333=DIRECTION('ref_axis',(1.,0.,0.));
+#2334=DIRECTION('',(0.,0.,-1.));
+#2335=DIRECTION('center_axis',(-1.,0.,0.));
+#2336=DIRECTION('ref_axis',(0.,1.,0.));
+#2337=DIRECTION('',(0.,1.,0.));
+#2338=DIRECTION('center_axis',(0.,0.,-1.));
+#2339=DIRECTION('ref_axis',(-8.8817841970012E-15,-1.,0.));
+#2340=DIRECTION('',(0.,0.,-1.));
+#2341=DIRECTION('center_axis',(0.,0.,1.));
+#2342=DIRECTION('ref_axis',(-8.8817841970012E-15,-1.,0.));
+#2343=DIRECTION('',(0.,0.,-1.));
+#2344=DIRECTION('center_axis',(0.,1.,0.));
+#2345=DIRECTION('ref_axis',(1.,0.,0.));
+#2346=DIRECTION('',(1.,0.,0.));
+#2347=DIRECTION('',(0.,0.,-1.));
+#2348=DIRECTION('center_axis',(0.,0.,-1.));
+#2349=DIRECTION('ref_axis',(-1.,0.,0.));
+#2350=DIRECTION('center_axis',(0.,0.,1.));
+#2351=DIRECTION('ref_axis',(-1.,0.,0.));
+#2352=DIRECTION('',(0.,0.,-1.));
+#2353=DIRECTION('center_axis',(1.,0.,0.));
+#2354=DIRECTION('ref_axis',(0.,-1.,0.));
+#2355=DIRECTION('',(0.,-1.,0.));
+#2356=DIRECTION('',(0.,0.,-1.));
+#2357=DIRECTION('center_axis',(0.,0.,-1.));
+#2358=DIRECTION('ref_axis',(0.,1.,0.));
+#2359=DIRECTION('center_axis',(0.,0.,1.));
+#2360=DIRECTION('ref_axis',(0.,1.,0.));
+#2361=DIRECTION('',(0.,0.,-1.));
+#2362=DIRECTION('center_axis',(0.,-1.,0.));
+#2363=DIRECTION('ref_axis',(-1.,0.,0.));
+#2364=DIRECTION('',(-1.,0.,0.));
+#2365=DIRECTION('',(0.,0.,-1.));
+#2366=DIRECTION('center_axis',(0.,0.,-1.));
+#2367=DIRECTION('ref_axis',(1.,0.,0.));
+#2368=DIRECTION('center_axis',(0.,0.,1.));
+#2369=DIRECTION('ref_axis',(1.,0.,0.));
+#2370=DIRECTION('',(0.,0.,-1.));
+#2371=DIRECTION('center_axis',(-1.,0.,0.));
+#2372=DIRECTION('ref_axis',(0.,1.,0.));
+#2373=DIRECTION('',(0.,1.,0.));
+#2374=DIRECTION('center_axis',(0.,0.,-1.));
+#2375=DIRECTION('ref_axis',(0.,-1.,0.));
+#2376=DIRECTION('',(0.,0.,-1.));
+#2377=DIRECTION('center_axis',(0.,0.,1.));
+#2378=DIRECTION('ref_axis',(0.,-1.,0.));
+#2379=DIRECTION('',(0.,0.,-1.));
+#2380=DIRECTION('center_axis',(0.,1.,0.));
+#2381=DIRECTION('ref_axis',(1.,0.,0.));
+#2382=DIRECTION('',(1.,0.,0.));
+#2383=DIRECTION('',(0.,0.,-1.));
+#2384=DIRECTION('center_axis',(0.,0.,-1.));
+#2385=DIRECTION('ref_axis',(-1.,0.,0.));
+#2386=DIRECTION('center_axis',(0.,0.,1.));
+#2387=DIRECTION('ref_axis',(-1.,0.,0.));
+#2388=DIRECTION('',(0.,0.,-1.));
+#2389=DIRECTION('center_axis',(1.,0.,0.));
+#2390=DIRECTION('ref_axis',(0.,-1.,0.));
+#2391=DIRECTION('',(0.,-1.,0.));
+#2392=DIRECTION('',(0.,0.,-1.));
+#2393=DIRECTION('center_axis',(0.,0.,-1.));
+#2394=DIRECTION('ref_axis',(0.,1.,0.));
+#2395=DIRECTION('center_axis',(0.,0.,1.));
+#2396=DIRECTION('ref_axis',(0.,1.,0.));
+#2397=DIRECTION('',(0.,0.,-1.));
+#2398=DIRECTION('center_axis',(0.,-1.,0.));
+#2399=DIRECTION('ref_axis',(-1.,0.,0.));
+#2400=DIRECTION('',(-1.,0.,0.));
+#2401=DIRECTION('',(0.,0.,-1.));
+#2402=DIRECTION('center_axis',(0.,0.,-1.));
+#2403=DIRECTION('ref_axis',(1.,0.,0.));
+#2404=DIRECTION('center_axis',(0.,0.,1.));
+#2405=DIRECTION('ref_axis',(1.,0.,0.));
+#2406=DIRECTION('',(0.,0.,-1.));
+#2407=DIRECTION('center_axis',(-1.,0.,0.));
+#2408=DIRECTION('ref_axis',(0.,1.,0.));
+#2409=DIRECTION('',(0.,1.,0.));
+#2410=DIRECTION('center_axis',(0.,0.,-1.));
+#2411=DIRECTION('ref_axis',(0.,-1.,0.));
+#2412=DIRECTION('',(0.,0.,-1.));
+#2413=DIRECTION('center_axis',(0.,0.,1.));
+#2414=DIRECTION('ref_axis',(0.,-1.,0.));
+#2415=DIRECTION('',(0.,0.,-1.));
+#2416=DIRECTION('center_axis',(0.,1.,0.));
+#2417=DIRECTION('ref_axis',(1.,0.,0.));
+#2418=DIRECTION('',(1.,0.,0.));
+#2419=DIRECTION('',(0.,0.,-1.));
+#2420=DIRECTION('center_axis',(0.,0.,-1.));
+#2421=DIRECTION('ref_axis',(-1.,0.,0.));
+#2422=DIRECTION('center_axis',(0.,0.,1.));
+#2423=DIRECTION('ref_axis',(-1.,0.,0.));
+#2424=DIRECTION('',(0.,0.,-1.));
+#2425=DIRECTION('center_axis',(1.,0.,0.));
+#2426=DIRECTION('ref_axis',(0.,-1.,0.));
+#2427=DIRECTION('',(0.,-1.,0.));
+#2428=DIRECTION('',(0.,0.,-1.));
+#2429=DIRECTION('center_axis',(0.,0.,-1.));
+#2430=DIRECTION('ref_axis',(0.,1.,0.));
+#2431=DIRECTION('center_axis',(0.,0.,1.));
+#2432=DIRECTION('ref_axis',(0.,1.,0.));
+#2433=DIRECTION('',(0.,0.,-1.));
+#2434=DIRECTION('center_axis',(0.,-1.,0.));
+#2435=DIRECTION('ref_axis',(-1.,0.,0.));
+#2436=DIRECTION('',(-1.,0.,0.));
+#2437=DIRECTION('',(0.,0.,-1.));
+#2438=DIRECTION('center_axis',(0.,0.,-1.));
+#2439=DIRECTION('ref_axis',(1.,0.,0.));
+#2440=DIRECTION('center_axis',(0.,0.,1.));
+#2441=DIRECTION('ref_axis',(1.,0.,0.));
+#2442=DIRECTION('',(0.,0.,-1.));
+#2443=DIRECTION('center_axis',(-1.,0.,0.));
+#2444=DIRECTION('ref_axis',(0.,1.,0.));
+#2445=DIRECTION('',(0.,1.,0.));
+#2446=DIRECTION('center_axis',(0.,0.,-1.));
+#2447=DIRECTION('ref_axis',(3.55271367880048E-14,-1.,0.));
+#2448=DIRECTION('',(0.,0.,-1.));
+#2449=DIRECTION('center_axis',(0.,0.,1.));
+#2450=DIRECTION('ref_axis',(3.55271367880048E-14,-1.,0.));
+#2451=DIRECTION('',(0.,0.,-1.));
+#2452=DIRECTION('center_axis',(0.,1.,0.));
+#2453=DIRECTION('ref_axis',(1.,0.,0.));
+#2454=DIRECTION('',(1.,0.,0.));
+#2455=DIRECTION('',(0.,0.,-1.));
+#2456=DIRECTION('center_axis',(0.,0.,-1.));
+#2457=DIRECTION('ref_axis',(-1.,0.,0.));
+#2458=DIRECTION('center_axis',(0.,0.,1.));
+#2459=DIRECTION('ref_axis',(-1.,0.,0.));
+#2460=DIRECTION('',(0.,0.,-1.));
+#2461=DIRECTION('center_axis',(1.,0.,0.));
+#2462=DIRECTION('ref_axis',(0.,-1.,0.));
+#2463=DIRECTION('',(0.,-1.,0.));
+#2464=DIRECTION('',(0.,0.,-1.));
+#2465=DIRECTION('center_axis',(0.,0.,-1.));
+#2466=DIRECTION('ref_axis',(0.,1.,0.));
+#2467=DIRECTION('center_axis',(0.,0.,1.));
+#2468=DIRECTION('ref_axis',(0.,1.,0.));
+#2469=DIRECTION('',(0.,0.,-1.));
+#2470=DIRECTION('center_axis',(0.,-1.,0.));
+#2471=DIRECTION('ref_axis',(-1.,0.,0.));
+#2472=DIRECTION('',(-1.,0.,0.));
+#2473=DIRECTION('',(0.,0.,-1.));
+#2474=DIRECTION('center_axis',(0.,0.,-1.));
+#2475=DIRECTION('ref_axis',(1.,0.,0.));
+#2476=DIRECTION('center_axis',(0.,0.,1.));
+#2477=DIRECTION('ref_axis',(1.,0.,0.));
+#2478=DIRECTION('',(0.,0.,-1.));
+#2479=DIRECTION('center_axis',(-1.,0.,0.));
+#2480=DIRECTION('ref_axis',(0.,1.,0.));
+#2481=DIRECTION('',(0.,1.,0.));
+#2482=DIRECTION('center_axis',(0.,0.,-1.));
+#2483=DIRECTION('ref_axis',(0.,-1.,0.));
+#2484=DIRECTION('',(0.,0.,-1.));
+#2485=DIRECTION('center_axis',(0.,0.,1.));
+#2486=DIRECTION('ref_axis',(0.,-1.,0.));
+#2487=DIRECTION('',(0.,0.,-1.));
+#2488=DIRECTION('center_axis',(0.,1.,0.));
+#2489=DIRECTION('ref_axis',(1.,0.,0.));
+#2490=DIRECTION('',(1.,0.,0.));
+#2491=DIRECTION('',(0.,0.,-1.));
+#2492=DIRECTION('center_axis',(0.,0.,-1.));
+#2493=DIRECTION('ref_axis',(-1.,0.,0.));
+#2494=DIRECTION('center_axis',(0.,0.,1.));
+#2495=DIRECTION('ref_axis',(-1.,0.,0.));
+#2496=DIRECTION('',(0.,0.,-1.));
+#2497=DIRECTION('center_axis',(1.,0.,0.));
+#2498=DIRECTION('ref_axis',(0.,-1.,0.));
+#2499=DIRECTION('',(0.,-1.,0.));
+#2500=DIRECTION('',(0.,0.,-1.));
+#2501=DIRECTION('center_axis',(0.,0.,-1.));
+#2502=DIRECTION('ref_axis',(0.,1.,0.));
+#2503=DIRECTION('center_axis',(0.,0.,1.));
+#2504=DIRECTION('ref_axis',(0.,1.,0.));
+#2505=DIRECTION('',(0.,0.,-1.));
+#2506=DIRECTION('center_axis',(0.,-1.,0.));
+#2507=DIRECTION('ref_axis',(-1.,0.,0.));
+#2508=DIRECTION('',(-1.,0.,0.));
+#2509=DIRECTION('',(0.,0.,-1.));
+#2510=DIRECTION('center_axis',(0.,0.,-1.));
+#2511=DIRECTION('ref_axis',(1.,0.,0.));
+#2512=DIRECTION('center_axis',(0.,0.,1.));
+#2513=DIRECTION('ref_axis',(1.,0.,0.));
+#2514=DIRECTION('',(0.,0.,-1.));
+#2515=DIRECTION('center_axis',(-1.,0.,0.));
+#2516=DIRECTION('ref_axis',(0.,1.,0.));
+#2517=DIRECTION('',(0.,1.,0.));
+#2518=DIRECTION('center_axis',(0.,0.,-1.));
+#2519=DIRECTION('ref_axis',(-8.88178419700128E-15,-1.,0.));
+#2520=DIRECTION('',(0.,0.,-1.));
+#2521=DIRECTION('center_axis',(0.,0.,1.));
+#2522=DIRECTION('ref_axis',(-8.88178419700128E-15,-1.,0.));
+#2523=DIRECTION('',(0.,0.,-1.));
+#2524=DIRECTION('center_axis',(0.,1.,0.));
+#2525=DIRECTION('ref_axis',(1.,0.,0.));
+#2526=DIRECTION('',(1.,0.,0.));
+#2527=DIRECTION('',(0.,0.,-1.));
+#2528=DIRECTION('center_axis',(0.,0.,-1.));
+#2529=DIRECTION('ref_axis',(-1.,0.,0.));
+#2530=DIRECTION('center_axis',(0.,0.,1.));
+#2531=DIRECTION('ref_axis',(-1.,0.,0.));
+#2532=DIRECTION('',(0.,0.,-1.));
+#2533=DIRECTION('center_axis',(1.,0.,0.));
+#2534=DIRECTION('ref_axis',(0.,-1.,0.));
+#2535=DIRECTION('',(0.,-1.,0.));
+#2536=DIRECTION('',(0.,0.,-1.));
+#2537=DIRECTION('center_axis',(0.,0.,-1.));
+#2538=DIRECTION('ref_axis',(0.,1.,0.));
+#2539=DIRECTION('center_axis',(0.,0.,1.));
+#2540=DIRECTION('ref_axis',(0.,1.,0.));
+#2541=DIRECTION('',(0.,0.,-1.));
+#2542=DIRECTION('center_axis',(0.,-1.,0.));
+#2543=DIRECTION('ref_axis',(-1.,0.,0.));
+#2544=DIRECTION('',(-1.,0.,0.));
+#2545=DIRECTION('',(0.,0.,-1.));
+#2546=DIRECTION('center_axis',(0.,0.,-1.));
+#2547=DIRECTION('ref_axis',(1.,0.,0.));
+#2548=DIRECTION('center_axis',(0.,0.,1.));
+#2549=DIRECTION('ref_axis',(1.,0.,0.));
+#2550=DIRECTION('',(0.,0.,-1.));
+#2551=DIRECTION('center_axis',(-1.,0.,0.));
+#2552=DIRECTION('ref_axis',(0.,1.,0.));
+#2553=DIRECTION('',(0.,1.,0.));
+#2554=DIRECTION('center_axis',(0.,0.,-1.));
+#2555=DIRECTION('ref_axis',(0.,-1.,0.));
+#2556=DIRECTION('',(0.,0.,-1.));
+#2557=DIRECTION('center_axis',(0.,0.,1.));
+#2558=DIRECTION('ref_axis',(0.,-1.,0.));
+#2559=DIRECTION('',(0.,0.,-1.));
+#2560=DIRECTION('center_axis',(0.,1.,0.));
+#2561=DIRECTION('ref_axis',(1.,0.,0.));
+#2562=DIRECTION('',(1.,0.,0.));
+#2563=DIRECTION('',(0.,0.,-1.));
+#2564=DIRECTION('center_axis',(0.,0.,-1.));
+#2565=DIRECTION('ref_axis',(-1.,0.,0.));
+#2566=DIRECTION('center_axis',(0.,0.,1.));
+#2567=DIRECTION('ref_axis',(-1.,0.,0.));
+#2568=DIRECTION('',(0.,0.,-1.));
+#2569=DIRECTION('center_axis',(1.,0.,0.));
+#2570=DIRECTION('ref_axis',(0.,-1.,0.));
+#2571=DIRECTION('',(0.,-1.,0.));
+#2572=DIRECTION('',(0.,0.,-1.));
+#2573=DIRECTION('center_axis',(0.,0.,-1.));
+#2574=DIRECTION('ref_axis',(0.,1.,0.));
+#2575=DIRECTION('center_axis',(0.,0.,1.));
+#2576=DIRECTION('ref_axis',(0.,1.,0.));
+#2577=DIRECTION('',(0.,0.,-1.));
+#2578=DIRECTION('center_axis',(0.,-1.,0.));
+#2579=DIRECTION('ref_axis',(-1.,0.,0.));
+#2580=DIRECTION('',(-1.,0.,0.));
+#2581=DIRECTION('',(0.,0.,-1.));
+#2582=DIRECTION('center_axis',(0.,0.,-1.));
+#2583=DIRECTION('ref_axis',(1.,0.,0.));
+#2584=DIRECTION('center_axis',(0.,0.,1.));
+#2585=DIRECTION('ref_axis',(1.,0.,0.));
+#2586=DIRECTION('',(0.,0.,-1.));
+#2587=DIRECTION('center_axis',(-1.,0.,0.));
+#2588=DIRECTION('ref_axis',(0.,1.,0.));
+#2589=DIRECTION('',(0.,1.,0.));
+#2590=DIRECTION('center_axis',(0.,0.,-1.));
+#2591=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#2592=DIRECTION('',(0.,0.,-1.));
+#2593=DIRECTION('center_axis',(0.,0.,1.));
+#2594=DIRECTION('ref_axis',(3.55271367880051E-14,-1.,0.));
+#2595=DIRECTION('',(0.,0.,-1.));
+#2596=DIRECTION('center_axis',(0.,1.,0.));
+#2597=DIRECTION('ref_axis',(1.,0.,0.));
+#2598=DIRECTION('',(1.,0.,0.));
+#2599=DIRECTION('',(0.,0.,-1.));
+#2600=DIRECTION('center_axis',(0.,0.,-1.));
+#2601=DIRECTION('ref_axis',(-1.,0.,0.));
+#2602=DIRECTION('center_axis',(0.,0.,1.));
+#2603=DIRECTION('ref_axis',(-1.,0.,0.));
+#2604=DIRECTION('',(0.,0.,-1.));
+#2605=DIRECTION('center_axis',(1.,0.,0.));
+#2606=DIRECTION('ref_axis',(0.,-1.,0.));
+#2607=DIRECTION('',(0.,-1.,0.));
+#2608=DIRECTION('',(0.,0.,-1.));
+#2609=DIRECTION('center_axis',(0.,0.,-1.));
+#2610=DIRECTION('ref_axis',(0.,1.,0.));
+#2611=DIRECTION('center_axis',(0.,0.,1.));
+#2612=DIRECTION('ref_axis',(0.,1.,0.));
+#2613=DIRECTION('',(0.,0.,-1.));
+#2614=DIRECTION('center_axis',(0.,-1.,0.));
+#2615=DIRECTION('ref_axis',(-1.,0.,0.));
+#2616=DIRECTION('',(-1.,0.,0.));
+#2617=DIRECTION('',(0.,0.,-1.));
+#2618=DIRECTION('center_axis',(0.,0.,-1.));
+#2619=DIRECTION('ref_axis',(1.,0.,0.));
+#2620=DIRECTION('center_axis',(0.,0.,1.));
+#2621=DIRECTION('ref_axis',(1.,0.,0.));
+#2622=DIRECTION('',(0.,0.,-1.));
+#2623=DIRECTION('center_axis',(-1.,0.,0.));
+#2624=DIRECTION('ref_axis',(0.,1.,0.));
+#2625=DIRECTION('',(0.,1.,0.));
+#2626=DIRECTION('center_axis',(0.,1.,0.));
+#2627=DIRECTION('ref_axis',(1.,0.,0.));
+#2628=DIRECTION('',(0.,0.,-1.));
+#2629=DIRECTION('',(1.,0.,0.));
+#2630=DIRECTION('',(0.,0.,-1.));
+#2631=DIRECTION('center_axis',(1.,0.,0.));
+#2632=DIRECTION('ref_axis',(0.,-1.,0.));
+#2633=DIRECTION('',(0.,-1.,0.));
+#2634=DIRECTION('',(0.,0.,-1.));
+#2635=DIRECTION('center_axis',(0.,-1.,0.));
+#2636=DIRECTION('ref_axis',(-1.,0.,0.));
+#2637=DIRECTION('',(-1.,0.,0.));
+#2638=DIRECTION('',(0.,0.,-1.));
+#2639=DIRECTION('center_axis',(-1.,0.,0.));
+#2640=DIRECTION('ref_axis',(0.,1.,0.));
+#2641=DIRECTION('',(0.,1.,0.));
+#2642=DIRECTION('center_axis',(0.00211883867752521,0.99999775525881,0.));
+#2643=DIRECTION('ref_axis',(0.99999775525881,-0.00211883867752521,0.));
+#2644=DIRECTION('',(0.,0.,-1.));
+#2645=DIRECTION('',(0.99999775525881,-0.00211883867752521,0.));
+#2646=DIRECTION('',(0.,0.,-1.));
+#2647=DIRECTION('center_axis',(0.99999775525881,-0.00211883867752538,0.));
+#2648=DIRECTION('ref_axis',(-0.00211883867752538,-0.99999775525881,0.));
+#2649=DIRECTION('',(-0.00211883867752538,-0.99999775525881,0.));
+#2650=DIRECTION('center_axis',(-1.,0.,0.));
+#2651=DIRECTION('ref_axis',(0.,1.,0.));
+#2652=DIRECTION('',(0.,1.,0.));
+#2653=DIRECTION('center_axis',(1.,0.,0.));
+#2654=DIRECTION('ref_axis',(0.,-1.,0.));
+#2655=DIRECTION('',(0.,-1.,0.));
+#2656=DIRECTION('center_axis',(-0.99999775525881,0.00211883867751913,0.));
+#2657=DIRECTION('ref_axis',(0.00211883867751913,0.99999775525881,0.));
+#2658=DIRECTION('',(0.00211883867751913,0.99999775525881,0.));
+#2659=DIRECTION('center_axis',(0.,0.,1.));
+#2660=DIRECTION('ref_axis',(1.,0.,0.));
+#2661=CARTESIAN_POINT('',(0.,0.,0.));
+#2662=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#2663=CARTESIAN_POINT('',(-5.,79.06,18.));
+#2664=CARTESIAN_POINT('',(-10.,74.06,18.));
+#2665=CARTESIAN_POINT('Origin',(-5.,74.06,18.));
+#2666=CARTESIAN_POINT('',(-10.,74.06,21.));
+#2667=CARTESIAN_POINT('',(-10.,74.06,21.));
+#2668=CARTESIAN_POINT('',(-5.,79.06,21.));
+#2669=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#2670=CARTESIAN_POINT('',(-5.,79.06,21.));
+#2671=CARTESIAN_POINT('Origin',(-10.,79.06,21.));
+#2672=CARTESIAN_POINT('',(4.24033755187631,79.06,21.));
+#2673=CARTESIAN_POINT('',(75.89,79.06,21.));
+#2674=CARTESIAN_POINT('',(4.24033755187631,79.06,18.));
+#2675=CARTESIAN_POINT('',(4.24033755187631,79.06,21.));
+#2676=CARTESIAN_POINT('',(75.89,79.06,18.));
+#2677=CARTESIAN_POINT('Origin',(47.26,34.53,21.));
+#2678=CARTESIAN_POINT('',(-10.,-5.,21.));
+#2679=CARTESIAN_POINT('',(-10.,56.795,21.));
+#2680=CARTESIAN_POINT('',(-5.,-10.,21.));
+#2681=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#2682=CARTESIAN_POINT('',(99.52,-10.,21.));
+#2683=CARTESIAN_POINT('',(18.63,-10.,21.));
+#2684=CARTESIAN_POINT('',(104.52,-5.,21.));
+#2685=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#2686=CARTESIAN_POINT('',(104.52,74.06,21.));
+#2687=CARTESIAN_POINT('',(104.52,12.265,21.));
+#2688=CARTESIAN_POINT('',(99.52,79.06,21.));
+#2689=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#2690=CARTESIAN_POINT('',(23.4403267770942,79.06,21.));
+#2691=CARTESIAN_POINT('',(75.89,79.06,21.));
+#2692=CARTESIAN_POINT('',(23.3634045213564,42.7561115145685,21.));
+#2693=CARTESIAN_POINT('',(23.3952026224009,57.7634030103233,21.));
+#2694=CARTESIAN_POINT('',(4.16350149405484,42.7967931030271,21.));
+#2695=CARTESIAN_POINT('',(37.720358113746,42.7256913777202,21.));
+#2696=CARTESIAN_POINT('',(4.15484025360816,38.7090722697651,21.));
+#2697=CARTESIAN_POINT('',(65.245,59.545,21.));
+#2698=CARTESIAN_POINT('',(65.245,47.045,21.));
+#2699=CARTESIAN_POINT('',(65.245,46.9375,21.));
+#2700=CARTESIAN_POINT('',(26.545,47.045,21.));
+#2701=CARTESIAN_POINT('',(56.1525,47.045,21.));
+#2702=CARTESIAN_POINT('',(26.545,59.545,21.));
+#2703=CARTESIAN_POINT('',(26.545,40.8875,21.));
+#2704=CARTESIAN_POINT('',(37.0025,59.545,21.));
+#2705=CARTESIAN_POINT('',(87.61,59.79,21.));
+#2706=CARTESIAN_POINT('',(87.61,46.79,21.));
+#2707=CARTESIAN_POINT('',(87.61,47.16,21.));
+#2708=CARTESIAN_POINT('',(87.11,46.29,21.));
+#2709=CARTESIAN_POINT('Origin',(87.11,46.79,21.));
+#2710=CARTESIAN_POINT('',(74.11,46.29,21.));
+#2711=CARTESIAN_POINT('',(67.185,46.29,21.));
+#2712=CARTESIAN_POINT('',(73.61,46.79,21.));
+#2713=CARTESIAN_POINT('Origin',(74.11,46.79,21.));
+#2714=CARTESIAN_POINT('',(73.61,59.79,21.));
+#2715=CARTESIAN_POINT('',(73.61,40.66,21.));
+#2716=CARTESIAN_POINT('',(74.11,60.29,21.));
+#2717=CARTESIAN_POINT('Origin',(74.11,59.79,21.));
+#2718=CARTESIAN_POINT('',(87.11,60.29,21.));
+#2719=CARTESIAN_POINT('',(60.685,60.29,21.));
+#2720=CARTESIAN_POINT('Origin',(87.11,59.79,21.));
+#2721=CARTESIAN_POINT('',(58.835,39.59,21.));
+#2722=CARTESIAN_POINT('',(58.835,26.59,21.));
+#2723=CARTESIAN_POINT('',(58.835,37.06,21.));
+#2724=CARTESIAN_POINT('',(58.335,26.09,21.));
+#2725=CARTESIAN_POINT('Origin',(58.335,26.59,21.));
+#2726=CARTESIAN_POINT('',(45.335,26.09,21.));
+#2727=CARTESIAN_POINT('',(52.7975,26.09,21.));
+#2728=CARTESIAN_POINT('',(44.835,26.59,21.));
+#2729=CARTESIAN_POINT('Origin',(45.335,26.59,21.));
+#2730=CARTESIAN_POINT('',(44.835,39.59,21.));
+#2731=CARTESIAN_POINT('',(44.835,30.56,21.));
+#2732=CARTESIAN_POINT('',(45.335,40.09,21.));
+#2733=CARTESIAN_POINT('Origin',(45.335,39.59,21.));
+#2734=CARTESIAN_POINT('',(58.335,40.09,21.));
+#2735=CARTESIAN_POINT('',(46.2975,40.09,21.));
+#2736=CARTESIAN_POINT('Origin',(58.335,39.59,21.));
+#2737=CARTESIAN_POINT('',(39.785,39.59,21.));
+#2738=CARTESIAN_POINT('',(39.785,26.59,21.));
+#2739=CARTESIAN_POINT('',(39.785,37.06,21.));
+#2740=CARTESIAN_POINT('',(39.285,26.09,21.));
+#2741=CARTESIAN_POINT('Origin',(39.285,26.59,21.));
+#2742=CARTESIAN_POINT('',(26.285,26.09,21.));
+#2743=CARTESIAN_POINT('',(43.2725,26.09,21.));
+#2744=CARTESIAN_POINT('',(25.785,26.59,21.));
+#2745=CARTESIAN_POINT('Origin',(26.285,26.59,21.));
+#2746=CARTESIAN_POINT('',(25.785,39.59,21.));
+#2747=CARTESIAN_POINT('',(25.785,30.56,21.));
+#2748=CARTESIAN_POINT('',(26.285,40.09,21.));
+#2749=CARTESIAN_POINT('Origin',(26.285,39.59,21.));
+#2750=CARTESIAN_POINT('',(39.285,40.09,21.));
+#2751=CARTESIAN_POINT('',(36.7725,40.09,21.));
+#2752=CARTESIAN_POINT('Origin',(39.285,39.59,21.));
+#2753=CARTESIAN_POINT('',(20.735,20.54,21.));
+#2754=CARTESIAN_POINT('',(20.735,7.54,21.));
+#2755=CARTESIAN_POINT('',(20.735,27.535,21.));
+#2756=CARTESIAN_POINT('',(20.235,7.04,21.));
+#2757=CARTESIAN_POINT('Origin',(20.235,7.54,21.));
+#2758=CARTESIAN_POINT('',(7.235,7.04000000000001,21.));
+#2759=CARTESIAN_POINT('',(33.7475,7.04,21.));
+#2760=CARTESIAN_POINT('',(6.735,7.54,21.));
+#2761=CARTESIAN_POINT('Origin',(7.235,7.54,21.));
+#2762=CARTESIAN_POINT('',(6.735,20.54,21.));
+#2763=CARTESIAN_POINT('',(6.735,21.035,21.));
+#2764=CARTESIAN_POINT('',(7.235,21.04,21.));
+#2765=CARTESIAN_POINT('Origin',(7.235,20.54,21.));
+#2766=CARTESIAN_POINT('',(20.235,21.04,21.));
+#2767=CARTESIAN_POINT('',(27.2475,21.04,21.));
+#2768=CARTESIAN_POINT('Origin',(20.235,20.54,21.));
+#2769=CARTESIAN_POINT('',(87.41,20.54,21.));
+#2770=CARTESIAN_POINT('',(87.41,7.54,21.));
+#2771=CARTESIAN_POINT('',(87.41,27.535,21.));
+#2772=CARTESIAN_POINT('',(86.91,7.04,21.));
+#2773=CARTESIAN_POINT('Origin',(86.91,7.54,21.));
+#2774=CARTESIAN_POINT('',(73.91,7.04000000000001,21.));
+#2775=CARTESIAN_POINT('',(67.085,7.04,21.));
+#2776=CARTESIAN_POINT('',(73.41,7.54,21.));
+#2777=CARTESIAN_POINT('Origin',(73.91,7.54,21.));
+#2778=CARTESIAN_POINT('',(73.41,20.54,21.));
+#2779=CARTESIAN_POINT('',(73.41,21.035,21.));
+#2780=CARTESIAN_POINT('',(73.91,21.04,21.));
+#2781=CARTESIAN_POINT('Origin',(73.91,20.54,21.));
+#2782=CARTESIAN_POINT('',(86.91,21.04,21.));
+#2783=CARTESIAN_POINT('',(60.585,21.04,21.));
+#2784=CARTESIAN_POINT('Origin',(86.91,20.54,21.));
+#2785=CARTESIAN_POINT('',(58.835,20.54,21.));
+#2786=CARTESIAN_POINT('',(58.835,7.54,21.));
+#2787=CARTESIAN_POINT('',(58.835,27.535,21.));
+#2788=CARTESIAN_POINT('',(58.335,7.04,21.));
+#2789=CARTESIAN_POINT('Origin',(58.335,7.54,21.));
+#2790=CARTESIAN_POINT('',(45.335,7.04000000000001,21.));
+#2791=CARTESIAN_POINT('',(52.7975,7.04,21.));
+#2792=CARTESIAN_POINT('',(44.835,7.54,21.));
+#2793=CARTESIAN_POINT('Origin',(45.335,7.54,21.));
+#2794=CARTESIAN_POINT('',(44.835,20.54,21.));
+#2795=CARTESIAN_POINT('',(44.835,21.035,21.));
+#2796=CARTESIAN_POINT('',(45.335,21.04,21.));
+#2797=CARTESIAN_POINT('Origin',(45.335,20.54,21.));
+#2798=CARTESIAN_POINT('',(58.335,21.04,21.));
+#2799=CARTESIAN_POINT('',(46.2975,21.04,21.));
+#2800=CARTESIAN_POINT('Origin',(58.335,20.54,21.));
+#2801=CARTESIAN_POINT('',(20.735,39.59,21.));
+#2802=CARTESIAN_POINT('',(20.735,26.59,21.));
+#2803=CARTESIAN_POINT('',(20.735,37.06,21.));
+#2804=CARTESIAN_POINT('',(20.235,26.09,21.));
+#2805=CARTESIAN_POINT('Origin',(20.235,26.59,21.));
+#2806=CARTESIAN_POINT('',(7.235,26.09,21.));
+#2807=CARTESIAN_POINT('',(33.7475,26.09,21.));
+#2808=CARTESIAN_POINT('',(6.735,26.59,21.));
+#2809=CARTESIAN_POINT('Origin',(7.235,26.59,21.));
+#2810=CARTESIAN_POINT('',(6.735,39.59,21.));
+#2811=CARTESIAN_POINT('',(6.735,30.56,21.));
+#2812=CARTESIAN_POINT('',(7.235,40.09,21.));
+#2813=CARTESIAN_POINT('Origin',(7.235,39.59,21.));
+#2814=CARTESIAN_POINT('',(20.235,40.09,21.));
+#2815=CARTESIAN_POINT('',(27.2475,40.09,21.));
+#2816=CARTESIAN_POINT('Origin',(20.235,39.59,21.));
+#2817=CARTESIAN_POINT('',(39.785,20.54,21.));
+#2818=CARTESIAN_POINT('',(39.785,7.54,21.));
+#2819=CARTESIAN_POINT('',(39.785,27.535,21.));
+#2820=CARTESIAN_POINT('',(39.285,7.04,21.));
+#2821=CARTESIAN_POINT('Origin',(39.285,7.54,21.));
+#2822=CARTESIAN_POINT('',(26.285,7.04000000000001,21.));
+#2823=CARTESIAN_POINT('',(43.2725,7.04,21.));
+#2824=CARTESIAN_POINT('',(25.785,7.54,21.));
+#2825=CARTESIAN_POINT('Origin',(26.285,7.54,21.));
+#2826=CARTESIAN_POINT('',(25.785,20.54,21.));
+#2827=CARTESIAN_POINT('',(25.785,21.035,21.));
+#2828=CARTESIAN_POINT('',(26.285,21.04,21.));
+#2829=CARTESIAN_POINT('Origin',(26.285,20.54,21.));
+#2830=CARTESIAN_POINT('',(39.285,21.04,21.));
+#2831=CARTESIAN_POINT('',(36.7725,21.04,21.));
+#2832=CARTESIAN_POINT('Origin',(39.285,20.54,21.));
+#2833=CARTESIAN_POINT('',(87.41,39.59,21.));
+#2834=CARTESIAN_POINT('',(87.41,26.59,21.));
+#2835=CARTESIAN_POINT('',(87.41,37.06,21.));
+#2836=CARTESIAN_POINT('',(86.91,26.09,21.));
+#2837=CARTESIAN_POINT('Origin',(86.91,26.59,21.));
+#2838=CARTESIAN_POINT('',(73.91,26.09,21.));
+#2839=CARTESIAN_POINT('',(67.085,26.09,21.));
+#2840=CARTESIAN_POINT('',(73.41,26.59,21.));
+#2841=CARTESIAN_POINT('Origin',(73.91,26.59,21.));
+#2842=CARTESIAN_POINT('',(73.41,39.59,21.));
+#2843=CARTESIAN_POINT('',(73.41,30.56,21.));
+#2844=CARTESIAN_POINT('',(73.91,40.09,21.));
+#2845=CARTESIAN_POINT('Origin',(73.91,39.59,21.));
+#2846=CARTESIAN_POINT('',(86.91,40.09,21.));
+#2847=CARTESIAN_POINT('',(60.585,40.09,21.));
+#2848=CARTESIAN_POINT('Origin',(86.91,39.59,21.));
+#2849=CARTESIAN_POINT('',(-6.4500000745058,74.16,21.));
+#2850=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#2851=CARTESIAN_POINT('',(98.17,74.16,21.));
+#2852=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#2853=CARTESIAN_POINT('',(-6.54999999999999,-5.10000000000001,21.));
+#2854=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#2855=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#2856=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#2857=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#2858=CARTESIAN_POINT('',(-10.,-5.,18.));
+#2859=CARTESIAN_POINT('',(-5.,-10.,18.));
+#2860=CARTESIAN_POINT('Origin',(-5.,-5.,18.));
+#2861=CARTESIAN_POINT('',(-5.,-10.,21.));
+#2862=CARTESIAN_POINT('',(-10.,-5.,21.));
+#2863=CARTESIAN_POINT('Origin',(104.52,-10.,21.));
+#2864=CARTESIAN_POINT('',(99.52,-10.,18.));
+#2865=CARTESIAN_POINT('',(18.63,-10.,18.));
+#2866=CARTESIAN_POINT('',(99.52,-10.,21.));
+#2867=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#2868=CARTESIAN_POINT('',(104.52,-5.,18.));
+#2869=CARTESIAN_POINT('Origin',(99.52,-5.,18.));
+#2870=CARTESIAN_POINT('',(104.52,-5.,21.));
+#2871=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#2872=CARTESIAN_POINT('',(104.52,74.06,18.));
+#2873=CARTESIAN_POINT('',(99.52,79.06,18.));
+#2874=CARTESIAN_POINT('Origin',(99.52,74.06,18.));
+#2875=CARTESIAN_POINT('',(99.52,79.06,21.));
+#2876=CARTESIAN_POINT('',(104.52,74.06,21.));
+#2877=CARTESIAN_POINT('Origin',(23.4403267770942,79.06,21.));
+#2878=CARTESIAN_POINT('',(23.4403267770942,79.06,18.));
+#2879=CARTESIAN_POINT('',(75.89,79.06,18.));
+#2880=CARTESIAN_POINT('',(23.4403267770942,79.06,21.));
+#2881=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#2882=CARTESIAN_POINT('',(98.17,-5.1,18.));
+#2883=CARTESIAN_POINT('Origin',(99.62,-5.1,18.));
+#2884=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#2885=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#2886=CARTESIAN_POINT('',(-6.54999999999999,-5.1,18.));
+#2887=CARTESIAN_POINT('Origin',(-5.1,-5.1,18.));
+#2888=CARTESIAN_POINT('',(-6.55,-5.1,21.));
+#2889=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#2890=CARTESIAN_POINT('',(98.17,74.16,18.));
+#2891=CARTESIAN_POINT('Origin',(99.62,74.16,18.));
+#2892=CARTESIAN_POINT('',(98.17,74.16,21.));
+#2893=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#2894=CARTESIAN_POINT('',(-6.4500000745058,74.16,18.));
+#2895=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,18.));
+#2896=CARTESIAN_POINT('',(-6.45000007450581,74.16,21.));
+#2897=CARTESIAN_POINT('Origin',(86.91,26.59,21.));
+#2898=CARTESIAN_POINT('',(87.41,26.59,18.));
+#2899=CARTESIAN_POINT('',(87.41,26.59,21.));
+#2900=CARTESIAN_POINT('',(86.91,26.09,18.));
+#2901=CARTESIAN_POINT('Origin',(86.91,26.59,18.));
+#2902=CARTESIAN_POINT('',(86.91,26.09,21.));
+#2903=CARTESIAN_POINT('Origin',(73.91,26.09,21.));
+#2904=CARTESIAN_POINT('',(73.91,26.09,18.));
+#2905=CARTESIAN_POINT('',(67.085,26.09,18.));
+#2906=CARTESIAN_POINT('',(73.91,26.09,21.));
+#2907=CARTESIAN_POINT('Origin',(73.91,26.59,21.));
+#2908=CARTESIAN_POINT('',(73.41,26.59,18.));
+#2909=CARTESIAN_POINT('Origin',(73.91,26.59,18.));
+#2910=CARTESIAN_POINT('',(73.41,26.59,21.));
+#2911=CARTESIAN_POINT('Origin',(73.41,39.59,21.));
+#2912=CARTESIAN_POINT('',(73.41,39.59,18.));
+#2913=CARTESIAN_POINT('',(73.41,30.56,18.));
+#2914=CARTESIAN_POINT('',(73.41,39.59,21.));
+#2915=CARTESIAN_POINT('Origin',(73.91,39.59,21.));
+#2916=CARTESIAN_POINT('',(73.91,40.09,18.));
+#2917=CARTESIAN_POINT('Origin',(73.91,39.59,18.));
+#2918=CARTESIAN_POINT('',(73.91,40.09,21.));
+#2919=CARTESIAN_POINT('Origin',(86.91,40.09,21.));
+#2920=CARTESIAN_POINT('',(86.91,40.09,18.));
+#2921=CARTESIAN_POINT('',(60.585,40.09,18.));
+#2922=CARTESIAN_POINT('',(86.91,40.09,21.));
+#2923=CARTESIAN_POINT('Origin',(86.91,39.59,21.));
+#2924=CARTESIAN_POINT('',(87.41,39.59,18.));
+#2925=CARTESIAN_POINT('Origin',(86.91,39.59,18.));
+#2926=CARTESIAN_POINT('',(87.41,39.59,21.));
+#2927=CARTESIAN_POINT('Origin',(87.41,26.59,21.));
+#2928=CARTESIAN_POINT('',(87.41,37.06,18.));
+#2929=CARTESIAN_POINT('Origin',(39.285,7.54,21.));
+#2930=CARTESIAN_POINT('',(39.785,7.54,18.));
+#2931=CARTESIAN_POINT('',(39.785,7.54,21.));
+#2932=CARTESIAN_POINT('',(39.285,7.04000000000001,18.));
+#2933=CARTESIAN_POINT('Origin',(39.285,7.54,18.));
+#2934=CARTESIAN_POINT('',(39.285,7.04,21.));
+#2935=CARTESIAN_POINT('Origin',(26.285,7.04,21.));
+#2936=CARTESIAN_POINT('',(26.285,7.04000000000001,18.));
+#2937=CARTESIAN_POINT('',(43.2725,7.04,18.));
+#2938=CARTESIAN_POINT('',(26.285,7.04000000000001,21.));
+#2939=CARTESIAN_POINT('Origin',(26.285,7.54,21.));
+#2940=CARTESIAN_POINT('',(25.785,7.54,18.));
+#2941=CARTESIAN_POINT('Origin',(26.285,7.54,18.));
+#2942=CARTESIAN_POINT('',(25.785,7.54,21.));
+#2943=CARTESIAN_POINT('Origin',(25.785,20.54,21.));
+#2944=CARTESIAN_POINT('',(25.785,20.54,18.));
+#2945=CARTESIAN_POINT('',(25.785,21.035,18.));
+#2946=CARTESIAN_POINT('',(25.785,20.54,21.));
+#2947=CARTESIAN_POINT('Origin',(26.285,20.54,21.));
+#2948=CARTESIAN_POINT('',(26.285,21.04,18.));
+#2949=CARTESIAN_POINT('Origin',(26.285,20.54,18.));
+#2950=CARTESIAN_POINT('',(26.285,21.04,21.));
+#2951=CARTESIAN_POINT('Origin',(39.285,21.04,21.));
+#2952=CARTESIAN_POINT('',(39.285,21.04,18.));
+#2953=CARTESIAN_POINT('',(36.7725,21.04,18.));
+#2954=CARTESIAN_POINT('',(39.285,21.04,21.));
+#2955=CARTESIAN_POINT('Origin',(39.285,20.54,21.));
+#2956=CARTESIAN_POINT('',(39.785,20.54,18.));
+#2957=CARTESIAN_POINT('Origin',(39.285,20.54,18.));
+#2958=CARTESIAN_POINT('',(39.785,20.54,21.));
+#2959=CARTESIAN_POINT('Origin',(39.785,7.54,21.));
+#2960=CARTESIAN_POINT('',(39.785,27.535,18.));
+#2961=CARTESIAN_POINT('Origin',(20.235,26.59,21.));
+#2962=CARTESIAN_POINT('',(20.735,26.59,18.));
+#2963=CARTESIAN_POINT('',(20.735,26.59,21.));
+#2964=CARTESIAN_POINT('',(20.235,26.09,18.));
+#2965=CARTESIAN_POINT('Origin',(20.235,26.59,18.));
+#2966=CARTESIAN_POINT('',(20.235,26.09,21.));
+#2967=CARTESIAN_POINT('Origin',(7.235,26.09,21.));
+#2968=CARTESIAN_POINT('',(7.235,26.09,18.));
+#2969=CARTESIAN_POINT('',(33.7475,26.09,18.));
+#2970=CARTESIAN_POINT('',(7.235,26.09,21.));
+#2971=CARTESIAN_POINT('Origin',(7.235,26.59,21.));
+#2972=CARTESIAN_POINT('',(6.735,26.59,18.));
+#2973=CARTESIAN_POINT('Origin',(7.235,26.59,18.));
+#2974=CARTESIAN_POINT('',(6.735,26.59,21.));
+#2975=CARTESIAN_POINT('Origin',(6.735,39.59,21.));
+#2976=CARTESIAN_POINT('',(6.735,39.59,18.));
+#2977=CARTESIAN_POINT('',(6.735,30.56,18.));
+#2978=CARTESIAN_POINT('',(6.735,39.59,21.));
+#2979=CARTESIAN_POINT('Origin',(7.235,39.59,21.));
+#2980=CARTESIAN_POINT('',(7.235,40.09,18.));
+#2981=CARTESIAN_POINT('Origin',(7.235,39.59,18.));
+#2982=CARTESIAN_POINT('',(7.235,40.09,21.));
+#2983=CARTESIAN_POINT('Origin',(20.235,40.09,21.));
+#2984=CARTESIAN_POINT('',(20.235,40.09,18.));
+#2985=CARTESIAN_POINT('',(27.2475,40.09,18.));
+#2986=CARTESIAN_POINT('',(20.235,40.09,21.));
+#2987=CARTESIAN_POINT('Origin',(20.235,39.59,21.));
+#2988=CARTESIAN_POINT('',(20.735,39.59,18.));
+#2989=CARTESIAN_POINT('Origin',(20.235,39.59,18.));
+#2990=CARTESIAN_POINT('',(20.735,39.59,21.));
+#2991=CARTESIAN_POINT('Origin',(20.735,26.59,21.));
+#2992=CARTESIAN_POINT('',(20.735,37.06,18.));
+#2993=CARTESIAN_POINT('Origin',(58.335,7.54,21.));
+#2994=CARTESIAN_POINT('',(58.835,7.54,18.));
+#2995=CARTESIAN_POINT('',(58.835,7.54,21.));
+#2996=CARTESIAN_POINT('',(58.335,7.04000000000001,18.));
+#2997=CARTESIAN_POINT('Origin',(58.335,7.54,18.));
+#2998=CARTESIAN_POINT('',(58.335,7.04,21.));
+#2999=CARTESIAN_POINT('Origin',(45.335,7.04,21.));
+#3000=CARTESIAN_POINT('',(45.335,7.04000000000001,18.));
+#3001=CARTESIAN_POINT('',(52.7975,7.04,18.));
+#3002=CARTESIAN_POINT('',(45.335,7.04000000000001,21.));
+#3003=CARTESIAN_POINT('Origin',(45.335,7.54,21.));
+#3004=CARTESIAN_POINT('',(44.835,7.54,18.));
+#3005=CARTESIAN_POINT('Origin',(45.335,7.54,18.));
+#3006=CARTESIAN_POINT('',(44.835,7.54,21.));
+#3007=CARTESIAN_POINT('Origin',(44.835,20.54,21.));
+#3008=CARTESIAN_POINT('',(44.835,20.54,18.));
+#3009=CARTESIAN_POINT('',(44.835,21.035,18.));
+#3010=CARTESIAN_POINT('',(44.835,20.54,21.));
+#3011=CARTESIAN_POINT('Origin',(45.335,20.54,21.));
+#3012=CARTESIAN_POINT('',(45.335,21.04,18.));
+#3013=CARTESIAN_POINT('Origin',(45.335,20.54,18.));
+#3014=CARTESIAN_POINT('',(45.335,21.04,21.));
+#3015=CARTESIAN_POINT('Origin',(58.335,21.04,21.));
+#3016=CARTESIAN_POINT('',(58.335,21.04,18.));
+#3017=CARTESIAN_POINT('',(46.2975,21.04,18.));
+#3018=CARTESIAN_POINT('',(58.335,21.04,21.));
+#3019=CARTESIAN_POINT('Origin',(58.335,20.54,21.));
+#3020=CARTESIAN_POINT('',(58.835,20.54,18.));
+#3021=CARTESIAN_POINT('Origin',(58.335,20.54,18.));
+#3022=CARTESIAN_POINT('',(58.835,20.54,21.));
+#3023=CARTESIAN_POINT('Origin',(58.835,7.54,21.));
+#3024=CARTESIAN_POINT('',(58.835,27.535,18.));
+#3025=CARTESIAN_POINT('Origin',(86.91,7.54,21.));
+#3026=CARTESIAN_POINT('',(87.41,7.54,18.));
+#3027=CARTESIAN_POINT('',(87.41,7.54,21.));
+#3028=CARTESIAN_POINT('',(86.91,7.04000000000001,18.));
+#3029=CARTESIAN_POINT('Origin',(86.91,7.54,18.));
+#3030=CARTESIAN_POINT('',(86.91,7.04,21.));
+#3031=CARTESIAN_POINT('Origin',(73.91,7.04,21.));
+#3032=CARTESIAN_POINT('',(73.91,7.04000000000001,18.));
+#3033=CARTESIAN_POINT('',(67.085,7.04,18.));
+#3034=CARTESIAN_POINT('',(73.91,7.04000000000001,21.));
+#3035=CARTESIAN_POINT('Origin',(73.91,7.54,21.));
+#3036=CARTESIAN_POINT('',(73.41,7.54,18.));
+#3037=CARTESIAN_POINT('Origin',(73.91,7.54,18.));
+#3038=CARTESIAN_POINT('',(73.41,7.54,21.));
+#3039=CARTESIAN_POINT('Origin',(73.41,20.54,21.));
+#3040=CARTESIAN_POINT('',(73.41,20.54,18.));
+#3041=CARTESIAN_POINT('',(73.41,21.035,18.));
+#3042=CARTESIAN_POINT('',(73.41,20.54,21.));
+#3043=CARTESIAN_POINT('Origin',(73.91,20.54,21.));
+#3044=CARTESIAN_POINT('',(73.91,21.04,18.));
+#3045=CARTESIAN_POINT('Origin',(73.91,20.54,18.));
+#3046=CARTESIAN_POINT('',(73.91,21.04,21.));
+#3047=CARTESIAN_POINT('Origin',(86.91,21.04,21.));
+#3048=CARTESIAN_POINT('',(86.91,21.04,18.));
+#3049=CARTESIAN_POINT('',(60.585,21.04,18.));
+#3050=CARTESIAN_POINT('',(86.91,21.04,21.));
+#3051=CARTESIAN_POINT('Origin',(86.91,20.54,21.));
+#3052=CARTESIAN_POINT('',(87.41,20.54,18.));
+#3053=CARTESIAN_POINT('Origin',(86.91,20.54,18.));
+#3054=CARTESIAN_POINT('',(87.41,20.54,21.));
+#3055=CARTESIAN_POINT('Origin',(87.41,7.54,21.));
+#3056=CARTESIAN_POINT('',(87.41,27.535,18.));
+#3057=CARTESIAN_POINT('Origin',(20.235,7.54,21.));
+#3058=CARTESIAN_POINT('',(20.735,7.54,18.));
+#3059=CARTESIAN_POINT('',(20.735,7.54,21.));
+#3060=CARTESIAN_POINT('',(20.235,7.04000000000001,18.));
+#3061=CARTESIAN_POINT('Origin',(20.235,7.54,18.));
+#3062=CARTESIAN_POINT('',(20.235,7.04,21.));
+#3063=CARTESIAN_POINT('Origin',(7.235,7.04,21.));
+#3064=CARTESIAN_POINT('',(7.235,7.04000000000001,18.));
+#3065=CARTESIAN_POINT('',(33.7475,7.04,18.));
+#3066=CARTESIAN_POINT('',(7.235,7.04000000000001,21.));
+#3067=CARTESIAN_POINT('Origin',(7.235,7.54,21.));
+#3068=CARTESIAN_POINT('',(6.735,7.54,18.));
+#3069=CARTESIAN_POINT('Origin',(7.235,7.54,18.));
+#3070=CARTESIAN_POINT('',(6.735,7.54,21.));
+#3071=CARTESIAN_POINT('Origin',(6.735,20.54,21.));
+#3072=CARTESIAN_POINT('',(6.735,20.54,18.));
+#3073=CARTESIAN_POINT('',(6.735,21.035,18.));
+#3074=CARTESIAN_POINT('',(6.735,20.54,21.));
+#3075=CARTESIAN_POINT('Origin',(7.235,20.54,21.));
+#3076=CARTESIAN_POINT('',(7.235,21.04,18.));
+#3077=CARTESIAN_POINT('Origin',(7.235,20.54,18.));
+#3078=CARTESIAN_POINT('',(7.235,21.04,21.));
+#3079=CARTESIAN_POINT('Origin',(20.235,21.04,21.));
+#3080=CARTESIAN_POINT('',(20.235,21.04,18.));
+#3081=CARTESIAN_POINT('',(27.2475,21.04,18.));
+#3082=CARTESIAN_POINT('',(20.235,21.04,21.));
+#3083=CARTESIAN_POINT('Origin',(20.235,20.54,21.));
+#3084=CARTESIAN_POINT('',(20.735,20.54,18.));
+#3085=CARTESIAN_POINT('Origin',(20.235,20.54,18.));
+#3086=CARTESIAN_POINT('',(20.735,20.54,21.));
+#3087=CARTESIAN_POINT('Origin',(20.735,7.54,21.));
+#3088=CARTESIAN_POINT('',(20.735,27.535,18.));
+#3089=CARTESIAN_POINT('Origin',(39.285,26.59,21.));
+#3090=CARTESIAN_POINT('',(39.785,26.59,18.));
+#3091=CARTESIAN_POINT('',(39.785,26.59,21.));
+#3092=CARTESIAN_POINT('',(39.285,26.09,18.));
+#3093=CARTESIAN_POINT('Origin',(39.285,26.59,18.));
+#3094=CARTESIAN_POINT('',(39.285,26.09,21.));
+#3095=CARTESIAN_POINT('Origin',(26.285,26.09,21.));
+#3096=CARTESIAN_POINT('',(26.285,26.09,18.));
+#3097=CARTESIAN_POINT('',(43.2725,26.09,18.));
+#3098=CARTESIAN_POINT('',(26.285,26.09,21.));
+#3099=CARTESIAN_POINT('Origin',(26.285,26.59,21.));
+#3100=CARTESIAN_POINT('',(25.785,26.59,18.));
+#3101=CARTESIAN_POINT('Origin',(26.285,26.59,18.));
+#3102=CARTESIAN_POINT('',(25.785,26.59,21.));
+#3103=CARTESIAN_POINT('Origin',(25.785,39.59,21.));
+#3104=CARTESIAN_POINT('',(25.785,39.59,18.));
+#3105=CARTESIAN_POINT('',(25.785,30.56,18.));
+#3106=CARTESIAN_POINT('',(25.785,39.59,21.));
+#3107=CARTESIAN_POINT('Origin',(26.285,39.59,21.));
+#3108=CARTESIAN_POINT('',(26.285,40.09,18.));
+#3109=CARTESIAN_POINT('Origin',(26.285,39.59,18.));
+#3110=CARTESIAN_POINT('',(26.285,40.09,21.));
+#3111=CARTESIAN_POINT('Origin',(39.285,40.09,21.));
+#3112=CARTESIAN_POINT('',(39.285,40.09,18.));
+#3113=CARTESIAN_POINT('',(36.7725,40.09,18.));
+#3114=CARTESIAN_POINT('',(39.285,40.09,21.));
+#3115=CARTESIAN_POINT('Origin',(39.285,39.59,21.));
+#3116=CARTESIAN_POINT('',(39.785,39.59,18.));
+#3117=CARTESIAN_POINT('Origin',(39.285,39.59,18.));
+#3118=CARTESIAN_POINT('',(39.785,39.59,21.));
+#3119=CARTESIAN_POINT('Origin',(39.785,26.59,21.));
+#3120=CARTESIAN_POINT('',(39.785,37.06,18.));
+#3121=CARTESIAN_POINT('Origin',(58.335,26.59,21.));
+#3122=CARTESIAN_POINT('',(58.835,26.59,18.));
+#3123=CARTESIAN_POINT('',(58.835,26.59,21.));
+#3124=CARTESIAN_POINT('',(58.335,26.09,18.));
+#3125=CARTESIAN_POINT('Origin',(58.335,26.59,18.));
+#3126=CARTESIAN_POINT('',(58.335,26.09,21.));
+#3127=CARTESIAN_POINT('Origin',(45.335,26.09,21.));
+#3128=CARTESIAN_POINT('',(45.335,26.09,18.));
+#3129=CARTESIAN_POINT('',(52.7975,26.09,18.));
+#3130=CARTESIAN_POINT('',(45.335,26.09,21.));
+#3131=CARTESIAN_POINT('Origin',(45.335,26.59,21.));
+#3132=CARTESIAN_POINT('',(44.835,26.59,18.));
+#3133=CARTESIAN_POINT('Origin',(45.335,26.59,18.));
+#3134=CARTESIAN_POINT('',(44.835,26.59,21.));
+#3135=CARTESIAN_POINT('Origin',(44.835,39.59,21.));
+#3136=CARTESIAN_POINT('',(44.835,39.59,18.));
+#3137=CARTESIAN_POINT('',(44.835,30.56,18.));
+#3138=CARTESIAN_POINT('',(44.835,39.59,21.));
+#3139=CARTESIAN_POINT('Origin',(45.335,39.59,21.));
+#3140=CARTESIAN_POINT('',(45.335,40.09,18.));
+#3141=CARTESIAN_POINT('Origin',(45.335,39.59,18.));
+#3142=CARTESIAN_POINT('',(45.335,40.09,21.));
+#3143=CARTESIAN_POINT('Origin',(58.335,40.09,21.));
+#3144=CARTESIAN_POINT('',(58.335,40.09,18.));
+#3145=CARTESIAN_POINT('',(46.2975,40.09,18.));
+#3146=CARTESIAN_POINT('',(58.335,40.09,21.));
+#3147=CARTESIAN_POINT('Origin',(58.335,39.59,21.));
+#3148=CARTESIAN_POINT('',(58.835,39.59,18.));
+#3149=CARTESIAN_POINT('Origin',(58.335,39.59,18.));
+#3150=CARTESIAN_POINT('',(58.835,39.59,21.));
+#3151=CARTESIAN_POINT('Origin',(58.835,26.59,21.));
+#3152=CARTESIAN_POINT('',(58.835,37.06,18.));
+#3153=CARTESIAN_POINT('Origin',(87.11,46.79,21.));
+#3154=CARTESIAN_POINT('',(87.61,46.79,18.));
+#3155=CARTESIAN_POINT('',(87.61,46.79,21.));
+#3156=CARTESIAN_POINT('',(87.11,46.29,18.));
+#3157=CARTESIAN_POINT('Origin',(87.11,46.79,18.));
+#3158=CARTESIAN_POINT('',(87.11,46.29,21.));
+#3159=CARTESIAN_POINT('Origin',(74.11,46.29,21.));
+#3160=CARTESIAN_POINT('',(74.11,46.29,18.));
+#3161=CARTESIAN_POINT('',(67.185,46.29,18.));
+#3162=CARTESIAN_POINT('',(74.11,46.29,21.));
+#3163=CARTESIAN_POINT('Origin',(74.11,46.79,21.));
+#3164=CARTESIAN_POINT('',(73.61,46.79,18.));
+#3165=CARTESIAN_POINT('Origin',(74.11,46.79,18.));
+#3166=CARTESIAN_POINT('',(73.61,46.79,21.));
+#3167=CARTESIAN_POINT('Origin',(73.61,59.79,21.));
+#3168=CARTESIAN_POINT('',(73.61,59.79,18.));
+#3169=CARTESIAN_POINT('',(73.61,40.66,18.));
+#3170=CARTESIAN_POINT('',(73.61,59.79,21.));
+#3171=CARTESIAN_POINT('Origin',(74.11,59.79,21.));
+#3172=CARTESIAN_POINT('',(74.11,60.29,18.));
+#3173=CARTESIAN_POINT('Origin',(74.11,59.79,18.));
+#3174=CARTESIAN_POINT('',(74.11,60.29,21.));
+#3175=CARTESIAN_POINT('Origin',(87.11,60.29,21.));
+#3176=CARTESIAN_POINT('',(87.11,60.29,18.));
+#3177=CARTESIAN_POINT('',(60.685,60.29,18.));
+#3178=CARTESIAN_POINT('',(87.11,60.29,21.));
+#3179=CARTESIAN_POINT('Origin',(87.11,59.79,21.));
+#3180=CARTESIAN_POINT('',(87.61,59.79,18.));
+#3181=CARTESIAN_POINT('Origin',(87.11,59.79,18.));
+#3182=CARTESIAN_POINT('',(87.61,59.79,21.));
+#3183=CARTESIAN_POINT('Origin',(87.61,46.79,21.));
+#3184=CARTESIAN_POINT('',(87.61,47.16,18.));
+#3185=CARTESIAN_POINT('Origin',(26.545,47.045,21.));
+#3186=CARTESIAN_POINT('',(65.245,47.045,18.));
+#3187=CARTESIAN_POINT('',(65.245,47.045,21.));
+#3188=CARTESIAN_POINT('',(26.545,47.045,18.));
+#3189=CARTESIAN_POINT('',(56.1525,47.045,18.));
+#3190=CARTESIAN_POINT('',(26.545,47.045,21.));
+#3191=CARTESIAN_POINT('Origin',(26.545,59.545,21.));
+#3192=CARTESIAN_POINT('',(26.545,59.545,18.));
+#3193=CARTESIAN_POINT('',(26.545,40.8875,18.));
+#3194=CARTESIAN_POINT('',(26.545,59.545,21.));
+#3195=CARTESIAN_POINT('Origin',(65.245,59.545,21.));
+#3196=CARTESIAN_POINT('',(65.245,59.545,18.));
+#3197=CARTESIAN_POINT('',(37.0025,59.545,18.));
+#3198=CARTESIAN_POINT('',(65.245,59.545,21.));
+#3199=CARTESIAN_POINT('Origin',(65.245,47.045,21.));
+#3200=CARTESIAN_POINT('',(65.245,46.9375,18.));
+#3201=CARTESIAN_POINT('Origin',(4.16350149405484,42.7967931030271,21.));
+#3202=CARTESIAN_POINT('',(23.3634045213564,42.7561115145685,18.));
+#3203=CARTESIAN_POINT('',(23.3634045213564,42.7561115145685,21.));
+#3204=CARTESIAN_POINT('',(4.16350149405484,42.7967931030271,18.));
+#3205=CARTESIAN_POINT('',(37.720358113746,42.7256913777202,18.));
+#3206=CARTESIAN_POINT('',(4.16350149405484,42.7967931030271,21.));
+#3207=CARTESIAN_POINT('Origin',(4.24033755187632,79.06,21.));
+#3208=CARTESIAN_POINT('',(4.15484025360816,38.7090722697651,18.));
+#3209=CARTESIAN_POINT('Origin',(-10.,-10.,21.));
+#3210=CARTESIAN_POINT('',(-10.,56.795,18.));
+#3211=CARTESIAN_POINT('Origin',(104.52,79.06,21.));
+#3212=CARTESIAN_POINT('',(104.52,12.265,18.));
+#3213=CARTESIAN_POINT('Origin',(23.3634045213564,42.7561115145685,21.));
+#3214=CARTESIAN_POINT('',(23.3952026224009,57.7634030103233,18.));
+#3215=CARTESIAN_POINT('Origin',(47.26,34.53,18.));
+#3216=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#3220,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#3217=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#3220,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#3218=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#3216))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#3220,#3221,#3222))
+REPRESENTATION_CONTEXT('','3D')
+);
+#3219=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#3217))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#3220,#3221,#3222))
+REPRESENTATION_CONTEXT('','3D')
+);
+#3220=(
+LENGTH_UNIT()
+NAMED_UNIT(*)
+SI_UNIT(.MILLI.,.METRE.)
+);
+#3221=(
+NAMED_UNIT(*)
+PLANE_ANGLE_UNIT()
+SI_UNIT($,.RADIAN.)
+);
+#3222=(
+NAMED_UNIT(*)
+SI_UNIT($,.STERADIAN.)
+SOLID_ANGLE_UNIT()
+);
+#3223=SHAPE_DEFINITION_REPRESENTATION(#3224,#3225);
+#3224=PRODUCT_DEFINITION_SHAPE('',$,#3227);
+#3225=SHAPE_REPRESENTATION('',(#1924),#3218);
+#3226=PRODUCT_DEFINITION_CONTEXT('part definition',#3231,'design');
+#3227=PRODUCT_DEFINITION('hackpad','hackpad v5',#3228,#3226);
+#3228=PRODUCT_DEFINITION_FORMATION('',$,#3233);
+#3229=PRODUCT_RELATED_PRODUCT_CATEGORY('hackpad v5','hackpad v5',(#3233));
+#3230=APPLICATION_PROTOCOL_DEFINITION('international standard',
+'automotive_design',2009,#3231);
+#3231=APPLICATION_CONTEXT(
+'Core Data for Automotive Mechanical Design Process');
+#3232=PRODUCT_CONTEXT('part definition',#3231,'mechanical');
+#3233=PRODUCT('hackpad','hackpad v5',$,(#3232));
+#3234=PRESENTATION_STYLE_ASSIGNMENT((#3235));
+#3235=SURFACE_STYLE_USAGE(.BOTH.,#3236);
+#3236=SURFACE_SIDE_STYLE('',(#3237));
+#3237=SURFACE_STYLE_FILL_AREA(#3238);
+#3238=FILL_AREA_STYLE('Steel - Satin',(#3239));
+#3239=FILL_AREA_STYLE_COLOUR('Steel - Satin',#3240);
+#3240=COLOUR_RGB('Steel - Satin',0.627450980392157,0.627450980392157,0.627450980392157);
+ENDSEC;
+END-ISO-10303-21;
diff --git a/hackpads/blipyboard/cad/top.step b/hackpads/blipyboard/cad/top.step
new file mode 100644
index 0000000000..29a5aed66c
--- /dev/null
+++ b/hackpads/blipyboard/cad/top.step
@@ -0,0 +1,671 @@
+ISO-10303-21;
+HEADER;
+/* Generated by software containing ST-Developer
+ * from STEP Tools, Inc. (www.steptools.com)
+ */
+
+FILE_DESCRIPTION(
+/* description */ (''),
+/* implementation_level */ '2;1');
+
+FILE_NAME(
+/* name */ 'top.step',
+/* time_stamp */ '2025-06-27T19:17:30-07:00',
+/* author */ (''),
+/* organization */ (''),
+/* preprocessor_version */ 'ST-DEVELOPER v20.1',
+/* originating_system */ 'Autodesk Translation Framework v14.10.0.0',
+/* authorisation */ '');
+
+FILE_SCHEMA (('AUTOMOTIVE_DESIGN { 1 0 10303 214 3 1 1 }'));
+ENDSEC;
+
+DATA;
+#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#13),#603);
+#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#609,#12);
+#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#14),#602);
+#13=STYLED_ITEM('',(#618),#14);
+#14=MANIFOLD_SOLID_BREP('top',#363);
+#15=FACE_BOUND('',#56,.T.);
+#16=FACE_BOUND('',#57,.T.);
+#17=FACE_BOUND('',#58,.T.);
+#18=FACE_BOUND('',#59,.T.);
+#19=FACE_BOUND('',#60,.T.);
+#20=FACE_BOUND('',#76,.T.);
+#21=FACE_BOUND('',#77,.T.);
+#22=FACE_BOUND('',#78,.T.);
+#23=FACE_BOUND('',#79,.T.);
+#24=FACE_BOUND('',#80,.T.);
+#25=PLANE('',#368);
+#26=PLANE('',#369);
+#27=PLANE('',#379);
+#28=PLANE('',#382);
+#29=PLANE('',#391);
+#30=PLANE('',#392);
+#31=PLANE('',#393);
+#32=PLANE('',#394);
+#33=PLANE('',#397);
+#34=PLANE('',#398);
+#35=FACE_OUTER_BOUND('',#53,.T.);
+#36=FACE_OUTER_BOUND('',#54,.T.);
+#37=FACE_OUTER_BOUND('',#55,.T.);
+#38=FACE_OUTER_BOUND('',#61,.T.);
+#39=FACE_OUTER_BOUND('',#62,.T.);
+#40=FACE_OUTER_BOUND('',#63,.T.);
+#41=FACE_OUTER_BOUND('',#64,.T.);
+#42=FACE_OUTER_BOUND('',#65,.T.);
+#43=FACE_OUTER_BOUND('',#66,.T.);
+#44=FACE_OUTER_BOUND('',#67,.T.);
+#45=FACE_OUTER_BOUND('',#68,.T.);
+#46=FACE_OUTER_BOUND('',#69,.T.);
+#47=FACE_OUTER_BOUND('',#70,.T.);
+#48=FACE_OUTER_BOUND('',#71,.T.);
+#49=FACE_OUTER_BOUND('',#72,.T.);
+#50=FACE_OUTER_BOUND('',#73,.T.);
+#51=FACE_OUTER_BOUND('',#74,.T.);
+#52=FACE_OUTER_BOUND('',#75,.T.);
+#53=EDGE_LOOP('',(#241,#242,#243,#244));
+#54=EDGE_LOOP('',(#245,#246,#247,#248));
+#55=EDGE_LOOP('',(#249,#250,#251,#252,#253,#254,#255,#256));
+#56=EDGE_LOOP('',(#257));
+#57=EDGE_LOOP('',(#258,#259,#260,#261));
+#58=EDGE_LOOP('',(#262));
+#59=EDGE_LOOP('',(#263));
+#60=EDGE_LOOP('',(#264));
+#61=EDGE_LOOP('',(#265,#266,#267,#268));
+#62=EDGE_LOOP('',(#269,#270,#271,#272));
+#63=EDGE_LOOP('',(#273,#274,#275,#276));
+#64=EDGE_LOOP('',(#277,#278,#279,#280));
+#65=EDGE_LOOP('',(#281,#282,#283,#284));
+#66=EDGE_LOOP('',(#285,#286,#287,#288));
+#67=EDGE_LOOP('',(#289,#290,#291,#292));
+#68=EDGE_LOOP('',(#293,#294,#295,#296));
+#69=EDGE_LOOP('',(#297,#298,#299,#300));
+#70=EDGE_LOOP('',(#301,#302,#303,#304));
+#71=EDGE_LOOP('',(#305,#306,#307,#308));
+#72=EDGE_LOOP('',(#309,#310,#311,#312));
+#73=EDGE_LOOP('',(#313,#314,#315,#316));
+#74=EDGE_LOOP('',(#317,#318,#319,#320));
+#75=EDGE_LOOP('',(#321,#322,#323,#324,#325,#326,#327,#328));
+#76=EDGE_LOOP('',(#329));
+#77=EDGE_LOOP('',(#330,#331,#332,#333));
+#78=EDGE_LOOP('',(#334));
+#79=EDGE_LOOP('',(#335));
+#80=EDGE_LOOP('',(#336));
+#81=LINE('',#507,#113);
+#82=LINE('',#510,#114);
+#83=LINE('',#513,#115);
+#84=LINE('',#515,#116);
+#85=LINE('',#516,#117);
+#86=LINE('',#519,#118);
+#87=LINE('',#523,#119);
+#88=LINE('',#527,#120);
+#89=LINE('',#533,#121);
+#90=LINE('',#535,#122);
+#91=LINE('',#537,#123);
+#92=LINE('',#538,#124);
+#93=LINE('',#548,#125);
+#94=LINE('',#551,#126);
+#95=LINE('',#552,#127);
+#96=LINE('',#556,#128);
+#97=LINE('',#559,#129);
+#98=LINE('',#560,#130);
+#99=LINE('',#564,#131);
+#100=LINE('',#568,#132);
+#101=LINE('',#572,#133);
+#102=LINE('',#576,#134);
+#103=LINE('',#579,#135);
+#104=LINE('',#581,#136);
+#105=LINE('',#582,#137);
+#106=LINE('',#585,#138);
+#107=LINE('',#586,#139);
+#108=LINE('',#589,#140);
+#109=LINE('',#590,#141);
+#110=LINE('',#592,#142);
+#111=LINE('',#596,#143);
+#112=LINE('',#598,#144);
+#113=VECTOR('',#405,10.);
+#114=VECTOR('',#408,10.);
+#115=VECTOR('',#411,10.);
+#116=VECTOR('',#412,10.);
+#117=VECTOR('',#413,10.);
+#118=VECTOR('',#416,10.);
+#119=VECTOR('',#419,10.);
+#120=VECTOR('',#422,10.);
+#121=VECTOR('',#427,10.);
+#122=VECTOR('',#428,10.);
+#123=VECTOR('',#429,10.);
+#124=VECTOR('',#430,10.);
+#125=VECTOR('',#441,10.);
+#126=VECTOR('',#444,10.);
+#127=VECTOR('',#445,10.);
+#128=VECTOR('',#450,10.);
+#129=VECTOR('',#453,10.);
+#130=VECTOR('',#454,10.);
+#131=VECTOR('',#459,10.);
+#132=VECTOR('',#464,1.45);
+#133=VECTOR('',#469,1.45);
+#134=VECTOR('',#474,1.45);
+#135=VECTOR('',#477,10.);
+#136=VECTOR('',#478,10.);
+#137=VECTOR('',#479,10.);
+#138=VECTOR('',#482,10.);
+#139=VECTOR('',#483,10.);
+#140=VECTOR('',#486,10.);
+#141=VECTOR('',#487,10.);
+#142=VECTOR('',#490,10.);
+#143=VECTOR('',#495,1.45);
+#144=VECTOR('',#498,10.);
+#145=CIRCLE('',#366,5.);
+#146=CIRCLE('',#367,5.);
+#147=CIRCLE('',#370,5.);
+#148=CIRCLE('',#371,5.);
+#149=CIRCLE('',#372,5.);
+#150=CIRCLE('',#373,1.45);
+#151=CIRCLE('',#374,1.45);
+#152=CIRCLE('',#375,1.45);
+#153=CIRCLE('',#376,1.45);
+#154=CIRCLE('',#378,5.);
+#155=CIRCLE('',#381,5.);
+#156=CIRCLE('',#384,5.);
+#157=CIRCLE('',#386,1.45);
+#158=CIRCLE('',#388,1.45);
+#159=CIRCLE('',#390,1.45);
+#160=CIRCLE('',#396,1.45);
+#161=VERTEX_POINT('',#503);
+#162=VERTEX_POINT('',#504);
+#163=VERTEX_POINT('',#506);
+#164=VERTEX_POINT('',#508);
+#165=VERTEX_POINT('',#512);
+#166=VERTEX_POINT('',#514);
+#167=VERTEX_POINT('',#518);
+#168=VERTEX_POINT('',#520);
+#169=VERTEX_POINT('',#522);
+#170=VERTEX_POINT('',#524);
+#171=VERTEX_POINT('',#526);
+#172=VERTEX_POINT('',#529);
+#173=VERTEX_POINT('',#531);
+#174=VERTEX_POINT('',#532);
+#175=VERTEX_POINT('',#534);
+#176=VERTEX_POINT('',#536);
+#177=VERTEX_POINT('',#539);
+#178=VERTEX_POINT('',#541);
+#179=VERTEX_POINT('',#543);
+#180=VERTEX_POINT('',#546);
+#181=VERTEX_POINT('',#550);
+#182=VERTEX_POINT('',#554);
+#183=VERTEX_POINT('',#558);
+#184=VERTEX_POINT('',#562);
+#185=VERTEX_POINT('',#566);
+#186=VERTEX_POINT('',#570);
+#187=VERTEX_POINT('',#574);
+#188=VERTEX_POINT('',#578);
+#189=VERTEX_POINT('',#580);
+#190=VERTEX_POINT('',#584);
+#191=VERTEX_POINT('',#588);
+#192=VERTEX_POINT('',#594);
+#193=EDGE_CURVE('',#161,#162,#145,.T.);
+#194=EDGE_CURVE('',#162,#163,#81,.T.);
+#195=EDGE_CURVE('',#163,#164,#146,.T.);
+#196=EDGE_CURVE('',#164,#161,#82,.T.);
+#197=EDGE_CURVE('',#165,#164,#83,.T.);
+#198=EDGE_CURVE('',#166,#165,#84,.T.);
+#199=EDGE_CURVE('',#161,#166,#85,.T.);
+#200=EDGE_CURVE('',#163,#167,#86,.T.);
+#201=EDGE_CURVE('',#168,#167,#147,.T.);
+#202=EDGE_CURVE('',#168,#169,#87,.T.);
+#203=EDGE_CURVE('',#170,#169,#148,.T.);
+#204=EDGE_CURVE('',#170,#171,#88,.T.);
+#205=EDGE_CURVE('',#165,#171,#149,.T.);
+#206=EDGE_CURVE('',#172,#172,#150,.T.);
+#207=EDGE_CURVE('',#173,#174,#89,.T.);
+#208=EDGE_CURVE('',#174,#175,#90,.T.);
+#209=EDGE_CURVE('',#175,#176,#91,.T.);
+#210=EDGE_CURVE('',#176,#173,#92,.T.);
+#211=EDGE_CURVE('',#177,#177,#151,.T.);
+#212=EDGE_CURVE('',#178,#178,#152,.T.);
+#213=EDGE_CURVE('',#179,#179,#153,.T.);
+#214=EDGE_CURVE('',#180,#166,#154,.T.);
+#215=EDGE_CURVE('',#171,#180,#93,.T.);
+#216=EDGE_CURVE('',#181,#170,#94,.T.);
+#217=EDGE_CURVE('',#180,#181,#95,.T.);
+#218=EDGE_CURVE('',#182,#181,#155,.T.);
+#219=EDGE_CURVE('',#169,#182,#96,.T.);
+#220=EDGE_CURVE('',#183,#168,#97,.T.);
+#221=EDGE_CURVE('',#182,#183,#98,.T.);
+#222=EDGE_CURVE('',#184,#183,#156,.T.);
+#223=EDGE_CURVE('',#167,#184,#99,.T.);
+#224=EDGE_CURVE('',#185,#185,#157,.T.);
+#225=EDGE_CURVE('',#185,#179,#100,.T.);
+#226=EDGE_CURVE('',#186,#186,#158,.T.);
+#227=EDGE_CURVE('',#186,#178,#101,.T.);
+#228=EDGE_CURVE('',#187,#187,#159,.T.);
+#229=EDGE_CURVE('',#187,#177,#102,.T.);
+#230=EDGE_CURVE('',#174,#188,#103,.T.);
+#231=EDGE_CURVE('',#189,#188,#104,.T.);
+#232=EDGE_CURVE('',#175,#189,#105,.T.);
+#233=EDGE_CURVE('',#190,#189,#106,.T.);
+#234=EDGE_CURVE('',#176,#190,#107,.T.);
+#235=EDGE_CURVE('',#191,#190,#108,.T.);
+#236=EDGE_CURVE('',#173,#191,#109,.T.);
+#237=EDGE_CURVE('',#188,#191,#110,.T.);
+#238=EDGE_CURVE('',#192,#192,#160,.T.);
+#239=EDGE_CURVE('',#192,#172,#111,.T.);
+#240=EDGE_CURVE('',#184,#162,#112,.T.);
+#241=ORIENTED_EDGE('',*,*,#193,.T.);
+#242=ORIENTED_EDGE('',*,*,#194,.T.);
+#243=ORIENTED_EDGE('',*,*,#195,.T.);
+#244=ORIENTED_EDGE('',*,*,#196,.T.);
+#245=ORIENTED_EDGE('',*,*,#196,.F.);
+#246=ORIENTED_EDGE('',*,*,#197,.F.);
+#247=ORIENTED_EDGE('',*,*,#198,.F.);
+#248=ORIENTED_EDGE('',*,*,#199,.F.);
+#249=ORIENTED_EDGE('',*,*,#195,.F.);
+#250=ORIENTED_EDGE('',*,*,#200,.T.);
+#251=ORIENTED_EDGE('',*,*,#201,.F.);
+#252=ORIENTED_EDGE('',*,*,#202,.T.);
+#253=ORIENTED_EDGE('',*,*,#203,.F.);
+#254=ORIENTED_EDGE('',*,*,#204,.T.);
+#255=ORIENTED_EDGE('',*,*,#205,.F.);
+#256=ORIENTED_EDGE('',*,*,#197,.T.);
+#257=ORIENTED_EDGE('',*,*,#206,.T.);
+#258=ORIENTED_EDGE('',*,*,#207,.T.);
+#259=ORIENTED_EDGE('',*,*,#208,.T.);
+#260=ORIENTED_EDGE('',*,*,#209,.T.);
+#261=ORIENTED_EDGE('',*,*,#210,.T.);
+#262=ORIENTED_EDGE('',*,*,#211,.T.);
+#263=ORIENTED_EDGE('',*,*,#212,.T.);
+#264=ORIENTED_EDGE('',*,*,#213,.T.);
+#265=ORIENTED_EDGE('',*,*,#214,.T.);
+#266=ORIENTED_EDGE('',*,*,#198,.T.);
+#267=ORIENTED_EDGE('',*,*,#205,.T.);
+#268=ORIENTED_EDGE('',*,*,#215,.T.);
+#269=ORIENTED_EDGE('',*,*,#215,.F.);
+#270=ORIENTED_EDGE('',*,*,#204,.F.);
+#271=ORIENTED_EDGE('',*,*,#216,.F.);
+#272=ORIENTED_EDGE('',*,*,#217,.F.);
+#273=ORIENTED_EDGE('',*,*,#218,.T.);
+#274=ORIENTED_EDGE('',*,*,#216,.T.);
+#275=ORIENTED_EDGE('',*,*,#203,.T.);
+#276=ORIENTED_EDGE('',*,*,#219,.T.);
+#277=ORIENTED_EDGE('',*,*,#219,.F.);
+#278=ORIENTED_EDGE('',*,*,#202,.F.);
+#279=ORIENTED_EDGE('',*,*,#220,.F.);
+#280=ORIENTED_EDGE('',*,*,#221,.F.);
+#281=ORIENTED_EDGE('',*,*,#222,.T.);
+#282=ORIENTED_EDGE('',*,*,#220,.T.);
+#283=ORIENTED_EDGE('',*,*,#201,.T.);
+#284=ORIENTED_EDGE('',*,*,#223,.T.);
+#285=ORIENTED_EDGE('',*,*,#224,.F.);
+#286=ORIENTED_EDGE('',*,*,#225,.T.);
+#287=ORIENTED_EDGE('',*,*,#213,.F.);
+#288=ORIENTED_EDGE('',*,*,#225,.F.);
+#289=ORIENTED_EDGE('',*,*,#226,.F.);
+#290=ORIENTED_EDGE('',*,*,#227,.T.);
+#291=ORIENTED_EDGE('',*,*,#212,.F.);
+#292=ORIENTED_EDGE('',*,*,#227,.F.);
+#293=ORIENTED_EDGE('',*,*,#228,.F.);
+#294=ORIENTED_EDGE('',*,*,#229,.T.);
+#295=ORIENTED_EDGE('',*,*,#211,.F.);
+#296=ORIENTED_EDGE('',*,*,#229,.F.);
+#297=ORIENTED_EDGE('',*,*,#208,.F.);
+#298=ORIENTED_EDGE('',*,*,#230,.T.);
+#299=ORIENTED_EDGE('',*,*,#231,.F.);
+#300=ORIENTED_EDGE('',*,*,#232,.F.);
+#301=ORIENTED_EDGE('',*,*,#209,.F.);
+#302=ORIENTED_EDGE('',*,*,#232,.T.);
+#303=ORIENTED_EDGE('',*,*,#233,.F.);
+#304=ORIENTED_EDGE('',*,*,#234,.F.);
+#305=ORIENTED_EDGE('',*,*,#210,.F.);
+#306=ORIENTED_EDGE('',*,*,#234,.T.);
+#307=ORIENTED_EDGE('',*,*,#235,.F.);
+#308=ORIENTED_EDGE('',*,*,#236,.F.);
+#309=ORIENTED_EDGE('',*,*,#207,.F.);
+#310=ORIENTED_EDGE('',*,*,#236,.T.);
+#311=ORIENTED_EDGE('',*,*,#237,.F.);
+#312=ORIENTED_EDGE('',*,*,#230,.F.);
+#313=ORIENTED_EDGE('',*,*,#238,.F.);
+#314=ORIENTED_EDGE('',*,*,#239,.T.);
+#315=ORIENTED_EDGE('',*,*,#206,.F.);
+#316=ORIENTED_EDGE('',*,*,#239,.F.);
+#317=ORIENTED_EDGE('',*,*,#194,.F.);
+#318=ORIENTED_EDGE('',*,*,#240,.F.);
+#319=ORIENTED_EDGE('',*,*,#223,.F.);
+#320=ORIENTED_EDGE('',*,*,#200,.F.);
+#321=ORIENTED_EDGE('',*,*,#193,.F.);
+#322=ORIENTED_EDGE('',*,*,#199,.T.);
+#323=ORIENTED_EDGE('',*,*,#214,.F.);
+#324=ORIENTED_EDGE('',*,*,#217,.T.);
+#325=ORIENTED_EDGE('',*,*,#218,.F.);
+#326=ORIENTED_EDGE('',*,*,#221,.T.);
+#327=ORIENTED_EDGE('',*,*,#222,.F.);
+#328=ORIENTED_EDGE('',*,*,#240,.T.);
+#329=ORIENTED_EDGE('',*,*,#238,.T.);
+#330=ORIENTED_EDGE('',*,*,#237,.T.);
+#331=ORIENTED_EDGE('',*,*,#235,.T.);
+#332=ORIENTED_EDGE('',*,*,#233,.T.);
+#333=ORIENTED_EDGE('',*,*,#231,.T.);
+#334=ORIENTED_EDGE('',*,*,#228,.T.);
+#335=ORIENTED_EDGE('',*,*,#226,.T.);
+#336=ORIENTED_EDGE('',*,*,#224,.T.);
+#337=CYLINDRICAL_SURFACE('',#365,5.);
+#338=CYLINDRICAL_SURFACE('',#377,5.);
+#339=CYLINDRICAL_SURFACE('',#380,5.);
+#340=CYLINDRICAL_SURFACE('',#383,5.);
+#341=CYLINDRICAL_SURFACE('',#385,1.45);
+#342=CYLINDRICAL_SURFACE('',#387,1.45);
+#343=CYLINDRICAL_SURFACE('',#389,1.45);
+#344=CYLINDRICAL_SURFACE('',#395,1.45);
+#345=ADVANCED_FACE('',(#35),#337,.T.);
+#346=ADVANCED_FACE('',(#36),#25,.T.);
+#347=ADVANCED_FACE('',(#37,#15,#16,#17,#18,#19),#26,.F.);
+#348=ADVANCED_FACE('',(#38),#338,.T.);
+#349=ADVANCED_FACE('',(#39),#27,.T.);
+#350=ADVANCED_FACE('',(#40),#339,.T.);
+#351=ADVANCED_FACE('',(#41),#28,.T.);
+#352=ADVANCED_FACE('',(#42),#340,.T.);
+#353=ADVANCED_FACE('',(#43),#341,.F.);
+#354=ADVANCED_FACE('',(#44),#342,.F.);
+#355=ADVANCED_FACE('',(#45),#343,.F.);
+#356=ADVANCED_FACE('',(#46),#29,.T.);
+#357=ADVANCED_FACE('',(#47),#30,.T.);
+#358=ADVANCED_FACE('',(#48),#31,.T.);
+#359=ADVANCED_FACE('',(#49),#32,.T.);
+#360=ADVANCED_FACE('',(#50),#344,.F.);
+#361=ADVANCED_FACE('',(#51),#33,.T.);
+#362=ADVANCED_FACE('',(#52,#20,#21,#22,#23,#24),#34,.T.);
+#363=CLOSED_SHELL('',(#345,#346,#347,#348,#349,#350,#351,#352,#353,#354,
+#355,#356,#357,#358,#359,#360,#361,#362));
+#364=AXIS2_PLACEMENT_3D('',#501,#399,#400);
+#365=AXIS2_PLACEMENT_3D('',#502,#401,#402);
+#366=AXIS2_PLACEMENT_3D('',#505,#403,#404);
+#367=AXIS2_PLACEMENT_3D('',#509,#406,#407);
+#368=AXIS2_PLACEMENT_3D('',#511,#409,#410);
+#369=AXIS2_PLACEMENT_3D('',#517,#414,#415);
+#370=AXIS2_PLACEMENT_3D('',#521,#417,#418);
+#371=AXIS2_PLACEMENT_3D('',#525,#420,#421);
+#372=AXIS2_PLACEMENT_3D('',#528,#423,#424);
+#373=AXIS2_PLACEMENT_3D('',#530,#425,#426);
+#374=AXIS2_PLACEMENT_3D('',#540,#431,#432);
+#375=AXIS2_PLACEMENT_3D('',#542,#433,#434);
+#376=AXIS2_PLACEMENT_3D('',#544,#435,#436);
+#377=AXIS2_PLACEMENT_3D('',#545,#437,#438);
+#378=AXIS2_PLACEMENT_3D('',#547,#439,#440);
+#379=AXIS2_PLACEMENT_3D('',#549,#442,#443);
+#380=AXIS2_PLACEMENT_3D('',#553,#446,#447);
+#381=AXIS2_PLACEMENT_3D('',#555,#448,#449);
+#382=AXIS2_PLACEMENT_3D('',#557,#451,#452);
+#383=AXIS2_PLACEMENT_3D('',#561,#455,#456);
+#384=AXIS2_PLACEMENT_3D('',#563,#457,#458);
+#385=AXIS2_PLACEMENT_3D('',#565,#460,#461);
+#386=AXIS2_PLACEMENT_3D('',#567,#462,#463);
+#387=AXIS2_PLACEMENT_3D('',#569,#465,#466);
+#388=AXIS2_PLACEMENT_3D('',#571,#467,#468);
+#389=AXIS2_PLACEMENT_3D('',#573,#470,#471);
+#390=AXIS2_PLACEMENT_3D('',#575,#472,#473);
+#391=AXIS2_PLACEMENT_3D('',#577,#475,#476);
+#392=AXIS2_PLACEMENT_3D('',#583,#480,#481);
+#393=AXIS2_PLACEMENT_3D('',#587,#484,#485);
+#394=AXIS2_PLACEMENT_3D('',#591,#488,#489);
+#395=AXIS2_PLACEMENT_3D('',#593,#491,#492);
+#396=AXIS2_PLACEMENT_3D('',#595,#493,#494);
+#397=AXIS2_PLACEMENT_3D('',#597,#496,#497);
+#398=AXIS2_PLACEMENT_3D('',#599,#499,#500);
+#399=DIRECTION('axis',(0.,0.,1.));
+#400=DIRECTION('refdir',(1.,0.,0.));
+#401=DIRECTION('center_axis',(0.,0.,1.));
+#402=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#403=DIRECTION('center_axis',(0.,0.,-1.));
+#404=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#405=DIRECTION('',(0.,0.,-1.));
+#406=DIRECTION('center_axis',(0.,0.,1.));
+#407=DIRECTION('ref_axis',(-0.707106781186547,0.707106781186547,0.));
+#408=DIRECTION('',(0.,0.,1.));
+#409=DIRECTION('center_axis',(-1.,0.,0.));
+#410=DIRECTION('ref_axis',(0.,-1.,0.));
+#411=DIRECTION('',(0.,1.,0.));
+#412=DIRECTION('',(0.,0.,-1.));
+#413=DIRECTION('',(0.,-1.,0.));
+#414=DIRECTION('center_axis',(0.,0.,1.));
+#415=DIRECTION('ref_axis',(1.,0.,0.));
+#416=DIRECTION('',(1.,0.,0.));
+#417=DIRECTION('center_axis',(0.,0.,1.));
+#418=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#419=DIRECTION('',(0.,-1.,0.));
+#420=DIRECTION('center_axis',(0.,0.,1.));
+#421=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#422=DIRECTION('',(-1.,-4.8472887907141E-17,0.));
+#423=DIRECTION('center_axis',(0.,0.,1.));
+#424=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#425=DIRECTION('center_axis',(0.,0.,1.));
+#426=DIRECTION('ref_axis',(1.,0.,0.));
+#427=DIRECTION('',(1.,2.89337761429314E-33,0.));
+#428=DIRECTION('',(0.,1.,0.));
+#429=DIRECTION('',(-1.,0.,0.));
+#430=DIRECTION('',(-1.72904223214608E-33,-1.,0.));
+#431=DIRECTION('center_axis',(0.,0.,1.));
+#432=DIRECTION('ref_axis',(1.,0.,0.));
+#433=DIRECTION('center_axis',(0.,0.,1.));
+#434=DIRECTION('ref_axis',(1.,0.,0.));
+#435=DIRECTION('center_axis',(0.,0.,1.));
+#436=DIRECTION('ref_axis',(1.,0.,0.));
+#437=DIRECTION('center_axis',(0.,0.,1.));
+#438=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#439=DIRECTION('center_axis',(0.,0.,-1.));
+#440=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186548,0.));
+#441=DIRECTION('',(0.,0.,1.));
+#442=DIRECTION('center_axis',(4.8472887907141E-17,-1.,0.));
+#443=DIRECTION('ref_axis',(1.,4.8472887907141E-17,0.));
+#444=DIRECTION('',(0.,0.,-1.));
+#445=DIRECTION('',(1.,4.8472887907141E-17,0.));
+#446=DIRECTION('center_axis',(0.,0.,1.));
+#447=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#448=DIRECTION('center_axis',(0.,0.,-1.));
+#449=DIRECTION('ref_axis',(0.707106781186547,-0.707106781186547,0.));
+#450=DIRECTION('',(0.,0.,1.));
+#451=DIRECTION('center_axis',(1.,0.,0.));
+#452=DIRECTION('ref_axis',(0.,1.,0.));
+#453=DIRECTION('',(0.,0.,-1.));
+#454=DIRECTION('',(0.,1.,0.));
+#455=DIRECTION('center_axis',(0.,0.,1.));
+#456=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#457=DIRECTION('center_axis',(0.,0.,-1.));
+#458=DIRECTION('ref_axis',(0.707106781186547,0.707106781186547,0.));
+#459=DIRECTION('',(0.,0.,1.));
+#460=DIRECTION('center_axis',(0.,0.,1.));
+#461=DIRECTION('ref_axis',(1.,0.,0.));
+#462=DIRECTION('center_axis',(0.,0.,-1.));
+#463=DIRECTION('ref_axis',(1.,0.,0.));
+#464=DIRECTION('',(0.,0.,-1.));
+#465=DIRECTION('center_axis',(0.,0.,1.));
+#466=DIRECTION('ref_axis',(1.,0.,0.));
+#467=DIRECTION('center_axis',(0.,0.,-1.));
+#468=DIRECTION('ref_axis',(1.,0.,0.));
+#469=DIRECTION('',(0.,0.,-1.));
+#470=DIRECTION('center_axis',(0.,0.,1.));
+#471=DIRECTION('ref_axis',(1.,0.,0.));
+#472=DIRECTION('center_axis',(0.,0.,-1.));
+#473=DIRECTION('ref_axis',(1.,0.,0.));
+#474=DIRECTION('',(0.,0.,-1.));
+#475=DIRECTION('center_axis',(-1.,0.,0.));
+#476=DIRECTION('ref_axis',(0.,-1.,0.));
+#477=DIRECTION('',(0.,0.,1.));
+#478=DIRECTION('',(0.,-1.,0.));
+#479=DIRECTION('',(0.,0.,1.));
+#480=DIRECTION('center_axis',(0.,-1.,0.));
+#481=DIRECTION('ref_axis',(1.,0.,0.));
+#482=DIRECTION('',(1.,0.,0.));
+#483=DIRECTION('',(0.,0.,1.));
+#484=DIRECTION('center_axis',(1.,-1.72904223214608E-33,0.));
+#485=DIRECTION('ref_axis',(1.72904223214608E-33,1.,0.));
+#486=DIRECTION('',(1.72904223214608E-33,1.,0.));
+#487=DIRECTION('',(0.,0.,1.));
+#488=DIRECTION('center_axis',(-2.89337761429314E-33,1.,0.));
+#489=DIRECTION('ref_axis',(-1.,-2.89337761429314E-33,0.));
+#490=DIRECTION('',(-1.,-2.89337761429314E-33,0.));
+#491=DIRECTION('center_axis',(0.,0.,1.));
+#492=DIRECTION('ref_axis',(1.,0.,0.));
+#493=DIRECTION('center_axis',(0.,0.,-1.));
+#494=DIRECTION('ref_axis',(1.,0.,0.));
+#495=DIRECTION('',(0.,0.,-1.));
+#496=DIRECTION('center_axis',(0.,1.,0.));
+#497=DIRECTION('ref_axis',(-1.,0.,0.));
+#498=DIRECTION('',(-1.,0.,0.));
+#499=DIRECTION('center_axis',(0.,0.,1.));
+#500=DIRECTION('ref_axis',(1.,0.,0.));
+#501=CARTESIAN_POINT('',(0.,0.,0.));
+#502=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#503=CARTESIAN_POINT('',(-10.,74.06,27.));
+#504=CARTESIAN_POINT('',(-5.,79.06,27.));
+#505=CARTESIAN_POINT('Origin',(-5.,74.06,27.));
+#506=CARTESIAN_POINT('',(-5.,79.06,21.));
+#507=CARTESIAN_POINT('',(-5.,79.06,21.));
+#508=CARTESIAN_POINT('',(-10.,74.06,21.));
+#509=CARTESIAN_POINT('Origin',(-5.,74.06,21.));
+#510=CARTESIAN_POINT('',(-10.,74.06,21.));
+#511=CARTESIAN_POINT('Origin',(-10.,79.06,21.));
+#512=CARTESIAN_POINT('',(-10.,-5.,21.));
+#513=CARTESIAN_POINT('',(-10.,56.795,21.));
+#514=CARTESIAN_POINT('',(-10.,-5.,27.));
+#515=CARTESIAN_POINT('',(-10.,-5.,21.));
+#516=CARTESIAN_POINT('',(-10.,56.795,27.));
+#517=CARTESIAN_POINT('Origin',(47.26,34.53,21.));
+#518=CARTESIAN_POINT('',(99.52,79.06,21.));
+#519=CARTESIAN_POINT('',(75.89,79.06,21.));
+#520=CARTESIAN_POINT('',(104.52,74.06,21.));
+#521=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#522=CARTESIAN_POINT('',(104.52,-5.,21.));
+#523=CARTESIAN_POINT('',(104.52,12.265,21.));
+#524=CARTESIAN_POINT('',(99.52,-10.,21.));
+#525=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#526=CARTESIAN_POINT('',(-5.,-10.,21.));
+#527=CARTESIAN_POINT('',(18.63,-10.,21.));
+#528=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#529=CARTESIAN_POINT('',(-6.45000007450581,74.16,21.));
+#530=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#531=CARTESIAN_POINT('',(0.,0.,21.));
+#532=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,21.));
+#533=CARTESIAN_POINT('',(70.89,0.,21.));
+#534=CARTESIAN_POINT('',(94.52,69.06,21.));
+#535=CARTESIAN_POINT('',(94.52,51.795,21.));
+#536=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,21.));
+#537=CARTESIAN_POINT('',(23.63,69.06,21.));
+#538=CARTESIAN_POINT('',(0.,17.265,21.));
+#539=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#540=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#541=CARTESIAN_POINT('',(-6.55,-5.1,21.));
+#542=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#543=CARTESIAN_POINT('',(98.17,74.16,21.));
+#544=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#545=CARTESIAN_POINT('Origin',(-5.,-5.,21.));
+#546=CARTESIAN_POINT('',(-5.,-10.,27.));
+#547=CARTESIAN_POINT('Origin',(-5.,-5.,27.));
+#548=CARTESIAN_POINT('',(-5.,-10.,21.));
+#549=CARTESIAN_POINT('Origin',(-10.,-10.,21.));
+#550=CARTESIAN_POINT('',(99.52,-10.,27.));
+#551=CARTESIAN_POINT('',(99.52,-10.,21.));
+#552=CARTESIAN_POINT('',(18.63,-10.,27.));
+#553=CARTESIAN_POINT('Origin',(99.52,-5.,21.));
+#554=CARTESIAN_POINT('',(104.52,-5.,27.));
+#555=CARTESIAN_POINT('Origin',(99.52,-5.,27.));
+#556=CARTESIAN_POINT('',(104.52,-5.,21.));
+#557=CARTESIAN_POINT('Origin',(104.52,-10.,21.));
+#558=CARTESIAN_POINT('',(104.52,74.06,27.));
+#559=CARTESIAN_POINT('',(104.52,74.06,21.));
+#560=CARTESIAN_POINT('',(104.52,12.265,27.));
+#561=CARTESIAN_POINT('Origin',(99.52,74.06,21.));
+#562=CARTESIAN_POINT('',(99.52,79.06,27.));
+#563=CARTESIAN_POINT('Origin',(99.52,74.06,27.));
+#564=CARTESIAN_POINT('',(99.52,79.06,21.));
+#565=CARTESIAN_POINT('Origin',(99.62,74.16,21.));
+#566=CARTESIAN_POINT('',(98.17,74.16,27.));
+#567=CARTESIAN_POINT('Origin',(99.62,74.16,27.));
+#568=CARTESIAN_POINT('',(98.17,74.16,21.));
+#569=CARTESIAN_POINT('Origin',(-5.1,-5.1,21.));
+#570=CARTESIAN_POINT('',(-6.55,-5.1,27.));
+#571=CARTESIAN_POINT('Origin',(-5.1,-5.1,27.));
+#572=CARTESIAN_POINT('',(-6.55,-5.1,21.));
+#573=CARTESIAN_POINT('Origin',(99.62,-5.1,21.));
+#574=CARTESIAN_POINT('',(98.17,-5.1,27.));
+#575=CARTESIAN_POINT('Origin',(99.62,-5.1,27.));
+#576=CARTESIAN_POINT('',(98.17,-5.1,21.));
+#577=CARTESIAN_POINT('Origin',(94.52,69.06,21.));
+#578=CARTESIAN_POINT('',(94.52,0.,27.));
+#579=CARTESIAN_POINT('',(94.52,2.73482052102987E-31,21.));
+#580=CARTESIAN_POINT('',(94.52,69.06,27.));
+#581=CARTESIAN_POINT('',(94.52,51.795,27.));
+#582=CARTESIAN_POINT('',(94.52,69.06,21.));
+#583=CARTESIAN_POINT('Origin',(0.,69.06,21.));
+#584=CARTESIAN_POINT('',(0.,69.06,27.));
+#585=CARTESIAN_POINT('',(23.63,69.06,27.));
+#586=CARTESIAN_POINT('',(1.19407656552009E-31,69.06,21.));
+#587=CARTESIAN_POINT('Origin',(-2.98519141380022E-32,0.,21.));
+#588=CARTESIAN_POINT('',(0.,0.,27.));
+#589=CARTESIAN_POINT('',(0.,17.265,27.));
+#590=CARTESIAN_POINT('',(0.,0.,21.));
+#591=CARTESIAN_POINT('Origin',(94.52,6.83705130257469E-32,21.));
+#592=CARTESIAN_POINT('',(70.89,0.,27.));
+#593=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,21.));
+#594=CARTESIAN_POINT('',(-6.45000007450581,74.16,27.));
+#595=CARTESIAN_POINT('Origin',(-5.00000007450581,74.16,27.));
+#596=CARTESIAN_POINT('',(-6.45000007450581,74.16,21.));
+#597=CARTESIAN_POINT('Origin',(104.52,79.06,21.));
+#598=CARTESIAN_POINT('',(75.89,79.06,27.));
+#599=CARTESIAN_POINT('Origin',(47.26,34.53,27.));
+#600=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#604,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#601=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#604,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#602=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#600))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#604,#605,#606))
+REPRESENTATION_CONTEXT('','3D')
+);
+#603=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#601))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#604,#605,#606))
+REPRESENTATION_CONTEXT('','3D')
+);
+#604=(
+LENGTH_UNIT()
+NAMED_UNIT(*)
+SI_UNIT(.MILLI.,.METRE.)
+);
+#605=(
+NAMED_UNIT(*)
+PLANE_ANGLE_UNIT()
+SI_UNIT($,.RADIAN.)
+);
+#606=(
+NAMED_UNIT(*)
+SI_UNIT($,.STERADIAN.)
+SOLID_ANGLE_UNIT()
+);
+#607=SHAPE_DEFINITION_REPRESENTATION(#608,#609);
+#608=PRODUCT_DEFINITION_SHAPE('',$,#611);
+#609=SHAPE_REPRESENTATION('',(#364),#602);
+#610=PRODUCT_DEFINITION_CONTEXT('part definition',#615,'design');
+#611=PRODUCT_DEFINITION('hackpad','hackpad v5',#612,#610);
+#612=PRODUCT_DEFINITION_FORMATION('',$,#617);
+#613=PRODUCT_RELATED_PRODUCT_CATEGORY('hackpad v5','hackpad v5',(#617));
+#614=APPLICATION_PROTOCOL_DEFINITION('international standard',
+'automotive_design',2009,#615);
+#615=APPLICATION_CONTEXT(
+'Core Data for Automotive Mechanical Design Process');
+#616=PRODUCT_CONTEXT('part definition',#615,'mechanical');
+#617=PRODUCT('hackpad','hackpad v5',$,(#616));
+#618=PRESENTATION_STYLE_ASSIGNMENT((#619));
+#619=SURFACE_STYLE_USAGE(.BOTH.,#620);
+#620=SURFACE_SIDE_STYLE('',(#621));
+#621=SURFACE_STYLE_FILL_AREA(#622);
+#622=FILL_AREA_STYLE('Steel - Satin',(#623));
+#623=FILL_AREA_STYLE_COLOUR('Steel - Satin',#624);
+#624=COLOUR_RGB('Steel - Satin',0.627450980392157,0.627450980392157,0.627450980392157);
+ENDSEC;
+END-ISO-10303-21;
diff --git a/hackpads/blipyboard/firmware/adafruit-circuitpython-seeeduino_xiao_rp2040-en_US-9.2.8.uf2 b/hackpads/blipyboard/firmware/adafruit-circuitpython-seeeduino_xiao_rp2040-en_US-9.2.8.uf2
new file mode 100644
index 0000000000..9ae47b2f98
Binary files /dev/null and b/hackpads/blipyboard/firmware/adafruit-circuitpython-seeeduino_xiao_rp2040-en_US-9.2.8.uf2 differ
diff --git a/hackpads/blipyboard/firmware/adafruit_display_text/__init__.mpy b/hackpads/blipyboard/firmware/adafruit_display_text/__init__.mpy
new file mode 100644
index 0000000000..0bee257687
Binary files /dev/null and b/hackpads/blipyboard/firmware/adafruit_display_text/__init__.mpy differ
diff --git a/hackpads/blipyboard/firmware/adafruit_display_text/bitmap_label.mpy b/hackpads/blipyboard/firmware/adafruit_display_text/bitmap_label.mpy
new file mode 100644
index 0000000000..ddf6a117ef
Binary files /dev/null and b/hackpads/blipyboard/firmware/adafruit_display_text/bitmap_label.mpy differ
diff --git a/hackpads/blipyboard/firmware/adafruit_display_text/label.mpy b/hackpads/blipyboard/firmware/adafruit_display_text/label.mpy
new file mode 100644
index 0000000000..d527058f32
Binary files /dev/null and b/hackpads/blipyboard/firmware/adafruit_display_text/label.mpy differ
diff --git a/hackpads/blipyboard/firmware/adafruit_display_text/outlined_label.mpy b/hackpads/blipyboard/firmware/adafruit_display_text/outlined_label.mpy
new file mode 100644
index 0000000000..580d1339aa
Binary files /dev/null and b/hackpads/blipyboard/firmware/adafruit_display_text/outlined_label.mpy differ
diff --git a/hackpads/blipyboard/firmware/adafruit_display_text/scrolling_label.mpy b/hackpads/blipyboard/firmware/adafruit_display_text/scrolling_label.mpy
new file mode 100644
index 0000000000..9081254b2d
Binary files /dev/null and b/hackpads/blipyboard/firmware/adafruit_display_text/scrolling_label.mpy differ
diff --git a/hackpads/blipyboard/firmware/adafruit_display_text/text_box.mpy b/hackpads/blipyboard/firmware/adafruit_display_text/text_box.mpy
new file mode 100644
index 0000000000..781fd5bdef
Binary files /dev/null and b/hackpads/blipyboard/firmware/adafruit_display_text/text_box.mpy differ
diff --git a/hackpads/blipyboard/firmware/kmk/__init__.py b/hackpads/blipyboard/firmware/kmk/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/hackpads/blipyboard/firmware/kmk/bootcfg.py b/hackpads/blipyboard/firmware/kmk/bootcfg.py
new file mode 100644
index 0000000000..9d68646d89
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/bootcfg.py
@@ -0,0 +1,138 @@
+try:
+ from typing import Optional
+except ImportError:
+ pass
+
+import digitalio
+import microcontroller
+import usb_hid
+
+
+def bootcfg(
+ sense: Optional[microcontroller.Pin, digitalio.DigitalInOut] = None,
+ source: Optional[microcontroller.Pin, digitalio.DigitalInOut] = None,
+ autoreload: bool = True,
+ boot_device: int = 0,
+ cdc_console: bool = True,
+ cdc_data: bool = False,
+ consumer_control: bool = True,
+ keyboard: bool = True,
+ midi: bool = True,
+ mouse: bool = True,
+ nkro: bool = False,
+ pan: bool = False,
+ six_axis: bool = False,
+ storage: bool = True,
+ usb_id: Optional[dict, tuple[str, str]] = {},
+ **kwargs,
+) -> bool:
+
+ if len(kwargs):
+ print('unknown option', kwargs)
+
+ if isinstance(sense, microcontroller.Pin):
+ sense = digitalio.DigitalInOut(sense)
+ sense.direction = digitalio.Direction.INPUT
+ sense.pull = digitalio.Pull.UP
+
+ if isinstance(source, microcontroller.Pin):
+ source = digitalio.DigitalInOut(source)
+ source.direction = digitalio.Direction.OUTPUT
+ source.value = False
+
+ if not autoreload:
+ import supervisor
+
+ supervisor.runtime.autoreload = False
+
+ # Parse `usb_id` tuple for backwards compatibility. This can be removed at
+ # some point in the future(TM).
+ if type(usb_id) is tuple:
+ usb_id = {'manufacturer': usb_id[0], 'product': usb_id[1]}
+
+ # configure HID devices
+ devices = []
+ if six_axis:
+ from kmk.hid_reports import six_axis
+
+ # SpaceMouse Compact
+ usb_id['vid'] = 0x256F
+ usb_id['pid'] = 0xC635
+
+ if keyboard:
+ if nkro:
+ devices.append(six_axis.NKRO_KEYBOARD)
+ else:
+ devices.append(six_axis.KEYBOARD)
+ keyboard = False
+ if mouse:
+ if pan:
+ devices.append(six_axis.POINTER)
+ else:
+ devices.append(six_axis.MOUSE)
+ mouse = False
+ if consumer_control:
+ devices.append(six_axis.CONSUMER_CONTROL)
+ consumer_control = False
+ devices.append(six_axis.SIX_AXIS)
+ if keyboard:
+ if nkro:
+ from kmk.hid_reports import nkro_keyboard
+
+ devices.append(nkro_keyboard.NKRO_KEYBOARD)
+ else:
+ devices.append(usb_hid.Device.KEYBOARD)
+ if mouse:
+ if pan:
+ from kmk.hid_reports import pointer
+
+ devices.append(pointer.POINTER)
+ else:
+ devices.append(usb_hid.Device.MOUSE)
+ if consumer_control:
+ devices.append(usb_hid.Device.CONSUMER_CONTROL)
+ if devices:
+ usb_hid.enable(devices, boot_device)
+ else:
+ usb_hid.disable()
+
+ # configure midi over usb
+ if not midi:
+ import usb_midi
+
+ usb_midi.disable()
+
+ # configure usb vendor and product id
+ if usb_id:
+ import supervisor
+
+ try:
+ supervisor.set_usb_identification(**usb_id)
+ except Exception as e:
+ print('supervisor.set_usb_identification: ', e, type(e))
+
+ # configure data serial
+ if cdc_data:
+ import usb_cdc
+
+ usb_cdc.enable(data=True)
+
+ # sense not provided or pulled low -> Skip boot configuration that may
+ # disable debug or rescue facilities.
+ if sense is None or not sense.value:
+ return False
+
+ # Entries for serial console (REPL) and storage are intentionally evaluated
+ # last to ensure the board is debuggable, mountable and rescueable, in case
+ # any of the previous code throws an exception.
+ if not cdc_console:
+ import usb_cdc
+
+ usb_cdc.enable(console=False)
+
+ if not storage:
+ import storage
+
+ storage.disable_usb_drive()
+
+ return True
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/__init__.py b/hackpads/blipyboard/firmware/kmk/extensions/__init__.py
new file mode 100644
index 0000000000..33eea68616
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/__init__.py
@@ -0,0 +1,54 @@
+class InvalidExtensionEnvironment(Exception):
+ pass
+
+
+class Extension:
+ _enabled = True
+
+ def enable(self, keyboard):
+ self._enabled = True
+
+ self.on_runtime_enable(keyboard)
+
+ def disable(self, keyboard):
+ self._enabled = False
+
+ self.on_runtime_disable(keyboard)
+
+ # The below methods should be implemented by subclasses
+
+ def on_runtime_enable(self, keyboard):
+ raise NotImplementedError
+
+ def on_runtime_disable(self, keyboard):
+ raise NotImplementedError
+
+ def during_bootup(self, keyboard):
+ raise NotImplementedError
+
+ def before_matrix_scan(self, keyboard):
+ '''
+ Return value will be injected as an extra matrix update
+ '''
+ raise NotImplementedError
+
+ def after_matrix_scan(self, keyboard):
+ '''
+ Return value will be replace matrix update if supplied
+ '''
+ raise NotImplementedError
+
+ def before_hid_send(self, keyboard):
+ raise NotImplementedError
+
+ def after_hid_send(self, keyboard):
+ raise NotImplementedError
+
+ def on_powersave_enable(self, keyboard):
+ raise NotImplementedError
+
+ def on_powersave_disable(self, keyboard):
+ raise NotImplementedError
+
+ def deinit(self, keyboard):
+ pass
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/display/__init__.py b/hackpads/blipyboard/firmware/kmk/extensions/display/__init__.py
new file mode 100644
index 0000000000..518baa5bee
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/display/__init__.py
@@ -0,0 +1,279 @@
+from supervisor import ticks_ms
+
+import displayio
+import terminalio
+from adafruit_display_text import label
+
+from kmk.extensions import Extension
+from kmk.keys import make_key
+from kmk.kmktime import PeriodicTimer, ticks_diff
+from kmk.modules.split import Split, SplitSide
+from kmk.utils import clamp
+
+
+class TextEntry:
+ def __init__(
+ self,
+ text='',
+ x=0,
+ y=0,
+ x_anchor='L',
+ y_anchor='T',
+ direction='LTR',
+ line_spacing=0.75,
+ inverted=False,
+ layer=None,
+ side=None,
+ ):
+ self.text = text
+ self.direction = direction
+ self.line_spacing = line_spacing
+ self.inverted = inverted
+ self.layer = layer
+ self.color = 0xFFFFFF
+ self.background_color = 0x000000
+ self.x_anchor = 0.0
+ self.y_anchor = 0.0
+ if x_anchor == 'L':
+ self.x_anchor = 0.0
+ x = x + 1
+ if x_anchor == 'M':
+ self.x_anchor = 0.5
+ if x_anchor == 'R':
+ self.x_anchor = 1.0
+ if y_anchor == 'T':
+ self.y_anchor = 0.0
+ if y_anchor == 'M':
+ self.y_anchor = 0.5
+ if y_anchor == 'B':
+ self.y_anchor = 1.0
+ self.anchor_point = (self.x_anchor, self.y_anchor)
+ self.anchored_position = (x, y)
+ if inverted:
+ self.color = 0x000000
+ self.background_color = 0xFFFFFF
+ self.side = side
+ if side == 'L':
+ self.side = SplitSide.LEFT
+ if side == 'R':
+ self.side = SplitSide.RIGHT
+
+
+class ImageEntry:
+ def __init__(self, x=0, y=0, image='', layer=None, side=None):
+ self.x = x
+ self.y = y
+ self.image = displayio.OnDiskBitmap(image)
+ self.layer = layer
+ self.side = side
+ if side == 'L':
+ self.side = SplitSide.LEFT
+ if side == 'R':
+ self.side = SplitSide.RIGHT
+
+
+class DisplayBase:
+ def __init__(self):
+ raise NotImplementedError
+
+ def during_bootup(self, width, height, rotation):
+ raise NotImplementedError
+
+ def deinit(self):
+ raise NotImplementedError
+
+ def sleep(self):
+ self.display.sleep()
+
+ def wake(self):
+ self.display.wake()
+
+ @property
+ def brightness(self):
+ return self.display.brightness
+
+ @brightness.setter
+ def brightness(self, new_brightness):
+ self.display.brightness = new_brightness
+
+ # display.show() is deprecated, so use root_group instead
+ @property
+ def root_group(self):
+ return self.display.root_group
+
+ @root_group.setter
+ def root_group(self, group):
+ self.display.root_group = group
+
+
+class Display(Extension):
+ def __init__(
+ self,
+ display=None,
+ entries=[],
+ width=128,
+ height=32,
+ flip: bool = False,
+ flip_left: bool = False,
+ flip_right: bool = False,
+ brightness=0.8,
+ brightness_step=0.1,
+ dim_time=20,
+ dim_target=0.1,
+ off_time=60,
+ powersave_dim_time=10,
+ powersave_dim_target=0.1,
+ powersave_off_time=30,
+ ):
+ self.display = display
+ self.flip = flip
+ self.flip_left = flip_left
+ self.flip_right = flip_right
+ self.entries = entries
+ self.width = width
+ self.height = height
+ self.prev_layer = None
+ self.brightness = brightness
+ self.brightness_step = brightness_step
+ self.timer_start = ticks_ms()
+ self.powersave = False
+ self.dim_time_ms = dim_time * 1000
+ self.dim_target = dim_target
+ self.off_time_ms = off_time * 1000
+ self.powersavedim_time_ms = powersave_dim_time * 1000
+ self.powersave_dim_target = powersave_dim_target
+ self.powersave_off_time_ms = powersave_off_time * 1000
+ self.dim_period = PeriodicTimer(50)
+ self.split_side = None
+
+ make_key(names=('DIS_BRI',), on_press=self.display_brightness_increase)
+ make_key(names=('DIS_BRD',), on_press=self.display_brightness_decrease)
+
+ def render(self, layer):
+ splash = displayio.Group()
+
+ for entry in self.entries:
+ if entry.layer != layer and entry.layer is not None:
+ continue
+ if isinstance(entry, TextEntry):
+ splash.append(
+ label.Label(
+ terminalio.FONT,
+ text=entry.text,
+ color=entry.color,
+ background_color=entry.background_color,
+ anchor_point=entry.anchor_point,
+ anchored_position=entry.anchored_position,
+ label_direction=entry.direction,
+ line_spacing=entry.line_spacing,
+ padding_left=1,
+ )
+ )
+ elif isinstance(entry, ImageEntry):
+ splash.append(
+ displayio.TileGrid(
+ entry.image,
+ pixel_shader=entry.image.pixel_shader,
+ x=entry.x,
+ y=entry.y,
+ )
+ )
+ self.display.root_group = splash
+
+ def on_runtime_enable(self, sandbox):
+ return
+
+ def on_runtime_disable(self, sandbox):
+ return
+
+ def during_bootup(self, keyboard):
+ for module in keyboard.modules:
+ if isinstance(module, Split):
+ self.split_side = module.split_side
+
+ if self.split_side == SplitSide.LEFT:
+ self.flip = self.flip_left
+ elif self.split_side == SplitSide.RIGHT:
+ self.flip = self.flip_right
+
+ for idx, entry in enumerate(self.entries):
+ if entry.side != self.split_side and entry.side is not None:
+ del self.entries[idx]
+
+ self.display.during_bootup(self.width, self.height, 180 if self.flip else 0)
+ self.display.brightness = self.brightness
+
+ def before_matrix_scan(self, sandbox):
+ if self.dim_period.tick():
+ self.dim()
+ if sandbox.active_layers[0] != self.prev_layer:
+ self.prev_layer = sandbox.active_layers[0]
+ self.render(sandbox.active_layers[0])
+
+ def after_matrix_scan(self, sandbox):
+ if sandbox.matrix_update or sandbox.secondary_matrix_update:
+ self.timer_start = ticks_ms()
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ return
+
+ def on_powersave_enable(self, sandbox):
+ self.powersave = True
+
+ def on_powersave_disable(self, sandbox):
+ self.powersave = False
+
+ def deinit(self, sandbox):
+ displayio.release_displays()
+ self.display.deinit()
+
+ def display_brightness_increase(self, *args):
+ self.display.brightness = clamp(
+ self.display.brightness + self.brightness_step, 0, 1
+ )
+ self.brightness = self.display.brightness # Save current brightness
+
+ def display_brightness_decrease(self, *args):
+ self.display.brightness = clamp(
+ self.display.brightness - self.brightness_step, 0, 1
+ )
+ self.brightness = self.display.brightness # Save current brightness
+
+ def dim(self):
+ if self.powersave:
+ if (
+ self.powersave_off_time_ms
+ and ticks_diff(ticks_ms(), self.timer_start)
+ > self.powersave_off_time_ms
+ ):
+ self.display.sleep()
+
+ elif (
+ self.powersave_dim_time_ms
+ and ticks_diff(ticks_ms(), self.timer_start)
+ > self.powersave_dim_time_ms
+ ):
+ self.display.brightness = self.powersave_dim_target
+
+ else:
+ self.display.brightness = self.brightness
+ self.display.wake()
+
+ elif (
+ self.off_time_ms
+ and ticks_diff(ticks_ms(), self.timer_start) > self.off_time_ms
+ ):
+ self.display.sleep()
+
+ elif (
+ self.dim_time_ms
+ and ticks_diff(ticks_ms(), self.timer_start) > self.dim_time_ms
+ ):
+ self.display.brightness = self.dim_target
+
+ else:
+ self.display.brightness = self.brightness
+ self.display.wake()
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/display/builtin.py b/hackpads/blipyboard/firmware/kmk/extensions/display/builtin.py
new file mode 100644
index 0000000000..9820f561df
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/display/builtin.py
@@ -0,0 +1,24 @@
+from . import DisplayBase
+
+
+# Intended for displays with drivers built into CircuitPython
+# that can be used directly without manual initialization
+class BuiltInDisplay(DisplayBase):
+ def __init__(self, display=None, sleep_command=None, wake_command=None):
+ self.display = display
+ self.sleep_command = sleep_command
+ self.wake_command = wake_command
+ self.is_awake = True
+
+ def during_bootup(self, width, height, rotation):
+ self.display.rotation = rotation
+ return self.display
+
+ def deinit(self):
+ return
+
+ def sleep(self):
+ self.display.bus.send(self.sleep_command, b'')
+
+ def wake(self):
+ self.display.bus.send(self.wake_command, b'')
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/display/sh1106.py b/hackpads/blipyboard/firmware/kmk/extensions/display/sh1106.py
new file mode 100644
index 0000000000..cf93a457ca
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/display/sh1106.py
@@ -0,0 +1,49 @@
+import busio
+
+import adafruit_displayio_sh1106 # Display-specific library
+import displayio
+
+from . import DisplayBase
+
+# Required to initialize this display
+displayio.release_displays()
+
+
+class SH1106(DisplayBase):
+ def __init__(
+ self,
+ spi=None,
+ sck=None,
+ mosi=None,
+ command=None,
+ chip_select=None,
+ reset=None,
+ baudrate=1000000,
+ ):
+ self.command = command
+ self.chip_select = chip_select
+ self.reset = reset
+ self.baudrate = baudrate
+ # spi initialization
+ self.spi = spi
+ if self.spi is None:
+ self.spi = busio.SPI(sck, mosi)
+
+ def during_bootup(self, width, height, rotation):
+ self.display = adafruit_displayio_sh1106.SH1106(
+ displayio.FourWire(
+ self.spi,
+ command=self.command,
+ chip_select=self.chip_select,
+ reset=self.reset,
+ baudrate=self.baudrate,
+ ),
+ width=width,
+ height=height,
+ rotation=rotation,
+ )
+
+ return self.display
+
+ def deinit(self):
+ self.spi.deinit()
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/display/ssd1306.py b/hackpads/blipyboard/firmware/kmk/extensions/display/ssd1306.py
new file mode 100644
index 0000000000..a6b2a0152c
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/display/ssd1306.py
@@ -0,0 +1,31 @@
+import busio
+
+import adafruit_displayio_ssd1306 # Display-specific library
+import displayio
+
+from . import DisplayBase
+
+# Required to initialize this display
+displayio.release_displays()
+
+
+class SSD1306(DisplayBase):
+ def __init__(self, i2c=None, sda=None, scl=None, device_address=0x3C):
+ self.device_address = device_address
+ # i2c initialization
+ self.i2c = i2c
+ if self.i2c is None:
+ self.i2c = busio.I2C(scl, sda)
+
+ def during_bootup(self, width, height, rotation):
+ self.display = adafruit_displayio_ssd1306.SSD1306(
+ displayio.I2CDisplay(self.i2c, device_address=self.device_address),
+ width=width,
+ height=height,
+ rotation=rotation,
+ )
+
+ return self.display
+
+ def deinit(self):
+ self.i2c.deinit()
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/international.py b/hackpads/blipyboard/firmware/kmk/extensions/international.py
new file mode 100644
index 0000000000..8d53e01ea2
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/international.py
@@ -0,0 +1,63 @@
+'''Adds international keys'''
+
+from kmk.extensions import Extension
+from kmk.keys import KeyboardKey, make_key
+
+
+class International(Extension):
+ '''Adds international keys'''
+
+ def __init__(self):
+ # International
+ codes = (
+ (50, ('NONUS_HASH', 'NUHS')),
+ (100, ('NONUS_BSLASH', 'NUBS')),
+ (101, ('APP', 'APPLICATION', 'SEL', 'WINMENU')),
+ (135, ('INT1', 'RO')),
+ (136, ('INT2', 'KANA')),
+ (137, ('INT3', 'JYEN')),
+ (138, ('INT4', 'HENK')),
+ (139, ('INT5', 'MHEN')),
+ (140, ('INT6',)),
+ (141, ('INT7',)),
+ (142, ('INT8',)),
+ (143, ('INT9',)),
+ (144, ('LANG1', 'HAEN')),
+ (145, ('LANG2', 'HAEJ')),
+ (146, ('LANG3',)),
+ (147, ('LANG4',)),
+ (148, ('LANG5',)),
+ (149, ('LANG6',)),
+ (150, ('LANG7',)),
+ (151, ('LANG8',)),
+ (152, ('LANG9',)),
+ )
+ for code, names in codes:
+ make_key(names=names, constructor=KeyboardKey, code=code)
+
+ def on_runtime_enable(self, sandbox):
+ return
+
+ def on_runtime_disable(self, sandbox):
+ return
+
+ def during_bootup(self, sandbox):
+ return
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ return
+
+ def on_powersave_enable(self, sandbox):
+ return
+
+ def on_powersave_disable(self, sandbox):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/keymap_extras/keymap_jp.py b/hackpads/blipyboard/firmware/kmk/extensions/keymap_extras/keymap_jp.py
new file mode 100644
index 0000000000..f4355dbf8e
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/keymap_extras/keymap_jp.py
@@ -0,0 +1,34 @@
+# What's this?
+# This is a keycode conversion script. With this, KMK will work as a JIS keyboard.
+
+# Usage
+# ```python
+# import kmk.extensions.keymap_extras.keymap_jp
+# ```
+
+from kmk.keys import KC
+
+KC.CIRC = KC.EQL # ^
+KC.AT = KC.LBRC # @
+KC.LBRC = KC.RBRC # [
+KC.EISU = KC.CAPS # Eisū (英数)
+KC.COLN = KC.QUOT # :
+KC.LCBR = KC.LSFT(KC.RBRC) # {
+KC.RBRC = KC.NUHS # ]
+KC.BSLS = KC.INT1 # (backslash)
+KC.PLUS = KC.LSFT(KC.SCLN)
+KC.TILD = KC.LSFT(KC.EQL) # ~
+KC.GRV = KC.LSFT(KC.AT) # `
+KC.DQUO = KC.LSFT(KC.N2) # "
+KC.AMPR = KC.LSFT(KC.N6) # &
+KC.ASTR = KC.LSFT(KC.QUOT) # *
+KC.QUOT = KC.LSFT(KC.N7) # '
+KC.LPRN = KC.LSFT(KC.N8) # (
+KC.RPRN = KC.LSFT(KC.N9) # )
+KC.EQL = KC.LSFT(KC.MINS) # =
+KC.PIPE = KC.LSFT(KC.INT3) # |
+KC.RCBR = KC.LSFT(KC.NUHS) # }
+KC.LABK = KC.LSFT(KC.COMM) # <
+KC.RABK = KC.LSFT(KC.DOT) # >
+KC.QUES = KC.LSFT(KC.SLSH) # ?
+KC.UNDS = KC.LSFT(KC.INT1) # _
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/led.py b/hackpads/blipyboard/firmware/kmk/extensions/led.py
new file mode 100644
index 0000000000..cd155efb7a
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/led.py
@@ -0,0 +1,256 @@
+import pwmio
+from math import e, exp, pi, sin
+
+from kmk.extensions import Extension, InvalidExtensionEnvironment
+from kmk.keys import Key, make_argumented_key, make_key
+from kmk.utils import Debug, clamp
+
+debug = Debug(__name__)
+
+
+class LEDKey(Key):
+ def __init__(self, *leds, brightness=None, **kwargs):
+ super().__init__(**kwargs)
+ self.leds = leds
+ self.brightness = None
+
+
+def led_set_key(brightness, *leds):
+ return LEDKey(*leds, brightness=brightness)
+
+
+class AnimationModes:
+ OFF = 0
+ STATIC = 1
+ STATIC_STANDBY = 2
+ BREATHING = 3
+ USER = 4
+
+
+class LED(Extension):
+ def __init__(
+ self,
+ led_pin,
+ brightness=50,
+ brightness_step=5,
+ brightness_limit=100,
+ breathe_center=1.5,
+ animation_mode=AnimationModes.STATIC,
+ animation_speed=1,
+ user_animation=None,
+ val=100,
+ ):
+ try:
+ pins_iter = iter(led_pin)
+ except TypeError:
+ pins_iter = [led_pin]
+
+ try:
+ self._leds = [pwmio.PWMOut(pin) for pin in pins_iter]
+ except Exception as e:
+ if debug.enabled:
+ debug(e)
+ raise InvalidExtensionEnvironment(
+ 'Unable to create pwmio.PWMOut() instance with provided led_pin'
+ )
+
+ self._brightness = brightness
+ self._pos = 0
+ self._effect_init = False
+ self._enabled = True
+
+ self.brightness_step = brightness_step
+ self.brightness_limit = brightness_limit
+ self.animation_mode = animation_mode
+ self.animation_speed = animation_speed
+ self.breathe_center = breathe_center
+ self.val = val
+
+ if user_animation is not None:
+ self.user_animation = user_animation
+
+ make_argumented_key(
+ names=('LED_TOG',),
+ constructor=LEDKey,
+ on_press=self._key_led_tog,
+ )
+ make_argumented_key(
+ names=('LED_INC',),
+ constructor=LEDKey,
+ on_press=self._key_led_inc,
+ )
+ make_argumented_key(
+ names=('LED_DEC',),
+ constructor=LEDKey,
+ on_press=self._key_led_dec,
+ )
+ make_argumented_key(
+ names=('LED_SET',),
+ constructor=led_set_key,
+ on_press=self._key_led_set,
+ )
+ make_key(names=('LED_ANI',), on_press=self._key_led_ani)
+ make_key(names=('LED_AND',), on_press=self._key_led_and)
+ make_key(
+ names=('LED_MODE_PLAIN', 'LED_M_P'), on_press=self._key_led_mode_static
+ )
+ make_key(
+ names=('LED_MODE_BREATHE', 'LED_M_B'), on_press=self._key_led_mode_breathe
+ )
+
+ def __repr__(self):
+ return f'LED({self._to_dict()})'
+
+ def _to_dict(self):
+ return {
+ '_brightness': self._brightness,
+ '_pos': self._pos,
+ 'brightness_step': self.brightness_step,
+ 'brightness_limit': self.brightness_limit,
+ 'animation_mode': self.animation_mode,
+ 'animation_speed': self.animation_speed,
+ 'breathe_center': self.breathe_center,
+ 'val': self.val,
+ }
+
+ def on_runtime_enable(self, sandbox):
+ return
+
+ def on_runtime_disable(self, sandbox):
+ return
+
+ def during_bootup(self, sandbox):
+ return
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ self.animate()
+
+ def on_powersave_enable(self, sandbox):
+ return
+
+ def on_powersave_disable(self, sandbox):
+ return
+
+ def _init_effect(self):
+ self._pos = 0
+ self._effect_init = False
+ return self
+
+ def set_brightness(self, percent, leds=None):
+ leds = leds or range(0, len(self._leds))
+ for i in leds:
+ self._leds[i].duty_cycle = int(percent / 100 * 65535)
+
+ def step_brightness(self, step, leds=None):
+ leds = leds or range(0, len(self._leds))
+ for i in leds:
+ brightness = int(self._leds[i].duty_cycle / 65535 * 100) + step
+ self.set_brightness(clamp(brightness), [i])
+
+ def increase_brightness(self, step=None, leds=None):
+ if step is None:
+ step = self.brightness_step
+ self.step_brightness(step, leds)
+
+ def decrease_brightness(self, step=None, leds=None):
+ if step is None:
+ step = self.brightness_step
+ self.step_brightness(-step, leds)
+
+ def off(self):
+ self.set_brightness(0)
+
+ def increase_ani(self):
+ '''
+ Increases animation speed by 1 amount stopping at 10
+ :param step:
+ '''
+ if (self.animation_speed + 1) >= 10:
+ self.animation_speed = 10
+ else:
+ self.val += 1
+
+ def decrease_ani(self):
+ '''
+ Decreases animation speed by 1 amount stopping at 0
+ :param step:
+ '''
+ if (self.val - 1) <= 0:
+ self.val = 0
+ else:
+ self.val -= 1
+
+ def effect_breathing(self):
+ # http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
+ # https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806
+ sined = sin((self._pos / 255.0) * pi)
+ multip_1 = exp(sined) - self.breathe_center / e
+ multip_2 = self.brightness_limit / (e - 1 / e)
+
+ self._brightness = int(multip_1 * multip_2)
+ self._pos = (self._pos + self.animation_speed) % 256
+ self.set_brightness(self._brightness)
+
+ def effect_static(self):
+ self.set_brightness(self._brightness)
+ # Set animation mode to standby to prevent cycles from being wasted
+ self.animation_mode = AnimationModes.STATIC_STANDBY
+
+ def animate(self):
+ '''
+ Activates a "step" in the animation based on the active mode
+ :return: Returns the new state in animation
+ '''
+ if self._effect_init:
+ self._init_effect()
+ if self._enabled:
+ if self.animation_mode == AnimationModes.BREATHING:
+ return self.effect_breathing()
+ elif self.animation_mode == AnimationModes.STATIC:
+ return self.effect_static()
+ elif self.animation_mode == AnimationModes.STATIC_STANDBY:
+ pass
+ elif self.animation_mode == AnimationModes.USER:
+ return self.user_animation(self)
+ else:
+ self.off()
+
+ def _key_led_tog(self, *args, **kwargs):
+ if self.animation_mode == AnimationModes.STATIC_STANDBY:
+ self.animation_mode = AnimationModes.STATIC
+
+ if self._enabled:
+ self.off()
+ self._enabled = not self._enabled
+
+ def _key_led_inc(self, key, *args, **kwargs):
+ self.increase_brightness(leds=key.leds)
+
+ def _key_led_dec(self, key, *args, **kwargs):
+ self.decrease_brightness(leds=key.leds)
+
+ def _key_led_set(self, key, *args, **kwargs):
+ self.set_brightness(percent=key.brightness, leds=key.leds)
+
+ def _key_led_ani(self, *args, **kwargs):
+ self.increase_ani()
+
+ def _key_led_and(self, *args, **kwargs):
+ self.decrease_ani()
+
+ def _key_led_mode_static(self, *args, **kwargs):
+ self._effect_init = True
+ self.animation_mode = AnimationModes.STATIC
+
+ def _key_led_mode_breathe(self, *args, **kwargs):
+ self._effect_init = True
+ self.animation_mode = AnimationModes.BREATHING
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/lock_status.py b/hackpads/blipyboard/firmware/kmk/extensions/lock_status.py
new file mode 100644
index 0000000000..85b890d3bb
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/lock_status.py
@@ -0,0 +1,69 @@
+import usb_hid
+from micropython import const
+
+from kmk.extensions import Extension
+
+_NUMLOCK = const(0x01)
+_CAPSLOCK = const(0x02)
+_SCROLLLOCK = const(0x04)
+_COMPOSE = const(0x08)
+_KANA = const(0x10)
+
+
+class LockStatus(Extension):
+ def __init__(self):
+ self.report = 0
+ self.hid = None
+ self._report_updated = False
+
+ def __repr__(self):
+ return f'LockStatus(report={self.report})'
+
+ def during_bootup(self, sandbox):
+ for device in usb_hid.devices:
+ if device.usage == usb_hid.Device.KEYBOARD.usage:
+ self.hid = device
+ if self.hid is None:
+ raise RuntimeError
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ report = self.hid.get_last_received_report()
+ if report is None:
+ self._report_updated = False
+ else:
+ self.report = report[0]
+ self._report_updated = True
+
+ def on_powersave_enable(self, sandbox):
+ return
+
+ def on_powersave_disable(self, sandbox):
+ return
+
+ @property
+ def report_updated(self):
+ return self._report_updated
+
+ def get_num_lock(self):
+ return bool(self.report & _NUMLOCK)
+
+ def get_caps_lock(self):
+ return bool(self.report & _CAPSLOCK)
+
+ def get_scroll_lock(self):
+ return bool(self.report & _SCROLLLOCK)
+
+ def get_compose(self):
+ return bool(self.report & _COMPOSE)
+
+ def get_kana(self):
+ return bool(self.report & _KANA)
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/media_keys.py b/hackpads/blipyboard/firmware/kmk/extensions/media_keys.py
new file mode 100644
index 0000000000..19edda23cc
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/media_keys.py
@@ -0,0 +1,61 @@
+from kmk.extensions import Extension
+from kmk.keys import ConsumerKey, make_key
+
+
+class MediaKeys(Extension):
+ def __init__(self):
+ # Consumer ("media") keys. Most known keys aren't supported here. A much
+ # longer list used to exist in this file, but the codes were almost certainly
+ # incorrect, conflicting with each other, or otherwise 'weird'. We'll add them
+ # back in piecemeal as needed. PRs welcome.
+ #
+ # A super useful reference for these is http://www.freebsddiary.org/APC/usb_hid_usages.php
+ # Note that currently we only have the PC codes. Recent MacOS versions seem to
+ # support PC media keys, so I don't know how much value we would get out of
+ # adding the old Apple-specific consumer codes, but again, PRs welcome if the
+ # lack of them impacts you.
+
+ codes = (
+ (0xE2, ('AUDIO_MUTE', 'MUTE')),
+ (0xE9, ('AUDIO_VOL_UP', 'VOLU')),
+ (0xEA, ('AUDIO_VOL_DOWN', 'VOLD')),
+ (0x6F, ('BRIGHTNESS_UP', 'BRIU')),
+ (0x70, ('BRIGHTNESS_DOWN', 'BRID')),
+ (0xB5, ('MEDIA_NEXT_TRACK', 'MNXT')),
+ (0xB6, ('MEDIA_PREV_TRACK', 'MPRV')),
+ (0xB7, ('MEDIA_STOP', 'MSTP')),
+ (0xCD, ('MEDIA_PLAY_PAUSE', 'MPLY')),
+ (0xB8, ('MEDIA_EJECT', 'EJCT')),
+ (0xB3, ('MEDIA_FAST_FORWARD', 'MFFD')),
+ (0xB4, ('MEDIA_REWIND', 'MRWD')),
+ )
+
+ for code, names in codes:
+ make_key(names=names, constructor=ConsumerKey, code=code)
+
+ def on_runtime_enable(self, sandbox):
+ return
+
+ def on_runtime_disable(self, sandbox):
+ return
+
+ def during_bootup(self, sandbox):
+ return
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ return
+
+ def on_powersave_enable(self, sandbox):
+ return
+
+ def on_powersave_disable(self, sandbox):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/peg_rgb_matrix.py b/hackpads/blipyboard/firmware/kmk/extensions/peg_rgb_matrix.py
new file mode 100644
index 0000000000..816dc57836
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/peg_rgb_matrix.py
@@ -0,0 +1,200 @@
+import neopixel
+
+from storage import getmount
+
+from kmk.extensions import Extension
+from kmk.keys import make_key
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class Color:
+ OFF = [0, 0, 0]
+ BLACK = OFF
+ WHITE = [249, 249, 249]
+ RED = [255, 0, 0]
+ AZURE = [153, 245, 255]
+ BLUE = [0, 0, 255]
+ CYAN = [0, 255, 255]
+ GREEN = [0, 255, 0]
+ YELLOW = [255, 247, 0]
+ MAGENTA = [255, 0, 255]
+ ORANGE = [255, 77, 0]
+ PURPLE = [255, 0, 242]
+ TEAL = [0, 128, 128]
+ PINK = [255, 0, 255]
+
+
+class Rgb_matrix_data:
+ def __init__(self, keys=[], underglow=[]):
+ if len(keys) == 0:
+ if debug.enabled:
+ debug('No colors passed for your keys')
+ return
+ if len(underglow) == 0:
+ if debug.enabled:
+ debug('No colors passed for your underglow')
+ return
+ self.data = keys + underglow
+
+ @staticmethod
+ def generate_led_map(
+ number_of_keys, number_of_underglow, key_color, underglow_color
+ ):
+ keys = [key_color] * number_of_keys
+ underglow = [underglow_color] * number_of_underglow
+ if debug.enabled:
+ debug('Rgb_matrix_data(keys=', keys, ', nunderglow=', underglow, ')')
+
+
+class Rgb_matrix(Extension):
+ def __init__(
+ self,
+ rgb_order=(1, 0, 2), # GRB WS2812
+ disable_auto_write=False,
+ ledDisplay=[],
+ split=False,
+ rightSide=False,
+ ):
+ name = str(getmount('/').label)
+ self.rgb_order = rgb_order
+ self.disable_auto_write = disable_auto_write
+ self.split = split
+ self.rightSide = rightSide
+ self.brightness_step = 0.1
+ self.brightness = 0
+
+ if name.endswith('L'):
+ self.rightSide = False
+ elif name.endswith('R'):
+ self.rightSide = True
+ if type(ledDisplay) is Rgb_matrix_data:
+ self.ledDisplay = ledDisplay.data
+ else:
+ self.ledDisplay = ledDisplay
+
+ make_key(names=('RGB_TOG',), on_press=self._rgb_tog)
+ make_key(names=('RGB_BRI',), on_press=self._rgb_bri)
+ make_key(names=('RGB_BRD',), on_press=self._rgb_brd)
+
+ def _rgb_tog(self, *args, **kwargs):
+ if self.enable:
+ self.off()
+ else:
+ self.on()
+ self.enable = not self.enable
+
+ def _rgb_bri(self, *args, **kwargs):
+ self.increase_brightness()
+
+ def _rgb_brd(self, *args, **kwargs):
+ self.decrease_brightness()
+
+ def on(self):
+ if self.neopixel:
+ self.setBasedOffDisplay()
+ self.neopixel.show()
+
+ def off(self):
+ if self.neopixel:
+ self.set_rgb_fill((0, 0, 0))
+
+ def set_rgb_fill(self, rgb):
+ if self.neopixel:
+ self.neopixel.fill(rgb)
+ if self.disable_auto_write:
+ self.neopixel.show()
+
+ def set_brightness(self, brightness=None):
+ if brightness is None:
+ brightness = self.brightness
+
+ if self.neopixel:
+ self.neopixel.brightness = brightness
+ if self.disable_auto_write:
+ self.neopixel.show()
+
+ def increase_brightness(self, step=None):
+ if step is None:
+ step = self.brightness_step
+
+ self.brightness = (
+ self.brightness + step if self.brightness + step <= 1.0 else 1.0
+ )
+
+ self.set_brightness(self.brightness)
+
+ def decrease_brightness(self, step=None):
+ if step is None:
+ step = self.brightness_step
+
+ self.brightness = (
+ self.brightness - step if self.brightness - step >= 0.0 else 0.0
+ )
+ self.set_brightness(self.brightness)
+
+ def setBasedOffDisplay(self):
+ if self.split:
+ for i, val in enumerate(self.ledDisplay):
+ if self.rightSide:
+ if self.keyPos[i] >= (self.num_pixels / 2):
+ self.neopixel[int(self.keyPos[i] - (self.num_pixels / 2))] = (
+ val[0],
+ val[1],
+ val[2],
+ )
+ else:
+ if self.keyPos[i] <= (self.num_pixels / 2):
+ self.neopixel[self.keyPos[i]] = (val[0], val[1], val[2])
+ else:
+ for i, val in enumerate(self.ledDisplay):
+ self.neopixel[self.keyPos[i]] = (val[0], val[1], val[2])
+
+ def on_runtime_enable(self, sandbox):
+ return
+
+ def on_runtime_disable(self, sandbox):
+ return
+
+ def during_bootup(self, board):
+ self.neopixel = neopixel.NeoPixel(
+ board.rgb_pixel_pin,
+ board.num_pixels,
+ brightness=board.brightness_limit,
+ pixel_order=self.rgb_order,
+ auto_write=not self.disable_auto_write,
+ )
+ self.num_pixels = board.num_pixels
+ self.keyPos = board.led_key_pos
+ self.brightness = board.brightness_limit
+ self.on()
+ return
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ return
+
+ def on_powersave_enable(self, sandbox):
+ if self.neopixel:
+ self.neopixel.brightness = (
+ self.neopixel.brightness / 2
+ if self.neopixel.brightness / 2 > 0
+ else 0.1
+ )
+ if self.disable_auto_write:
+ self.neopixel.show()
+
+ def on_powersave_disable(self, sandbox):
+ if self.neopixel:
+ self.neopixel.brightness = self.brightness
+ if self.disable_auto_write:
+ self.neopixel.show()
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/rgb.py b/hackpads/blipyboard/firmware/kmk/extensions/rgb.py
new file mode 100644
index 0000000000..e54e939b92
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/rgb.py
@@ -0,0 +1,551 @@
+from adafruit_pixelbuf import PixelBuf
+from math import e, exp, pi, sin
+
+from kmk.extensions import Extension
+from kmk.keys import make_key
+from kmk.scheduler import create_task
+from kmk.utils import Debug, clamp
+
+debug = Debug(__name__)
+
+rgb_config = {}
+
+
+def hsv_to_rgb(hue, sat, val):
+ '''
+ Converts HSV values, and returns a tuple of RGB values
+ :param hue:
+ :param sat:
+ :param val:
+ :return: (r, g, b)
+ '''
+ if sat == 0:
+ return (val, val, val)
+
+ hue = 6 * (hue & 0xFF)
+ frac = hue & 0xFF
+ sxt = hue >> 8
+
+ base = (0xFF - sat) * val
+ color = (val * sat * frac) >> 8
+ val <<= 8
+
+ if sxt == 0:
+ r = val
+ g = base + color
+ b = base
+ elif sxt == 1:
+ r = val - color
+ g = val
+ b = base
+ elif sxt == 2:
+ r = base
+ g = val
+ b = base + color
+ elif sxt == 3:
+ r = base
+ g = val - color
+ b = val
+ elif sxt == 4:
+ r = base + color
+ g = base
+ b = val
+ elif sxt == 5:
+ r = val
+ g = base
+ b = val - color
+
+ return (r >> 8), (g >> 8), (b >> 8)
+
+
+def hsv_to_rgbw(hue, sat, val):
+ '''
+ Converts HSV values, and returns a tuple of RGBW values
+ :param hue:
+ :param sat:
+ :param val:
+ :return: (r, g, b, w)
+ '''
+ rgb = hsv_to_rgb(hue, sat, val)
+ return rgb[0], rgb[1], rgb[2], min(rgb)
+
+
+class AnimationModes:
+ OFF = 0
+ STATIC = 1
+ STATIC_STANDBY = 2
+ BREATHING = 3
+ RAINBOW = 4
+ BREATHING_RAINBOW = 5
+ KNIGHT = 6
+ SWIRL = 7
+ USER = 8
+
+
+class RGB(Extension):
+ pos = 0
+
+ def __init__(
+ self,
+ pixel_pin,
+ num_pixels=0,
+ rgb_order=(1, 0, 2), # GRB WS2812
+ val_limit=255,
+ hue_default=0,
+ sat_default=255,
+ val_default=255,
+ hue_step=4,
+ sat_step=13,
+ val_step=13,
+ animation_speed=1,
+ breathe_center=1, # 1.0-2.7
+ knight_effect_length=3,
+ animation_mode=AnimationModes.STATIC,
+ effect_init=False,
+ reverse_animation=False,
+ user_animation=None,
+ pixels=None,
+ refresh_rate=60,
+ ):
+ self.pixel_pin = pixel_pin
+ self.num_pixels = num_pixels
+ self.rgb_order = rgb_order
+ self.hue_step = hue_step
+ self.sat_step = sat_step
+ self.val_step = val_step
+ self.hue = hue_default
+ self.hue_default = hue_default
+ self.sat = sat_default
+ self.sat_default = sat_default
+ self.val = val_default
+ self.val_default = val_default
+ self.breathe_center = breathe_center
+ self.knight_effect_length = knight_effect_length
+ self.val_limit = val_limit
+ self.animation_mode = animation_mode
+ self.animation_speed = animation_speed
+ self.effect_init = effect_init
+ self.reverse_animation = reverse_animation
+ self.user_animation = user_animation
+ self.pixels = pixels
+ self.refresh_rate = refresh_rate
+
+ self.rgbw = bool(len(rgb_order) == 4)
+
+ self._substep = 0
+
+ make_key(names=('RGB_TOG',), on_press=self._rgb_tog)
+ make_key(names=('RGB_HUI',), on_press=self._rgb_hui)
+ make_key(names=('RGB_HUD',), on_press=self._rgb_hud)
+ make_key(names=('RGB_SAI',), on_press=self._rgb_sai)
+ make_key(names=('RGB_SAD',), on_press=self._rgb_sad)
+ make_key(names=('RGB_VAI',), on_press=self._rgb_vai)
+ make_key(names=('RGB_VAD',), on_press=self._rgb_vad)
+ make_key(names=('RGB_ANI',), on_press=self._rgb_ani)
+ make_key(names=('RGB_AND',), on_press=self._rgb_and)
+ make_key(names=('RGB_MODE_PLAIN', 'RGB_M_P'), on_press=self._rgb_mode_static)
+ make_key(names=('RGB_MODE_BREATHE', 'RGB_M_B'), on_press=self._rgb_mode_breathe)
+ make_key(names=('RGB_MODE_RAINBOW', 'RGB_M_R'), on_press=self._rgb_mode_rainbow)
+ make_key(
+ names=('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'),
+ on_press=self._rgb_mode_breathe_rainbow,
+ )
+ make_key(names=('RGB_MODE_SWIRL', 'RGB_M_S'), on_press=self._rgb_mode_swirl)
+ make_key(names=('RGB_MODE_KNIGHT', 'RGB_M_K'), on_press=self._rgb_mode_knight)
+ make_key(names=('RGB_RESET', 'RGB_RST'), on_press=self._rgb_reset)
+
+ def on_runtime_enable(self, sandbox):
+ return
+
+ def on_runtime_disable(self, sandbox):
+ return
+
+ def during_bootup(self, sandbox):
+ if self.pixels is None:
+ import neopixel
+
+ self.pixels = neopixel.NeoPixel(
+ self.pixel_pin,
+ self.num_pixels,
+ pixel_order=self.rgb_order,
+ )
+
+ # PixelBuffer are already iterable, can't do the usual `try: iter(...)`
+ if issubclass(self.pixels.__class__, PixelBuf):
+ self.pixels = (self.pixels,)
+
+ # Turn off auto_write on the backend. We handle the propagation of auto_write
+ # behaviour.
+ for pixel in self.pixels:
+ pixel.auto_write = False
+
+ if self.num_pixels == 0:
+ for pixels in self.pixels:
+ self.num_pixels += len(pixels)
+
+ if debug.enabled:
+ for n, pixels in enumerate(self.pixels):
+ debug(f'pixels[{n}] = {pixels.__class__}[{len(pixels)}]')
+
+ self._task = create_task(self.animate, period_ms=(1000 // self.refresh_rate))
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ pass
+
+ def on_powersave_enable(self, sandbox):
+ return
+
+ def on_powersave_disable(self, sandbox):
+ self._do_update()
+
+ def deinit(self, sandbox):
+ for pixel in self.pixels:
+ pixel.deinit()
+
+ def set_hsv(self, hue, sat, val, index):
+ '''
+ Takes HSV values and displays it on a single LED/Neopixel
+ :param hue:
+ :param sat:
+ :param val:
+ :param index: Index of LED/Pixel
+ '''
+
+ val = clamp(val, 0, self.val_limit)
+
+ if self.rgbw:
+ self.set_rgb(hsv_to_rgbw(hue, sat, val), index)
+ else:
+ self.set_rgb(hsv_to_rgb(hue, sat, val), index)
+
+ def set_hsv_fill(self, hue, sat, val):
+ '''
+ Takes HSV values and displays it on all LEDs/Neopixels
+ :param hue:
+ :param sat:
+ :param val:
+ '''
+
+ val = clamp(val, 0, self.val_limit)
+
+ if self.rgbw:
+ self.set_rgb_fill(hsv_to_rgbw(hue, sat, val))
+ else:
+ self.set_rgb_fill(hsv_to_rgb(hue, sat, val))
+
+ def set_rgb(self, rgb, index):
+ '''
+ Takes an RGB or RGBW and displays it on a single LED/Neopixel
+ :param rgb: RGB or RGBW
+ :param index: Index of LED/Pixel
+ '''
+ if 0 <= index <= self.num_pixels - 1:
+ for pixels in self.pixels:
+ if index <= (len(pixels) - 1):
+ pixels[index] = rgb
+ break
+ index -= len(pixels)
+
+ def set_rgb_fill(self, rgb):
+ '''
+ Takes an RGB or RGBW and displays it on all LEDs/Neopixels
+ :param rgb: RGB or RGBW
+ '''
+ for pixels in self.pixels:
+ pixels.fill(rgb)
+
+ def increase_hue(self, step=None):
+ '''
+ Increases hue by step amount rolling at 256 and returning to 0
+ :param step:
+ '''
+ if step is None:
+ step = self.hue_step
+
+ self.hue = (self.hue + step) % 256
+
+ if self._check_update():
+ self._do_update()
+
+ def decrease_hue(self, step=None):
+ '''
+ Decreases hue by step amount rolling at 0 and returning to 256
+ :param step:
+ '''
+ if step is None:
+ step = self.hue_step
+
+ if (self.hue - step) <= 0:
+ self.hue = (self.hue + 256 - step) % 256
+ else:
+ self.hue = (self.hue - step) % 256
+
+ if self._check_update():
+ self._do_update()
+
+ def increase_sat(self, step=None):
+ '''
+ Increases saturation by step amount stopping at 255
+ :param step:
+ '''
+ if step is None:
+ step = self.sat_step
+
+ self.sat = clamp(self.sat + step, 0, 255)
+
+ if self._check_update():
+ self._do_update()
+
+ def decrease_sat(self, step=None):
+ '''
+ Decreases saturation by step amount stopping at 0
+ :param step:
+ '''
+ if step is None:
+ step = self.sat_step
+
+ self.sat = clamp(self.sat - step, 0, 255)
+
+ if self._check_update():
+ self._do_update()
+
+ def increase_val(self, step=None):
+ '''
+ Increases value by step amount stopping at 100
+ :param step:
+ '''
+ if step is None:
+ step = self.val_step
+
+ self.val = clamp(self.val + step, 0, 255)
+
+ if self._check_update():
+ self._do_update()
+
+ def decrease_val(self, step=None):
+ '''
+ Decreases value by step amount stopping at 0
+ :param step:
+ '''
+ if step is None:
+ step = self.val_step
+
+ self.val = clamp(self.val - step, 0, 255)
+
+ if self._check_update():
+ self._do_update()
+
+ def increase_ani(self):
+ '''
+ Increases animation speed by 1 amount stopping at 10
+ :param step:
+ '''
+ self.animation_speed = clamp(self.animation_speed + 1, 0, 10)
+
+ if self._check_update():
+ self._do_update()
+
+ def decrease_ani(self):
+ '''
+ Decreases animation speed by 1 amount stopping at 0
+ :param step:
+ '''
+ self.animation_speed = clamp(self.animation_speed - 1, 0, 10)
+
+ if self._check_update():
+ self._do_update()
+
+ def off(self):
+ '''
+ Turns off all LEDs/Neopixels without changing stored values
+ '''
+ self.set_hsv_fill(0, 0, 0)
+
+ self.show()
+
+ def show(self):
+ '''
+ Turns on all LEDs/Neopixels without changing stored values
+ '''
+ for pixels in self.pixels:
+ pixels.show()
+
+ def animate(self):
+ '''
+ Activates a "step" in the animation based on the active mode
+ :return: Returns the new state in animation
+ '''
+ if self.effect_init:
+ self._init_effect()
+
+ if self.animation_mode is AnimationModes.STATIC_STANDBY:
+ return
+
+ if not self.enable:
+ return
+
+ self._animation_step()
+
+ if self.animation_mode == AnimationModes.STATIC_STANDBY:
+ return
+ elif self.animation_mode == AnimationModes.BREATHING:
+ self.effect_breathing()
+ elif self.animation_mode == AnimationModes.BREATHING_RAINBOW:
+ self.effect_breathing_rainbow()
+ elif self.animation_mode == AnimationModes.KNIGHT:
+ self.effect_knight()
+ elif self.animation_mode == AnimationModes.RAINBOW:
+ self.effect_rainbow()
+ elif self.animation_mode == AnimationModes.STATIC:
+ self.effect_static()
+ elif self.animation_mode == AnimationModes.SWIRL:
+ self.effect_swirl()
+ elif self.animation_mode == AnimationModes.USER:
+ self.user_animation(self)
+ else:
+ self.off()
+
+ self.show()
+
+ def _animation_step(self):
+ self._substep += self.animation_speed / 4
+ self._step = int(self._substep)
+ self._substep -= self._step
+
+ def _init_effect(self):
+ self.pos = 0
+ self.reverse_animation = False
+ self.effect_init = False
+
+ def _check_update(self):
+ return bool(self.animation_mode == AnimationModes.STATIC_STANDBY)
+
+ def _do_update(self):
+ if self.animation_mode == AnimationModes.STATIC_STANDBY:
+ self.animation_mode = AnimationModes.STATIC
+
+ def effect_static(self):
+ self.set_hsv_fill(self.hue, self.sat, self.val)
+ self.animation_mode = AnimationModes.STATIC_STANDBY
+
+ def effect_breathing(self):
+ # http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
+ # https://github.com/qmk/qmk_firmware/blob/9f1d781fcb7129a07e671a46461e501e3f1ae59d/quantum/rgblight.c#L806
+ sined = sin((self.pos / 255.0) * pi)
+ multip_1 = exp(sined) - self.breathe_center / e
+ multip_2 = clamp(self.val, 0, self.val_limit) / (e - 1 / e)
+
+ val = int(multip_1 * multip_2)
+ self.pos = (self.pos + self._step) % 256
+ self.set_hsv_fill(self.hue, self.sat, val)
+
+ def effect_breathing_rainbow(self):
+ self.increase_hue(self._step)
+ self.effect_breathing()
+
+ def effect_rainbow(self):
+ self.increase_hue(self._step)
+ self.set_hsv_fill(self.hue, self.sat, self.val)
+
+ def effect_swirl(self):
+ self.increase_hue(self._step)
+ for i in range(0, self.num_pixels):
+ self.set_hsv(
+ (self.hue - (i * self.num_pixels)) % 256, self.sat, self.val, i
+ )
+
+ def effect_knight(self):
+ # Determine which LEDs should be lit up
+ self.off() # Fill all off
+ pos = int(self.pos)
+
+ # Set all pixels on in range of animation length offset by position
+ for i in range(pos, (pos + self.knight_effect_length)):
+ self.set_hsv(self.hue, self.sat, self.val, i)
+
+ # Reverse animation when a boundary is hit
+ if pos >= self.num_pixels:
+ self.reverse_animation = True
+ elif 1 - pos > self.knight_effect_length:
+ self.reverse_animation = False
+
+ if self.reverse_animation:
+ self.pos -= self._step / 2
+ else:
+ self.pos += self._step / 2
+
+ def _rgb_tog(self, *args, **kwargs):
+ if self.animation_mode == AnimationModes.STATIC:
+ self.animation_mode = AnimationModes.STATIC_STANDBY
+ self._do_update()
+ if self.animation_mode == AnimationModes.STATIC_STANDBY:
+ self.animation_mode = AnimationModes.STATIC
+ self._do_update()
+ if self.enable:
+ self.off()
+ self.enable = not self.enable
+
+ def _rgb_hui(self, *args, **kwargs):
+ self.increase_hue()
+
+ def _rgb_hud(self, *args, **kwargs):
+ self.decrease_hue()
+
+ def _rgb_sai(self, *args, **kwargs):
+ self.increase_sat()
+
+ def _rgb_sad(self, *args, **kwargs):
+ self.decrease_sat()
+
+ def _rgb_vai(self, *args, **kwargs):
+ self.increase_val()
+
+ def _rgb_vad(self, *args, **kwargs):
+ self.decrease_val()
+
+ def _rgb_ani(self, *args, **kwargs):
+ self.increase_ani()
+
+ def _rgb_and(self, *args, **kwargs):
+ self.decrease_ani()
+
+ def _rgb_mode_static(self, *args, **kwargs):
+ self.effect_init = True
+ self.animation_mode = AnimationModes.STATIC
+
+ def _rgb_mode_breathe(self, *args, **kwargs):
+ self.effect_init = True
+ self.animation_mode = AnimationModes.BREATHING
+
+ def _rgb_mode_breathe_rainbow(self, *args, **kwargs):
+ self.effect_init = True
+ self.animation_mode = AnimationModes.BREATHING_RAINBOW
+
+ def _rgb_mode_rainbow(self, *args, **kwargs):
+ self.effect_init = True
+ self.animation_mode = AnimationModes.RAINBOW
+
+ def _rgb_mode_swirl(self, *args, **kwargs):
+ self.effect_init = True
+ self.animation_mode = AnimationModes.SWIRL
+
+ def _rgb_mode_knight(self, *args, **kwargs):
+ self.effect_init = True
+ self.animation_mode = AnimationModes.KNIGHT
+
+ def _rgb_reset(self, *args, **kwargs):
+ self.hue = self.hue_default
+ self.sat = self.sat_default
+ self.val = self.val_default
+ if self.animation_mode == AnimationModes.STATIC_STANDBY:
+ self.animation_mode = AnimationModes.STATIC
+ self._do_update()
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/spacemouse_status.py b/hackpads/blipyboard/firmware/kmk/extensions/spacemouse_status.py
new file mode 100644
index 0000000000..64d566493d
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/spacemouse_status.py
@@ -0,0 +1,54 @@
+import usb_hid
+from micropython import const
+
+from kmk.extensions import Extension
+
+_SIX_AXIS_USAGE = const(0x08)
+_LED = const(0x01)
+
+
+class SpacemouseStatus(Extension):
+ def __init__(self):
+ self.report = 0
+ self.hid = None
+ self._report_updated = False
+
+ def __repr__(self):
+ return f'SpacemouseStatus(report={self.report})'
+
+ def during_bootup(self, sandbox):
+ for device in usb_hid.devices:
+ if device.usage == _SIX_AXIS_USAGE:
+ self.hid = device
+ if self.hid is None:
+ raise RuntimeError
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ report = self.hid.get_last_received_report(4)
+ if report is None:
+ self._report_updated = False
+ else:
+ self.report = report[0]
+ self._report_updated = True
+
+ def on_powersave_enable(self, sandbox):
+ return
+
+ def on_powersave_disable(self, sandbox):
+ return
+
+ @property
+ def report_updated(self):
+ return self._report_updated
+
+ def get_led(self):
+ return bool(self.report & _LED)
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/statusled.py b/hackpads/blipyboard/firmware/kmk/extensions/statusled.py
new file mode 100644
index 0000000000..7610ca121d
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/statusled.py
@@ -0,0 +1,149 @@
+# Use this extension for showing layer status with three leds
+
+import pwmio
+import time
+
+from kmk.extensions import Extension, InvalidExtensionEnvironment
+from kmk.keys import make_key
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class statusLED(Extension):
+ def __init__(
+ self,
+ led_pins,
+ brightness=30,
+ brightness_step=5,
+ brightness_limit=100,
+ ):
+ self._leds = []
+ for led in led_pins:
+ try:
+ self._leds.append(pwmio.PWMOut(led))
+ except Exception as e:
+ if debug.enabled:
+ debug(e)
+ raise InvalidExtensionEnvironment(
+ 'Unable to create pulseio.PWMOut() instance with provided led_pin'
+ )
+ self._led_count = len(self._leds)
+
+ self.brightness = brightness
+ self._layer_last = -1
+
+ self.brightness_step = brightness_step
+ self.brightness_limit = brightness_limit
+
+ make_key(names=('SLED_INC',), on_press=self._key_led_inc)
+ make_key(names=('SLED_DEC',), on_press=self._key_led_dec)
+
+ def _layer_indicator(self, layer_active, *args, **kwargs):
+ '''
+ Indicates layer with leds
+
+ For the time being just a simple consecutive single led
+ indicator. And when there are more layers than leds it
+ wraps around to the first led again.
+ (Also works for a single led, which just lights when any
+ layer is active)
+ '''
+
+ if self._layer_last != layer_active:
+ led_last = 0 if self._layer_last == 0 else 1 + (self._layer_last - 1) % 3
+ if layer_active > 0:
+ led_active = 0 if layer_active == 0 else 1 + (layer_active - 1) % 3
+ self.set_brightness(self.brightness, led_active)
+ self.set_brightness(0, led_last)
+ else:
+ self.set_brightness(0, led_last)
+ self._layer_last = layer_active
+
+ def __repr__(self):
+ return f'SLED({self._to_dict()})'
+
+ def _to_dict(self):
+ return {
+ 'brightness': self.brightness,
+ 'brightness_step': self.brightness_step,
+ 'brightness_limit': self.brightness_limit,
+ }
+
+ def on_runtime_enable(self, sandbox):
+ return
+
+ def on_runtime_disable(self, sandbox):
+ return
+
+ def during_bootup(self, sandbox):
+ '''Light up every single led once for 200 ms'''
+ for i in range(self._led_count + 2):
+ if i < self._led_count:
+ self._leds[i].duty_cycle = int(self.brightness / 100 * 65535)
+ i_off = i - 2
+ if i_off >= 0 and i_off < self._led_count:
+ self._leds[i_off].duty_cycle = int(0)
+ time.sleep(0.1)
+ for led in self._leds:
+ led.duty_cycle = int(0)
+ return
+
+ def before_matrix_scan(self, sandbox):
+ return
+
+ def after_matrix_scan(self, sandbox):
+ self._layer_indicator(sandbox.active_layers[0])
+ return
+
+ def before_hid_send(self, sandbox):
+ return
+
+ def after_hid_send(self, sandbox):
+ return
+
+ def on_powersave_enable(self, sandbox):
+ self.set_brightness(0)
+ return
+
+ def on_powersave_disable(self, sandbox):
+ self.set_brightness(self.brightness)
+ self._leds[2].duty_cycle = int(50 / 100 * 65535)
+ time.sleep(0.2)
+ self._leds[2].duty_cycle = int(0)
+ return
+
+ def set_brightness(self, percent, layer_id=-1):
+ if layer_id < 0:
+ for led in self._leds:
+ led.duty_cycle = int(percent / 100 * 65535)
+ else:
+ self._leds[layer_id - 1].duty_cycle = int(percent / 100 * 65535)
+
+ def increase_brightness(self, step=None):
+ if not step:
+ self.brightness += self.brightness_step
+ else:
+ self.brightness += step
+
+ if self.brightness > 100:
+ self.brightness = 100
+
+ self.set_brightness(self.brightness, self._layer_last)
+
+ def decrease_brightness(self, step=None):
+ if not step:
+ self.brightness -= self.brightness_step
+ else:
+ self.brightness -= step
+
+ if self.brightness < 0:
+ self.brightness = 0
+
+ self.set_brightness(self.brightness, self._layer_last)
+
+ def _key_led_inc(self, *args, **kwargs):
+ self.increase_brightness()
+
+ def _key_led_dec(self, *args, **kwargs):
+ self.decrease_brightness()
diff --git a/hackpads/blipyboard/firmware/kmk/extensions/stringy_keymaps.py b/hackpads/blipyboard/firmware/kmk/extensions/stringy_keymaps.py
new file mode 100644
index 0000000000..ea8e490a3f
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/extensions/stringy_keymaps.py
@@ -0,0 +1,44 @@
+from kmk.extensions import Extension
+from kmk.keys import KC
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class StringyKeymaps(Extension):
+ def on_runtime_enable(self, keyboard):
+ return
+
+ def on_runtime_disable(self, keyboard):
+ return
+
+ def during_bootup(self, keyboard):
+ for _, layer in enumerate(keyboard.keymap):
+ for key_idx, key in enumerate(layer):
+ if isinstance(key, str):
+ replacement = KC.get(key)
+ if replacement is None:
+ replacement = KC.NO
+ if debug.enabled:
+ debug('Failed replacing ', key, '. Using KC.NO')
+ elif debug.enabled:
+ debug('Replacing ', key, ' with ', replacement)
+ layer[key_idx] = replacement
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/handlers/__init__.py b/hackpads/blipyboard/firmware/kmk/handlers/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/hackpads/blipyboard/firmware/kmk/handlers/stock.py b/hackpads/blipyboard/firmware/kmk/handlers/stock.py
new file mode 100644
index 0000000000..437f70480e
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/handlers/stock.py
@@ -0,0 +1,121 @@
+from time import sleep
+
+
+def passthrough(key, keyboard, *args, **kwargs):
+ return keyboard
+
+
+def reset(*args, **kwargs):
+ import microcontroller
+
+ microcontroller.reset()
+
+
+def reload(*args, **kwargs):
+ import supervisor
+
+ supervisor.reload()
+
+
+def bootloader(*args, **kwargs):
+ import microcontroller
+
+ microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
+ microcontroller.reset()
+
+
+def gesc_pressed(key, keyboard, KC, *args, **kwargs):
+ GESC_TRIGGERS = {KC.LSHIFT, KC.RSHIFT, KC.LGUI, KC.RGUI}
+
+ if GESC_TRIGGERS.intersection(keyboard.keys_pressed):
+ # First, release GUI if already pressed
+ keyboard._send_hid()
+ # if Shift is held, KC_GRAVE will become KC_TILDE on OS level
+ keyboard.keys_pressed.add(KC.GRAVE)
+ keyboard.hid_pending = True
+ return keyboard
+
+ # else return KC_ESC
+ keyboard.keys_pressed.add(KC.ESCAPE)
+ keyboard.hid_pending = True
+
+ return keyboard
+
+
+def gesc_released(key, keyboard, KC, *args, **kwargs):
+ keyboard.keys_pressed.discard(KC.ESCAPE)
+ keyboard.keys_pressed.discard(KC.GRAVE)
+ keyboard.hid_pending = True
+ return keyboard
+
+
+def bkdl_pressed(key, keyboard, KC, *args, **kwargs):
+ BKDL_TRIGGERS = {KC.LGUI, KC.RGUI}
+
+ if BKDL_TRIGGERS.intersection(keyboard.keys_pressed):
+ keyboard._send_hid()
+ keyboard.keys_pressed.add(KC.DEL)
+ keyboard.hid_pending = True
+ return keyboard
+
+ # else return KC_ESC
+ keyboard.keys_pressed.add(KC.BKSP)
+ keyboard.hid_pending = True
+
+ return keyboard
+
+
+def bkdl_released(key, keyboard, KC, *args, **kwargs):
+ keyboard.keys_pressed.discard(KC.BKSP)
+ keyboard.keys_pressed.discard(KC.DEL)
+ keyboard.hid_pending = True
+ return keyboard
+
+
+def sleep_pressed(key, keyboard, KC, *args, **kwargs):
+ sleep(key.meta.ms / 1000)
+ return keyboard
+
+
+def uc_mode_pressed(key, keyboard, *args, **kwargs):
+ keyboard.unicode_mode = key.meta.mode
+
+ return keyboard
+
+
+def hid_switch(key, keyboard, *args, **kwargs):
+ keyboard.hid_type, keyboard.secondary_hid_type = (
+ keyboard.secondary_hid_type,
+ keyboard.hid_type,
+ )
+ keyboard._init_hid()
+ return keyboard
+
+
+def ble_refresh(key, keyboard, *args, **kwargs):
+ from kmk.hid import HIDModes
+
+ if keyboard.hid_type != HIDModes.BLE:
+ return keyboard
+
+ keyboard._hid_helper.stop_advertising()
+ keyboard._hid_helper.start_advertising()
+ return keyboard
+
+
+def ble_disconnect(key, keyboard, *args, **kwargs):
+ from kmk.hid import HIDModes
+
+ if keyboard.hid_type != HIDModes.BLE:
+ return keyboard
+
+ keyboard._hid_helper.clear_bonds()
+ return keyboard
+
+
+def any_pressed(key, keyboard, *args, **kwargs):
+ from random import randint
+
+ key.code = randint(4, 56)
+ keyboard.keys_pressed.add(key)
+ keyboard.hid_pending = True
diff --git a/hackpads/blipyboard/firmware/kmk/hid.py b/hackpads/blipyboard/firmware/kmk/hid.py
new file mode 100644
index 0000000000..567fd83ffb
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/hid.py
@@ -0,0 +1,379 @@
+import supervisor
+import usb_hid
+from micropython import const
+
+from struct import pack, pack_into
+
+from kmk.keys import (
+ Axis,
+ ConsumerKey,
+ KeyboardKey,
+ ModifierKey,
+ MouseKey,
+ SixAxis,
+ SpacemouseKey,
+)
+from kmk.scheduler import cancel_task, create_task
+from kmk.utils import Debug, clamp
+
+try:
+ from adafruit_ble import BLERadio
+ from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
+ from adafruit_ble.services.standard.hid import HIDService
+ from storage import getmount
+
+ _BLE_APPEARANCE_HID_KEYBOARD = const(961)
+except ImportError:
+ # BLE not supported on this platform
+ pass
+
+
+debug = Debug(__name__)
+
+
+class HIDModes:
+ NOOP = 0 # currently unused; for testing?
+ USB = 1
+ BLE = 2
+
+
+_USAGE_PAGE_CONSUMER = const(0x0C)
+_USAGE_PAGE_KEYBOARD = const(0x01)
+_USAGE_PAGE_MOUSE = const(0x01)
+_USAGE_PAGE_SIXAXIS = const(0x01)
+_USAGE_PAGE_SYSCONTROL = const(0x01)
+
+_USAGE_CONSUMER = const(0x01)
+_USAGE_KEYBOARD = const(0x06)
+_USAGE_MOUSE = const(0x02)
+_USAGE_SIXAXIS = const(0x08)
+_USAGE_SYSCONTROL = const(0x80)
+
+_REPORT_SIZE_CONSUMER = const(2)
+_REPORT_SIZE_KEYBOARD = const(8)
+_REPORT_SIZE_KEYBOARD_NKRO = const(16)
+_REPORT_SIZE_MOUSE = const(4)
+_REPORT_SIZE_MOUSE_HSCROLL = const(5)
+_REPORT_SIZE_SIXAXIS = const(12)
+_REPORT_SIZE_SIXAXIS_BUTTON = const(2)
+_REPORT_SIZE_SYSCONTROL = const(8)
+
+
+def find_device(devices, usage_page, usage):
+ for device in devices:
+ if (
+ device.usage_page == usage_page
+ and device.usage == usage
+ and hasattr(device, 'send_report')
+ ):
+ return device
+
+
+class Report:
+ def __init__(self, size):
+ self.buffer = bytearray(size)
+ self.pending = False
+
+ def clear(self):
+ for k, v in enumerate(self.buffer):
+ if v:
+ self.buffer[k] = 0x00
+ self.pending = True
+
+ def get_action_map(self):
+ return {}
+
+
+class KeyboardReport(Report):
+ def __init__(self, size=_REPORT_SIZE_KEYBOARD):
+ self.buffer = bytearray(size)
+ self.prev_buffer = bytearray(size)
+
+ @property
+ def pending(self):
+ return self.buffer != self.prev_buffer
+
+ @pending.setter
+ def pending(self, v):
+ if v is False:
+ self.prev_buffer[:] = self.buffer[:]
+
+ def clear(self):
+ for idx in range(len(self.buffer)):
+ self.buffer[idx] = 0x00
+
+ def add_key(self, key):
+ # Find the first empty slot in the key report, and fill it; drop key if
+ # report is full.
+ idx = self.buffer.find(b'\x00', 2)
+
+ if 0 < idx < _REPORT_SIZE_KEYBOARD:
+ self.buffer[idx] = key.code
+
+ def remove_key(self, key):
+ idx = self.buffer.find(pack('B', key.code), 2)
+ if 0 < idx:
+ self.buffer[idx] = 0x00
+
+ def add_modifier(self, modifier):
+ self.buffer[0] |= modifier.code
+
+ def remove_modifier(self, modifier):
+ self.buffer[0] &= ~modifier.code
+
+ def get_action_map(self):
+ return {KeyboardKey: self.add_key, ModifierKey: self.add_modifier}
+
+
+class NKROKeyboardReport(KeyboardReport):
+ def __init__(self):
+ super().__init__(_REPORT_SIZE_KEYBOARD_NKRO)
+
+ def add_key(self, key):
+ self.buffer[(key.code >> 3) + 1] |= 1 << (key.code & 0x07)
+
+ def remove_key(self, key):
+ self.buffer[(key.code >> 3) + 1] &= ~(1 << (key.code & 0x07))
+
+
+class ConsumerControlReport(Report):
+ def __init__(self):
+ super().__init__(_REPORT_SIZE_CONSUMER)
+
+ def add_cc(self, cc):
+ pack_into('> 8)
+ self.pending = True
+ except IndexError:
+ if debug.enabled:
+ debug(axis, ' not supported')
+
+ def get_action_map(self):
+ return {SixAxis: self.move_six_axis}
+
+
+class SixAxisDeviceButtonReport(Report):
+ def __init__(self, size=_REPORT_SIZE_SIXAXIS_BUTTON):
+ super().__init__(size)
+
+ def add_six_axis_button(self, key):
+ self.buffer[0] |= key.code
+ self.pending = True
+
+ def remove_six_axis_button(self, key):
+ self.buffer[0] &= ~key.code
+ self.pending = True
+
+ def get_action_map(self):
+ return {SpacemouseKey: self.add_six_axis_button}
+
+
+class IdentifiedDevice:
+ def __init__(self, device, report_id):
+ self.device = device
+ self.report_id = report_id
+
+ def send_report(self, buffer):
+ self.device.send_report(buffer, self.report_id)
+
+
+class AbstractHID:
+ def __init__(self):
+ self.report_map = {}
+ self.device_map = {}
+ self._setup_task = create_task(self.setup, period_ms=100)
+
+ def __repr__(self):
+ return self.__class__.__name__
+
+ def create_report(self, keys):
+ for report in self.device_map.keys():
+ report.clear()
+
+ for key in keys:
+ if action := self.report_map.get(type(key)):
+ action(key)
+
+ def send(self):
+ for report in self.device_map.keys():
+ if report.pending:
+ self.device_map[report].send_report(report.buffer)
+ report.pending = False
+
+ def setup(self):
+ if not self.connected:
+ return
+
+ try:
+ self.setup_keyboard_hid()
+ self.setup_consumer_control()
+ self.setup_mouse_hid()
+ self.setup_sixaxis_hid()
+
+ cancel_task(self._setup_task)
+ self._setup_task = None
+ if debug.enabled:
+ self.show_debug()
+
+ except OSError as e:
+ if debug.enabled:
+ debug(type(e), ':', e)
+
+ def setup_keyboard_hid(self):
+ if device := find_device(self.devices, _USAGE_PAGE_KEYBOARD, _USAGE_KEYBOARD):
+ # bodgy NKRO autodetect
+ try:
+ report = KeyboardReport()
+ device.send_report(report.buffer)
+ except ValueError:
+ report = NKROKeyboardReport()
+
+ self.report_map.update(report.get_action_map())
+ self.device_map[report] = device
+
+ def setup_consumer_control(self):
+ if device := find_device(self.devices, _USAGE_PAGE_CONSUMER, _USAGE_CONSUMER):
+ report = ConsumerControlReport()
+ self.report_map.update(report.get_action_map())
+ self.device_map[report] = device
+
+ def setup_mouse_hid(self):
+ if device := find_device(self.devices, _USAGE_PAGE_MOUSE, _USAGE_MOUSE):
+ # bodgy pointing device panning autodetect
+ try:
+ report = PointingDeviceReport()
+ device.send_report(report.buffer)
+ except ValueError:
+ report = HSPointingDeviceReport()
+
+ self.report_map.update(report.get_action_map())
+ self.device_map[report] = device
+
+ def setup_sixaxis_hid(self):
+ if device := find_device(self.devices, _USAGE_PAGE_SIXAXIS, _USAGE_SIXAXIS):
+ report = SixAxisDeviceReport()
+ self.report_map.update(report.get_action_map())
+ self.device_map[report] = IdentifiedDevice(device, 1)
+ report = SixAxisDeviceButtonReport()
+ self.report_map.update(report.get_action_map())
+ self.device_map[report] = IdentifiedDevice(device, 3)
+
+ def show_debug(self):
+ for report in self.device_map.keys():
+ debug('use ', report.__class__.__name__)
+
+
+class USBHID(AbstractHID):
+ @property
+ def connected(self):
+ return supervisor.runtime.usb_connected
+
+ @property
+ def devices(self):
+ return usb_hid.devices
+
+
+class BLEHID(AbstractHID):
+ def __init__(self, ble_name=None):
+ super().__init__()
+
+ self.ble = BLERadio()
+ self.ble.name = ble_name if ble_name else getmount('/').label
+ self.ble_connected = False
+
+ self.hid = HIDService()
+ self.hid.protocol_mode = 0 # Boot protocol
+
+ create_task(self.ble_monitor, period_ms=1000)
+
+ @property
+ def connected(self):
+ return self.ble.connected
+
+ @property
+ def devices(self):
+ return self.hid.devices
+
+ def ble_monitor(self):
+ if self.ble_connected != self.connected:
+ self.ble_connected = self.connected
+ if debug.enabled:
+ if self.connected:
+ debug('BLE connected')
+ else:
+ debug('BLE disconnected')
+
+ if not self.connected:
+ # Security-wise this is not right. While you're away someone turns
+ # on your keyboard and they can pair with it nice and clean and then
+ # listen to keystrokes.
+ # On the other hand we don't have LESC so it's like shouting your
+ # keystrokes in the air
+ self.start_advertising()
+
+ def clear_bonds(self):
+ import _bleio
+
+ _bleio.adapter.erase_bonding()
+
+ def start_advertising(self):
+ if not self.ble.advertising:
+ advertisement = ProvideServicesAdvertisement(self.hid)
+ advertisement.appearance = _BLE_APPEARANCE_HID_KEYBOARD
+
+ self.ble.start_advertising(advertisement)
+
+ def stop_advertising(self):
+ self.ble.stop_advertising()
diff --git a/hackpads/blipyboard/firmware/kmk/hid_reports/nkro_keyboard.py b/hackpads/blipyboard/firmware/kmk/hid_reports/nkro_keyboard.py
new file mode 100644
index 0000000000..51933775e8
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/hid_reports/nkro_keyboard.py
@@ -0,0 +1,50 @@
+import usb_hid
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls),
+ 0x09, 0x06, # Usage (Keyboard),
+ 0xA1, 0x01, # Collection (Application),
+ 0x85, 0x01, # Report ID (1)
+ # modifiers
+ 0x05, 0x07, # Usage Page (Key Codes),
+ 0x19, 0xE0, # Usage Minimum (224),
+ 0x29, 0xE7, # Usage Maximum (231),
+ 0x15, 0x00, # Logical Minimum (0),
+ 0x25, 0x01, # Logical Maximum (1),
+ 0x75, 0x01, # Report Size (1),
+ 0x95, 0x08, # Report Count (8),
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ # LEDs
+ 0x05, 0x08, # Usage Page (LEDs),
+ 0x19, 0x01, # Usage Minimum (1),
+ 0x29, 0x05, # Usage Maximum (5),
+ 0x95, 0x05, # Report Count (5),
+ 0x75, 0x01, # Report Size (1),
+ 0x91, 0x02, # Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non- olatile)
+ 0x95, 0x01, # Report Count (1),
+ 0x75, 0x03, # Report Size (3),
+ 0x91, 0x01, # Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,N n-volatile)
+ # keys
+ 0x05, 0x07, # Usage Page (Kbrd/Keypad),
+ 0x19, 0x00, # Usage Minimum (0),
+ 0x29, 0x77, # Usage Maximum (119),
+ 0x15, 0x00, # Logical Minimum (0),
+ 0x25, 0x01, # Logical Maximum(1),
+ 0x95, 0x78, # Report Count (120),
+ 0x75, 0x01, # Report Size (1),
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+NKRO_KEYBOARD = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x01,
+ usage=0x06,
+ report_ids=(0x01,),
+ in_report_lengths=(16,),
+ out_report_lengths=(1,),
+)
diff --git a/hackpads/blipyboard/firmware/kmk/hid_reports/pointer.py b/hackpads/blipyboard/firmware/kmk/hid_reports/pointer.py
new file mode 100644
index 0000000000..9e9f1b09fd
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/hid_reports/pointer.py
@@ -0,0 +1,53 @@
+import usb_hid
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x02, # Usage (Mouse)
+ 0xA1, 0x01, # Collection (Application)
+ 0x09, 0x01, # Usage (Pointer)
+ 0xA1, 0x00, # Collection (Physical)
+ 0x85, 0x02, # Report ID (2)
+ 0x05, 0x09, # Usage Page (Button)
+ 0x19, 0x01, # Usage Minimum (0x01)
+ 0x29, 0x05, # Usage Maximum (0x05)
+ 0x15, 0x00, # Logical Minimum (0)
+ 0x25, 0x01, # Logical Maximum (1)
+ 0x95, 0x05, # Report Count (5)
+ 0x75, 0x01, # Report Size (1)
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x03, # Report Size (3)
+ 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x30, # Usage (X)
+ 0x09, 0x31, # Usage (Y)
+ 0x09, 0x38, # Usage (Wheel)
+ 0x15, 0x81, # Logical Minimum (-127)
+ 0x25, 0x7F, # Logical Maximum (127)
+ 0x95, 0x03, # Report Count (3)
+ 0x75, 0x08, # Report Size (8)
+ 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
+ 0x05, 0x0C, # Usage Page (Consumer Devices)
+ 0x0A, 0x38, 0x02, # Usage (AC Pan)
+ 0x15, 0x81, # Logical Minimum (-127)
+ 0x25, 0x7F, # Logical Maximum (127)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x08, # Report Size (8)
+ 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+
+POINTER = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x01,
+ usage=0x02,
+ report_ids=(0x02,),
+ in_report_lengths=(5,),
+ out_report_lengths=(0,),
+)
diff --git a/hackpads/blipyboard/firmware/kmk/hid_reports/six_axis.py b/hackpads/blipyboard/firmware/kmk/hid_reports/six_axis.py
new file mode 100644
index 0000000000..b289a125f5
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/hid_reports/six_axis.py
@@ -0,0 +1,324 @@
+import usb_hid
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x08, # Usage (Multi-axis Controller)
+ 0xA1, 0x01, # Collection (Application)
+ 0xA1, 0x00, # Collection (Physical)
+ 0x85, 0x01, # Report ID (1)
+ 0x16, 0x0C, 0xFE, # Logical Minimum (-500)
+ 0x26, 0xF4, 0x01, # Logical Maximum (500)
+ 0x36, 0x00, 0x80, # Physical Minimum (-32768)
+ 0x46, 0xFF, 0x7F, # Physical Maximum (32767)
+ 0x55, 0x0C, # Unit Exponent (-4)
+ 0x65, 0x11, # Unit (System: SI Linear, Length: Centimeter)
+ 0x09, 0x30, # Usage (X)
+ 0x09, 0x31, # Usage (Y)
+ 0x09, 0x32, # Usage (Z)
+ 0x09, 0x33, # Usage (Rx)
+ 0x09, 0x34, # Usage (Ry)
+ 0x09, 0x35, # Usage (Rz)
+ 0x75, 0x10, # Report Size (16)
+ 0x95, 0x06, # Report Count (6)
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+
+ 0xA1, 0x00, # Collection (Physical)
+ 0x85, 0x03, # Report ID (3)
+ 0x05, 0x09, # Usage Page (Button)
+ 0x19, 0x01, # Usage Minimum (1)
+ 0x29, 0x02, # Usage Maximum (2)
+ 0x15, 0x00, # Logical Minimum (0)
+ 0x25, 0x01, # Logical Maximum (1)
+ 0x35, 0x00, # Physical Minimum (0)
+ 0x45, 0x01, # Physical Maximum (1)
+ 0x75, 0x01, # Report Size (1)
+ 0x95, 0x02, # Report Count (2)
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x95, 0x0E, # Report Count (14)
+ 0x81, 0x03, # Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+
+ 0xA1, 0x02, # Collection (Logical)
+ 0x85, 0x04, # Report ID (4)
+ 0x05, 0x08, # Usage Page (LEDs)
+ 0x09, 0x4B, # Usage (Generic Indicator)
+ 0x15, 0x00, # Logical Minimum (0)
+ 0x25, 0x01, # Logical Maximum (1)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x01, # Report Size (1)
+ 0x91, 0x02, # Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x07, # Report Size (7)
+ 0x91, 0x03, # Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ 0xC0, # End Collection
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+SIX_AXIS = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x01,
+ usage=0x08,
+ report_ids=(
+ 0x01,
+ 0x03,
+ 0x04,
+ ),
+ in_report_lengths=(
+ 12,
+ 2,
+ 0,
+ ),
+ out_report_lengths=(
+ 0,
+ 0,
+ 1,
+ ),
+)
+
+
+# Keyboard descriptors using Report ID 5
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x06, # Usage (Keyboard)
+ 0xA1, 0x01, # Collection (Application)
+ 0x85, 0x05, # Report ID (5)
+
+ 0x05, 0x07, # Usage Page (Kbrd/Keypad)
+ 0x19, 0xE0, # Usage Minimum (224)
+ 0x29, 0xE7, # Usage Maximum (231)
+ 0x15, 0x00, # Logical Minimum (0)
+ 0x25, 0x01, # Logical Maximum (1)
+ 0x75, 0x01, # Report Size (1)
+ 0x95, 0x08, # Report Count (8)
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x08, # Report Size (8)
+ 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x95, 0x05, # Report Count (5)
+ 0x75, 0x01, # Report Size (1)
+
+ 0x05, 0x08, # Usage Page (LEDs)
+ 0x19, 0x01, # Usage Minimum (Num Lock)
+ 0x29, 0x05, # Usage Maximum (Kana)
+ 0x91, 0x02, # Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x03, # Report Size (3)
+ 0x91, 0x01, # Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ 0x95, 0x06, # Report Count (6)
+ 0x75, 0x08, # Report Size (8)
+ 0x15, 0x00, # Logical Minimum (0)
+ 0x26, 0xFF, 0x00, # Logical Maximum (255)
+
+ 0x05, 0x07, # Usage Page (Kbrd/Keypad)
+ 0x19, 0x00, # Usage Minimum (0)
+ 0x2A, 0xFF, 0x00, # Usage Maximum (255)
+ 0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+KEYBOARD = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x01,
+ usage=0x06,
+ report_ids=(0x05,),
+ in_report_lengths=(8,),
+ out_report_lengths=(1,),
+)
+
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls),
+ 0x09, 0x06, # Usage (Keyboard),
+ 0xA1, 0x01, # Collection (Application),
+ 0x85, 0x05, # Report ID (5)
+ # Modifiers
+ 0x05, 0x07, # Usage Page (Key Codes),
+ 0x19, 0xE0, # Usage Minimum (224),
+ 0x29, 0xE7, # Usage Maximum (231),
+ 0x15, 0x00, # Logical Minimum (0),
+ 0x25, 0x01, # Logical Maximum (1),
+ 0x75, 0x01, # Report Size (1),
+ 0x95, 0x08, # Report Count (8),
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ # LEDs
+ 0x05, 0x08, # Usage Page (LEDs),
+ 0x19, 0x01, # Usage Minimum (1),
+ 0x29, 0x05, # Usage Maximum (5),
+ 0x95, 0x05, # Report Count (5),
+ 0x75, 0x01, # Report Size (1),
+ 0x91, 0x02, # Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non- olatile)
+ 0x95, 0x01, # Report Count (1),
+ 0x75, 0x03, # Report Size (3),
+ 0x91, 0x01, # Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,N n-volatile)
+ # Keys
+ 0x05, 0x07, # Usage Page (Kbrd/Keypad),
+ 0x19, 0x00, # Usage Minimum (0),
+ 0x29, 0x77, # Usage Maximum (119),
+ 0x15, 0x00, # Logical Minimum (0),
+ 0x25, 0x01, # Logical Maximum(1),
+ 0x95, 0x78, # Report Count (120),
+ 0x75, 0x01, # Report Size (1),
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+NKRO_KEYBOARD = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x01,
+ usage=0x06,
+ report_ids=(0x05,),
+ in_report_lengths=(16,),
+ out_report_lengths=(1,),
+)
+
+
+# Mouse descriptors using Report ID 6
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x02, # Usage (Mouse)
+ 0xA1, 0x01, # Collection (Application)
+ 0x09, 0x01, # Usage (Pointer)
+ 0xA1, 0x00, # Collection (Physical)
+ 0x85, 0x06, # Report ID (6)
+
+ 0x05, 0x09, # Usage Page (Button)
+ 0x19, 0x01, # Usage Minimum (1)
+ 0x29, 0x05, # Usage Maximum (5)
+ 0x15, 0x00, # Logical Minimum (0)
+ 0x25, 0x01, # Logical Maximum (1)
+ 0x95, 0x05, # Report Count (5)
+ 0x75, 0x01, # Report Size (1)
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x03, # Report Size (3)
+ 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x30, # Usage (X)
+ 0x09, 0x31, # Usage (Y)
+ 0x09, 0x38, # Usage (Wheel)
+ 0x15, 0x81, # Logical Minimum (-127)
+ 0x25, 0x7F, # Logical Maximum (127)
+ 0x95, 0x03, # Report Count (3)
+ 0x75, 0x08, # Report Size (8)
+ 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+
+MOUSE = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x01,
+ usage=0x02,
+ report_ids=(0x06,),
+ in_report_lengths=(4,),
+ out_report_lengths=(0,),
+)
+
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x02, # Usage (Mouse)
+ 0xA1, 0x01, # Collection (Application)
+ 0x09, 0x01, # Usage (Pointer)
+ 0xA1, 0x00, # Collection (Physical)
+ 0x85, 0x06, # Report ID (6)
+
+ 0x05, 0x09, # Usage Page (Button)
+ 0x19, 0x01, # Usage Minimum (1)
+ 0x29, 0x05, # Usage Maximum (5)
+ 0x15, 0x00, # Logical Minimum (0)
+ 0x25, 0x01, # Logical Maximum (1)
+ 0x95, 0x05, # Report Count (5)
+ 0x75, 0x01, # Report Size (1)
+ 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x03, # Report Size (3)
+ 0x81, 0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+
+ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls)
+ 0x09, 0x30, # Usage (X)
+ 0x09, 0x31, # Usage (Y)
+ 0x09, 0x38, # Usage (Wheel)
+ 0x15, 0x81, # Logical Minimum (-127)
+ 0x25, 0x7F, # Logical Maximum (127)
+ 0x95, 0x03, # Report Count (3)
+ 0x75, 0x08, # Report Size (8)
+ 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
+
+ 0x05, 0x0C, # Usage Page (Consumer Devices)
+ 0x0A, 0x38, 0x02, # Usage (AC Pan)
+ 0x15, 0x81, # Logical Minimum (-127)
+ 0x25, 0x7F, # Logical Maximum (127)
+ 0x95, 0x01, # Report Count (1)
+ 0x75, 0x08, # Report Size (8)
+ 0x81, 0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+
+POINTER = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x01,
+ usage=0x02,
+ report_ids=(0x06,),
+ in_report_lengths=(5,),
+ out_report_lengths=(0,),
+)
+
+
+# Consumer Control descriptor using Report ID 7
+
+# fmt:off
+report_descriptor = bytes(
+ (
+ 0x05, 0x0C, # Usage Page (Consumer)
+ 0x09, 0x01, # Usage (Consumer Control)
+ 0xA1, 0x01, # Collection (Application)
+ 0x85, 0x07, # Report ID (7)
+ 0x75, 0x10, # Report Size (16)
+ 0x95, 0x01, # Report Count (1)
+ 0x15, 0x01, # Logical Minimum (1)
+ 0x26, 0x8C, 0x02, # Logical Maximum (652)
+ 0x19, 0x01, # Usage Minimum (Consumer Control)
+ 0x2A, 0x8C, 0x02, # Usage Maximum (AC Send)
+ 0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0xC0, # End Collection
+ )
+)
+# fmt:on
+
+
+CONSUMER_CONTROL = usb_hid.Device(
+ report_descriptor=report_descriptor,
+ usage_page=0x0C,
+ usage=0x01,
+ report_ids=(0x07,),
+ in_report_lengths=(2,),
+ out_report_lengths=(0,),
+)
diff --git a/hackpads/blipyboard/firmware/kmk/keys.py b/hackpads/blipyboard/firmware/kmk/keys.py
new file mode 100644
index 0000000000..af59ba9143
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/keys.py
@@ -0,0 +1,593 @@
+try:
+ from typing import Callable, Optional, Tuple
+except ImportError:
+ pass
+
+import kmk.handlers.stock as handlers
+from kmk.utils import Debug
+
+# Type aliases / forward declaration; can't use the proper types because of circular imports.
+Keyboard = object
+Key = object
+
+
+ALL_ALPHAS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ALL_NUMBERS = '1234567890'
+# since KC.1 isn't valid Python, alias to KC.N1
+ALL_NUMBER_ALIASES = tuple(f'N{x}' for x in ALL_NUMBERS)
+
+debug = Debug(__name__)
+
+
+class Axis:
+ def __init__(self, code: int) -> None:
+ self.code = code
+ self.delta = 0
+
+ def __repr__(self) -> str:
+ return f'Axis(code={self.code}, delta={self.delta})'
+
+ def move(self, keyboard: Keyboard, delta: int):
+ self.delta += delta
+ if self.delta:
+ keyboard.keys_pressed.add(self)
+ keyboard.hid_pending = True
+ else:
+ keyboard.keys_pressed.discard(self)
+
+
+class SixAxis(Axis):
+ def __repr__(self) -> str:
+ return f'SixAxis(code={self.code}, delta={self.delta})'
+
+
+class AX:
+ P = Axis(3)
+ W = Axis(2)
+ X = Axis(0)
+ Y = Axis(1)
+
+
+class SM:
+ A = SixAxis(3)
+ B = SixAxis(4)
+ C = SixAxis(5)
+ X = SixAxis(0)
+ Y = SixAxis(1)
+ Z = SixAxis(2)
+
+
+def maybe_make_key(
+ names: Tuple[str, ...],
+ *args,
+ **kwargs,
+) -> Callable[[str], Key]:
+ def closure(candidate):
+ if candidate in names:
+ return make_key(names=names, *args, **kwargs)
+
+ return closure
+
+
+def maybe_make_argumented_key(
+ names: Tuple[str, ...],
+ constructor: [Key, Callable[[...], Key]],
+ **kwargs,
+) -> Callable[[str], Key]:
+ def closure(candidate):
+ if candidate in names:
+ return make_argumented_key(
+ names=names,
+ constructor=constructor,
+ **kwargs,
+ )
+
+ return closure
+
+
+def maybe_make_no_key(candidate: str) -> Optional[Key]:
+ # NO and TRNS are functionally identical in how they (don't) mutate
+ # the state, but are tracked semantically separately, so create
+ # two keys with the exact same functionality
+ keys = (
+ ('NO', 'XXXXXXX'),
+ ('TRANSPARENT', 'TRNS'),
+ )
+
+ for names in keys:
+ if candidate in names:
+ return make_key(
+ names=names,
+ on_press=handlers.passthrough,
+ on_release=handlers.passthrough,
+ )
+
+
+def maybe_make_alpha_key(candidate: str) -> Optional[Key]:
+ if len(candidate) != 1:
+ return
+
+ candidate_upper = candidate.upper()
+ if candidate_upper in ALL_ALPHAS:
+ return make_key(
+ names=(candidate_upper, candidate.lower()),
+ constructor=KeyboardKey,
+ code=4 + ALL_ALPHAS.index(candidate_upper),
+ )
+
+
+def maybe_make_numeric_key(candidate: str) -> Optional[Key]:
+ if candidate in ALL_NUMBERS or candidate in ALL_NUMBER_ALIASES:
+ try:
+ offset = ALL_NUMBERS.index(candidate)
+ except ValueError:
+ offset = ALL_NUMBER_ALIASES.index(candidate)
+
+ return make_key(
+ names=(ALL_NUMBERS[offset], ALL_NUMBER_ALIASES[offset]),
+ constructor=KeyboardKey,
+ code=30 + offset,
+ )
+
+
+def maybe_make_mod_key(candidate: str) -> Optional[Key]:
+ # MEH = LCTL | LALT | LSFT
+ # HYPR = LCTL | LALT | LSFT | LGUI
+ mods = (
+ (0x01, ('LEFT_CONTROL', 'LCTRL', 'LCTL')),
+ (0x02, ('LEFT_SHIFT', 'LSHIFT', 'LSFT')),
+ (0x04, ('LEFT_ALT', 'LALT', 'LOPT')),
+ (0x08, ('LEFT_SUPER', 'LGUI', 'LCMD', 'LWIN')),
+ (0x10, ('RIGHT_CONTROL', 'RCTRL', 'RCTL')),
+ (0x20, ('RIGHT_SHIFT', 'RSHIFT', 'RSFT')),
+ (0x40, ('RIGHT_ALT', 'RALT', 'ROPT')),
+ (0x80, ('RIGHT_SUPER', 'RGUI', 'RCMD', 'RWIN')),
+ (0x07, ('MEH',)),
+ (0x0F, ('HYPER', 'HYPR')),
+ )
+
+ for code, names in mods:
+ if candidate in names:
+ return make_key(names=names, constructor=ModifierKey, code=code)
+
+
+def maybe_make_more_ascii(candidate: str) -> Optional[Key]:
+ codes = (
+ (40, ('ENTER', 'ENT', '\n')),
+ (41, ('ESCAPE', 'ESC')),
+ (42, ('BACKSPACE', 'BSPACE', 'BSPC', 'BKSP')),
+ (43, ('TAB', '\t')),
+ (44, ('SPACE', 'SPC', ' ')),
+ (45, ('MINUS', 'MINS', '-')),
+ (46, ('EQUAL', 'EQL', '=')),
+ (47, ('LBRACKET', 'LBRC', '[')),
+ (48, ('RBRACKET', 'RBRC', ']')),
+ (49, ('BACKSLASH', 'BSLASH', 'BSLS', '\\')),
+ (51, ('SEMICOLON', 'SCOLON', 'SCLN', ';')),
+ (52, ('QUOTE', 'QUOT', "'")),
+ (53, ('GRAVE', 'GRV', 'ZKHK', '`')),
+ (54, ('COMMA', 'COMM', ',')),
+ (55, ('DOT', '.')),
+ (56, ('SLASH', 'SLSH', '/')),
+ )
+
+ for code, names in codes:
+ if candidate in names:
+ return make_key(names=names, constructor=KeyboardKey, code=code)
+
+
+def maybe_make_fn_key(candidate: str) -> Optional[Key]:
+ codes = (
+ (58, ('F1',)),
+ (59, ('F2',)),
+ (60, ('F3',)),
+ (61, ('F4',)),
+ (62, ('F5',)),
+ (63, ('F6',)),
+ (64, ('F7',)),
+ (65, ('F8',)),
+ (66, ('F9',)),
+ (67, ('F10',)),
+ (68, ('F11',)),
+ (69, ('F12',)),
+ (104, ('F13',)),
+ (105, ('F14',)),
+ (106, ('F15',)),
+ (107, ('F16',)),
+ (108, ('F17',)),
+ (109, ('F18',)),
+ (110, ('F19',)),
+ (111, ('F20',)),
+ (112, ('F21',)),
+ (113, ('F22',)),
+ (114, ('F23',)),
+ (115, ('F24',)),
+ )
+
+ for code, names in codes:
+ if candidate in names:
+ return make_key(names=names, constructor=KeyboardKey, code=code)
+
+
+def maybe_make_navlock_key(candidate: str) -> Optional[Key]:
+ codes = (
+ (57, ('CAPS_LOCK', 'CAPSLOCK', 'CLCK', 'CAPS')),
+ # FIXME: Investigate whether this key actually works, and
+ # uncomment when/if it does.
+ # (130, ('LOCKING_CAPS', 'LCAP')),
+ (70, ('PRINT_SCREEN', 'PSCREEN', 'PSCR')),
+ (71, ('SCROLL_LOCK', 'SCROLLLOCK', 'SLCK')),
+ # FIXME: Investigate whether this key actually works, and
+ # uncomment when/if it does.
+ # (132, ('LOCKING_SCROLL', 'LSCRL')),
+ (72, ('PAUSE', 'PAUS', 'BRK')),
+ (73, ('INSERT', 'INS')),
+ (74, ('HOME',)),
+ (75, ('PGUP',)),
+ (76, ('DELETE', 'DEL')),
+ (77, ('END',)),
+ (78, ('PGDOWN', 'PGDN')),
+ (79, ('RIGHT', 'RGHT')),
+ (80, ('LEFT',)),
+ (81, ('DOWN',)),
+ (82, ('UP',)),
+ )
+
+ for code, names in codes:
+ if candidate in names:
+ return make_key(names=names, constructor=KeyboardKey, code=code)
+
+
+def maybe_make_numpad_key(candidate: str) -> Optional[Key]:
+ codes = (
+ (83, ('NUM_LOCK', 'NUMLOCK', 'NLCK')),
+ (84, ('KP_SLASH', 'NUMPAD_SLASH', 'PSLS')),
+ (85, ('KP_ASTERISK', 'NUMPAD_ASTERISK', 'PAST')),
+ (86, ('KP_MINUS', 'NUMPAD_MINUS', 'PMNS')),
+ (87, ('KP_PLUS', 'NUMPAD_PLUS', 'PPLS')),
+ (88, ('KP_ENTER', 'NUMPAD_ENTER', 'PENT')),
+ (89, ('KP_1', 'P1', 'NUMPAD_1')),
+ (90, ('KP_2', 'P2', 'NUMPAD_2')),
+ (91, ('KP_3', 'P3', 'NUMPAD_3')),
+ (92, ('KP_4', 'P4', 'NUMPAD_4')),
+ (93, ('KP_5', 'P5', 'NUMPAD_5')),
+ (94, ('KP_6', 'P6', 'NUMPAD_6')),
+ (95, ('KP_7', 'P7', 'NUMPAD_7')),
+ (96, ('KP_8', 'P8', 'NUMPAD_8')),
+ (97, ('KP_9', 'P9', 'NUMPAD_9')),
+ (98, ('KP_0', 'P0', 'NUMPAD_0')),
+ (99, ('KP_DOT', 'PDOT', 'NUMPAD_DOT')),
+ (103, ('KP_EQUAL', 'PEQL', 'NUMPAD_EQUAL')),
+ (133, ('KP_COMMA', 'PCMM', 'NUMPAD_COMMA')),
+ (134, ('KP_EQUAL_AS400', 'NUMPAD_EQUAL_AS400')),
+ )
+
+ for code, names in codes:
+ if candidate in names:
+ return make_key(names=names, constructor=KeyboardKey, code=code)
+
+
+def maybe_make_shifted_key(candidate: str) -> Optional[Key]:
+ codes = (
+ ('1', ('EXCLAIM', 'EXLM', '!')),
+ ('2', ('AT', '@')),
+ ('3', ('HASH', 'POUND', '#')),
+ ('4', ('DOLLAR', 'DLR', '$')),
+ ('5', ('PERCENT', 'PERC', '%')),
+ ('6', ('CIRCUMFLEX', 'CIRC', '^')),
+ ('7', ('AMPERSAND', 'AMPR', '&')),
+ ('8', ('ASTERISK', 'ASTR', '*')),
+ ('9', ('LEFT_PAREN', 'LPRN', '(')),
+ ('0', ('RIGHT_PAREN', 'RPRN', ')')),
+ ('-', ('UNDERSCORE', 'UNDS', '_')),
+ ('=', ('PLUS', '+')),
+ ('[', ('LEFT_CURLY_BRACE', 'LCBR', '{')),
+ (']', ('RIGHT_CURLY_BRACE', 'RCBR', '}')),
+ ('\\', ('PIPE', '|')),
+ (';', ('COLON', 'COLN', ':')),
+ ("'", ('DOUBLE_QUOTE', 'DQUO', 'DQT', '"')),
+ ('`', ('TILDE', 'TILD', '~')),
+ (',', ('LEFT_ANGLE_BRACKET', 'LABK', '<')),
+ ('.', ('RIGHT_ANGLE_BRACKET', 'RABK', '>')),
+ ('/', ('QUESTION', 'QUES', '?')),
+ )
+
+ for unshifted, names in codes:
+ if candidate in names:
+ return make_key(
+ names=names,
+ constructor=ModifiedKey,
+ code=KC[unshifted],
+ modifier=KC.LSFT,
+ )
+
+
+def maybe_make_firmware_key(candidate: str) -> Optional[Key]:
+ keys = (
+ ((('BLE_REFRESH',), handlers.ble_refresh)),
+ ((('BLE_DISCONNECT',), handlers.ble_disconnect)),
+ ((('BOOTLOADER',), handlers.bootloader)),
+ ((('HID_SWITCH', 'HID'), handlers.hid_switch)),
+ ((('RELOAD', 'RLD'), handlers.reload)),
+ ((('RESET',), handlers.reset)),
+ ((('ANY',), handlers.any_pressed)),
+ )
+
+ for names, handler in keys:
+ if candidate in names:
+ return make_key(names=names, on_press=handler)
+
+
+KEY_GENERATORS = (
+ maybe_make_no_key,
+ maybe_make_alpha_key,
+ maybe_make_numeric_key,
+ maybe_make_firmware_key,
+ maybe_make_key(
+ ('BKDL',),
+ on_press=handlers.bkdl_pressed,
+ on_release=handlers.bkdl_released,
+ ),
+ maybe_make_key(
+ ('GESC', 'GRAVE_ESC'),
+ on_press=handlers.gesc_pressed,
+ on_release=handlers.gesc_released,
+ ),
+ maybe_make_mod_key,
+ # More ASCII standard keys
+ maybe_make_more_ascii,
+ # Function Keys
+ maybe_make_fn_key,
+ # Lock Keys, Navigation, etc.
+ maybe_make_navlock_key,
+ # Numpad
+ # FIXME: Investigate whether this key actually works, and
+ # uncomment when/if it does.
+ # maybe_make_key(131, ('LOCKING_NUM', 'LNUM')),
+ maybe_make_numpad_key,
+ # Making life better for folks on tiny keyboards especially: exposes
+ # the 'shifted' keys as raw keys. Under the hood we're still
+ # sending Shift+(whatever key is normally pressed) to get these, so
+ # for example `KC_AT` will hold shift and press 2.
+ maybe_make_shifted_key,
+)
+
+
+class KeyAttrDict:
+ # Instead of relying on the uncontrollable availability of a big chunk of
+ # contiguous memory for key caching, we can manually fragment the cache into
+ # reasonably small partitions. The partition size is chosen from the magic
+ # values of CPs hash allocation sizes.
+ # (https://github.com/adafruit/circuitpython/blob/main/py/map.c, 2023-02)
+ __partition_size = 37
+ __cache = [{}]
+
+ def __iter__(self):
+ for partition in self.__cache:
+ for name in partition:
+ yield name
+
+ def __setitem__(self, name: str, key: Key):
+ # Overwrite existing reference.
+ for partition in self.__cache:
+ if name in partition:
+ partition[name] = key
+ return key
+
+ # Insert new reference.
+ if len(self.__cache[-1]) >= self.__partition_size:
+ self.__cache.append({})
+ self.__cache[-1][name] = key
+ return key
+
+ def __getattr__(self, name: str):
+ return self.__getitem__(name)
+
+ def get(self, name: str, default: Optional[Key] = None):
+ try:
+ return self.__getitem__(name)
+ except Exception:
+ return default
+
+ def clear(self):
+ self.__cache.clear()
+ self.__cache.append({})
+
+ def __getitem__(self, name: str):
+ for partition in self.__cache:
+ if name in partition:
+ return partition[name]
+
+ for func in KEY_GENERATORS:
+ maybe_key = func(name)
+ if maybe_key:
+ break
+
+ if not maybe_key:
+ if debug.enabled:
+ debug('Invalid key: ', name)
+ return KC.NO
+
+ return maybe_key
+
+
+# Global state, will be filled in throughout this file, and
+# anywhere the user creates custom keys
+KC = KeyAttrDict()
+
+
+class Key:
+ '''Generic Key class with assignable handlers.'''
+
+ def __init__(
+ self,
+ on_press: Callable[[object, Key, Keyboard, ...], None] = handlers.passthrough,
+ on_release: Callable[[object, Key, Keyboard, ...], None] = handlers.passthrough,
+ ):
+ self._on_press = on_press
+ self._on_release = on_release
+
+ def __repr__(self):
+ return self.__class__.__name__
+
+ def on_press(self, keyboard: Keyboard, coord_int: Optional[int] = None) -> None:
+ self._on_press(self, keyboard, KC, coord_int)
+
+ def on_release(self, keyboard: Keyboard, coord_int: Optional[int] = None) -> None:
+ self._on_release(self, keyboard, KC, coord_int)
+
+
+class _DefaultKey(Key):
+ '''Meta class implementing handlers for Keys with HID codes.'''
+
+ def __init__(self, code: Optional[int] = None):
+ self.code = code
+
+ def __repr__(self):
+ return super().__repr__() + '(code=' + str(self.code) + ')'
+
+ def on_press(self, keyboard: Keyboard, coord_int: Optional[int] = None) -> None:
+ if keyboard.implicit_modifier is not None:
+ keyboard.keys_pressed.discard(keyboard.implicit_modifier)
+ keyboard.implicit_modifier = None
+ if self in keyboard.keys_pressed:
+ keyboard.keys_pressed.discard(self)
+ keyboard.hid_pending = True
+ keyboard._send_hid()
+ keyboard.keys_pressed.add(self)
+ keyboard.hid_pending = True
+
+ def on_release(self, keyboard: Keyboard, coord_int: Optional[int] = None) -> None:
+ keyboard.keys_pressed.discard(self)
+ keyboard.hid_pending = True
+
+
+class KeyboardKey(_DefaultKey):
+ pass
+
+
+class ModifierKey(_DefaultKey):
+ def __call__(self, key: Key) -> Key:
+ # don't duplicate when applying the same modifier twice
+ if (
+ isinstance(key, ModifiedKey)
+ and key.modifier.code & self.code == key.modifier.code
+ ):
+ return key
+ elif isinstance(key, ModifierKey) and key.code & self.code == key.code:
+ return key
+
+ return ModifiedKey(key, self)
+
+
+class ModifiedKey(Key):
+ def __init__(self, code: [Key, int], modifier: [ModifierKey]):
+ # generate from code by maybe_make_shifted_key
+ if isinstance(code, int):
+ key = KeyboardKey(code=code)
+ else:
+ key = code
+
+ # stack modifier keys
+ if isinstance(key, ModifierKey):
+ modifier = ModifierKey(key.code | modifier.code)
+ key = None
+ # stack modified keys
+ elif isinstance(key, ModifiedKey):
+ modifier = ModifierKey(key.modifier.code | modifier.code)
+ key = key.key
+ # clone modifier so it doesn't override explicit mods
+ else:
+ modifier = ModifierKey(modifier.code)
+
+ self.key = key
+ self.modifier = modifier
+
+ def on_press(self, keyboard: Keyboard, coord_int: Optional[int] = None) -> None:
+ if self.key in keyboard.keys_pressed:
+ self.key.on_release(keyboard, coord_int)
+ keyboard._send_hid()
+ keyboard.keys_pressed.add(self.modifier)
+ if self.key is not None:
+ self.key.on_press(keyboard, coord_int)
+ if keyboard.implicit_modifier is not None:
+ keyboard.keys_pressed.discard(keyboard.implicit_modifier)
+ keyboard.implicit_modifier = self.modifier
+ keyboard.hid_pending = True
+
+ def on_release(self, keyboard: Keyboard, coord_int: Optional[int] = None) -> None:
+ keyboard.keys_pressed.discard(self.modifier)
+ if self.key is not None:
+ self.key.on_release(keyboard, coord_int)
+ if keyboard.implicit_modifier == self.modifier:
+ keyboard.implicit_modifier = None
+ keyboard.hid_pending = True
+
+ def __repr__(self):
+ return (
+ super().__repr__()
+ + '(key='
+ + str(self.key)
+ + ', modifier='
+ + str(self.modifier)
+ + ')'
+ )
+
+
+class ConsumerKey(_DefaultKey):
+ pass
+
+
+class MouseKey(_DefaultKey):
+ pass
+
+
+class SpacemouseKey(_DefaultKey):
+ pass
+
+
+def make_key(
+ names: Tuple[str, ...],
+ constructor: Key = Key,
+ **kwargs,
+) -> Key:
+ '''
+ Create a new key, aliased by `names` in the KC lookup table.
+
+ Names are globally unique. If a later key is created with
+ the same name as an existing entry in `KC`, it will overwrite
+ the existing entry.
+
+ Names are case sensitive.
+
+ All **kwargs are passed to the Key constructor
+ '''
+
+ key = constructor(**kwargs)
+
+ for name in names:
+ KC[name] = key
+
+ return key
+
+
+# Argumented keys are implicitly internal, so auto-gen of code
+# is almost certainly the best plan here
+def make_argumented_key(
+ names: Tuple[str, ...],
+ constructor: [Key, Callable[[...], Key]],
+ **_kwargs,
+) -> Key:
+
+ def argumented_key(*args, **kwargs) -> Key:
+ # This is a very ugly workaround for missing syntax in mpy-cross 8.x
+ # and, once EOL, can be replaced by:
+ # return constructor(*args, **_kwargs, **kwargs)
+ k = _kwargs.copy()
+ k.update(**kwargs)
+ return constructor(*args, **k)
+
+ for name in names:
+ KC[name] = argumented_key
+
+ return argumented_key
diff --git a/hackpads/blipyboard/firmware/kmk/kmk_keyboard.py b/hackpads/blipyboard/firmware/kmk/kmk_keyboard.py
new file mode 100644
index 0000000000..bc61d8bd14
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/kmk_keyboard.py
@@ -0,0 +1,528 @@
+try:
+ from typing import Callable, Optional
+except ImportError:
+ pass
+
+from collections import namedtuple
+from keypad import Event as KeyEvent
+
+from kmk.hid import BLEHID, USBHID, AbstractHID, HIDModes
+from kmk.keys import KC, Axis, Key
+from kmk.modules import Module
+from kmk.scanners.keypad import MatrixScanner
+from kmk.scheduler import Task, cancel_task, create_task, get_due_task
+from kmk.utils import Debug
+
+debug = Debug('kmk.keyboard')
+
+KeyBufferFrame = namedtuple(
+ 'KeyBufferFrame', ('key', 'is_pressed', 'int_coord', 'index')
+)
+
+
+def debug_error(module, message: str, error: Exception):
+ if debug.enabled:
+ debug(
+ message, ': ', error.__class__.__name__, ': ', error, name=module.__module__
+ )
+
+
+class Sandbox:
+ matrix_update = None
+ secondary_matrix_update = None
+ active_layers = None
+
+
+class KMKKeyboard:
+ def __init__(self) -> None:
+ #####
+ # User-configurable
+ self.keymap = []
+ self.coord_mapping = None
+
+ self.row_pins = None
+ self.col_pins = None
+ self.diode_orientation = None
+ self.matrix = None
+
+ self.modules = []
+ self.extensions = []
+ self.sandbox = Sandbox()
+
+ #####
+ # Internal State
+ self.keys_pressed = set()
+ self._coordkeys_pressed = {}
+ self.implicit_modifier = None
+ self.hid_type = HIDModes.USB
+ self.secondary_hid_type = None
+ self._hid_helper = None
+ self._hid_send_enabled = False
+ self.hid_pending = False
+ self.matrix_update = None
+ self.secondary_matrix_update = None
+ self.matrix_update_queue = []
+ self._trigger_powersave_enable = False
+ self._trigger_powersave_disable = False
+ self._go_args = None
+ self._resume_buffer = []
+ self._resume_buffer_x = []
+
+ # this should almost always be PREpended to, replaces
+ # former use of reversed_active_layers which had pointless
+ # overhead (the underlying list was never used anyway)
+ self.active_layers = [0]
+
+ def __repr__(self) -> str:
+ return self.__class__.__name__
+
+ def _send_hid(self) -> None:
+ if not self._hid_send_enabled:
+ return
+
+ if debug.enabled:
+ if self.keys_pressed:
+ debug('keys_pressed=', self.keys_pressed)
+
+ self._hid_helper.create_report(self.keys_pressed)
+ try:
+ self._hid_helper.send()
+ except Exception as err:
+ debug_error(self._hid_helper, 'send', err)
+
+ self.hid_pending = False
+
+ for key in self.keys_pressed:
+ if isinstance(key, Axis):
+ key.move(self, 0)
+
+ def _handle_matrix_report(self, kevent: KeyEvent) -> None:
+ if kevent is not None:
+ self._on_matrix_changed(kevent)
+
+ def _find_key_in_map(self, int_coord: int) -> Key:
+ try:
+ idx = self.coord_mapping.index(int_coord)
+ except ValueError:
+ if debug.enabled:
+ debug('no such int_coord: ', int_coord)
+ return None
+
+ key = None
+ for layer in self.active_layers:
+ try:
+ key = self.keymap[layer][idx]
+ except IndexError:
+ if debug.enabled:
+ debug('keymap IndexError: idx=', idx, ' layer=', layer)
+
+ if key and key != KC.TRNS:
+ break
+
+ return key
+
+ def _on_matrix_changed(self, kevent: KeyEvent) -> None:
+ int_coord = kevent.key_number
+ is_pressed = kevent.pressed
+ key = None
+
+ if not is_pressed:
+ key = self._coordkeys_pressed.pop(int_coord, None)
+
+ if key is None:
+ key = self._find_key_in_map(int_coord)
+
+ if key is None:
+ return
+
+ if debug.enabled:
+ debug(kevent, ': ', key)
+
+ self.pre_process_key(key, is_pressed, int_coord)
+
+ def _process_resume_buffer(self):
+ '''
+ Resume the processing of buffered, delayed, deferred, etc. key events
+ emitted by modules.
+
+ We use a copy of the `_resume_buffer` as a working buffer. The working
+ buffer holds all key events in the correct order for processing. If
+ during processing new events are pushed to the `_resume_buffer`, they
+ are prepended to the working buffer (which may not be emptied), in
+ order to preserve key event order.
+ We also double-buffer `_resume_buffer` with `_resume_buffer_x`, only
+ copying the reference to hopefully safe some time on allocations.
+ '''
+
+ buffer, self._resume_buffer = self._resume_buffer, self._resume_buffer_x
+
+ while buffer:
+ ksf = buffer.pop(0)
+ key = ksf.key
+
+ # Handle any unaccounted-for layer shifts by looking up the key resolution again.
+ if ksf.int_coord is not None:
+ if ksf.is_pressed:
+ key = self._find_key_in_map(ksf.int_coord)
+ else:
+ key = self._coordkeys_pressed.pop(ksf.int_coord, key)
+
+ # Resume the processing of the key event and update the HID report
+ # when applicable.
+ self.pre_process_key(key, ksf.is_pressed, ksf.int_coord, ksf.index)
+
+ if self.hid_pending:
+ self._send_hid()
+ self.hid_pending = False
+
+ # Any newly buffered key events must be prepended to the working
+ # buffer.
+ if self._resume_buffer:
+ self._resume_buffer.extend(buffer)
+ buffer.clear()
+ buffer, self._resume_buffer = self._resume_buffer, buffer
+
+ self._resume_buffer_x = buffer
+
+ def pre_process_key(
+ self,
+ key: Key,
+ is_pressed: bool,
+ int_coord: Optional[int] = None,
+ index: int = 0,
+ ) -> None:
+ for module in self.modules[index:]:
+ try:
+ key = module.process_key(self, key, is_pressed, int_coord)
+ if key is None:
+ break
+ except Exception as err:
+ debug_error(module, 'process_key', err)
+
+ if int_coord is not None:
+ if is_pressed:
+ self._coordkeys_pressed[int_coord] = key
+
+ if debug.enabled:
+ debug('coordkeys_pressed=', self._coordkeys_pressed)
+
+ if key:
+ self.process_key(key, is_pressed, int_coord)
+
+ def process_key(
+ self, key: Key, is_pressed: bool, int_coord: Optional[int] = None
+ ) -> None:
+ if is_pressed:
+ key.on_press(self, int_coord)
+ else:
+ key.on_release(self, int_coord)
+
+ def resume_process_key(
+ self,
+ module: Module,
+ key: Key,
+ is_pressed: bool,
+ int_coord: Optional[int] = None,
+ reprocess: Optional[bool] = False,
+ ) -> None:
+ index = self.modules.index(module) + (0 if reprocess else 1)
+ ksf = KeyBufferFrame(
+ key=key, is_pressed=is_pressed, int_coord=int_coord, index=index
+ )
+ self._resume_buffer.append(ksf)
+
+ def remove_key(self, keycode: Key) -> None:
+ self.process_key(keycode, False)
+
+ def add_key(self, keycode: Key) -> None:
+ self.process_key(keycode, True)
+
+ def tap_key(self, keycode: Key) -> None:
+ self.add_key(keycode)
+ # On the next cycle, we'll remove the key.
+ self.set_timeout(0, lambda: self.remove_key(keycode))
+
+ def set_timeout(self, after_ticks: int, callback: Callable[[None], None]) -> [Task]:
+ return create_task(callback, after_ms=after_ticks)
+
+ def cancel_timeout(self, timeout_key: int) -> None:
+ cancel_task(timeout_key)
+
+ def _process_timeouts(self) -> None:
+ for task in get_due_task():
+ task()
+
+ def _init_coord_mapping(self) -> None:
+ '''
+ Attempt to sanely guess a coord_mapping if one is not provided. No-op
+ if `kmk.extensions.split.Split` is used, it provides equivalent
+ functionality in `on_bootup`
+
+ To save RAM on boards that don't use Split, we don't import Split
+ and do an isinstance check, but instead do string detection
+ '''
+ if any(x.__class__.__module__ == 'kmk.modules.split' for x in self.modules):
+ return
+
+ if not self.coord_mapping:
+ cm = []
+ for m in self.matrix:
+ cm.extend(m.coord_mapping)
+ self.coord_mapping = tuple(cm)
+
+ def _init_hid(self) -> None:
+ if self.hid_type == HIDModes.NOOP:
+ self._hid_helper = AbstractHID
+ elif self.hid_type == HIDModes.USB:
+ self._hid_helper = USBHID
+ elif self.hid_type == HIDModes.BLE:
+ self._hid_helper = BLEHID
+ else:
+ self._hid_helper = AbstractHID
+ self._hid_helper = self._hid_helper(**self._go_args)
+ self._hid_send_enabled = True
+
+ if debug.enabled:
+ debug('hid=', self._hid_helper)
+
+ def _deinit_hid(self) -> None:
+ try:
+ self._hid_helper.create_report({})
+ self._hid_helper.send()
+ except Exception as e:
+ debug_error(self, '_deinit_hid', e)
+
+ def _init_matrix(self) -> None:
+ if self.matrix is None:
+ self.matrix = MatrixScanner(
+ column_pins=self.col_pins,
+ row_pins=self.row_pins,
+ columns_to_anodes=self.diode_orientation,
+ )
+
+ try:
+ self.matrix = tuple(iter(self.matrix))
+ offset = 0
+ for matrix in self.matrix:
+ matrix.offset = offset
+ offset += matrix.key_count
+ except TypeError:
+ self.matrix = (self.matrix,)
+
+ if debug.enabled:
+ debug('matrix=', [_.__class__.__name__ for _ in self.matrix])
+
+ def during_bootup(self) -> None:
+ # Modules and extensions that fail `during_bootup` get removed from
+ # their respective lists. This serves as a self-check mechanism; any
+ # modules or extensions that initialize peripherals or data structures
+ # should do that in `during_bootup`.
+ for idx, module in enumerate(self.modules):
+ try:
+ module.during_bootup(self)
+ except Exception as err:
+ debug_error(module, 'during_bootup', err)
+ self.modules[idx] = None
+
+ self.modules[:] = [_ for _ in self.modules if _]
+
+ if debug.enabled:
+ debug('modules=', [_.__class__.__name__ for _ in self.modules])
+
+ for idx, ext in enumerate(self.extensions):
+ try:
+ ext.during_bootup(self)
+ except Exception as err:
+ debug_error(ext, 'during_bootup', err)
+ self.extensions[idx] = None
+
+ self.extensions[:] = [_ for _ in self.extensions if _]
+
+ if debug.enabled:
+ debug('extensions=', [_.__class__.__name__ for _ in self.extensions])
+
+ def before_matrix_scan(self) -> None:
+ for module in self.modules:
+ try:
+ module.before_matrix_scan(self)
+ except Exception as err:
+ debug_error(module, 'before_matrix_scan', err)
+
+ for ext in self.extensions:
+ try:
+ ext.before_matrix_scan(self.sandbox)
+ except Exception as err:
+ debug_error(ext, 'before_matrix_scan', err)
+
+ def after_matrix_scan(self) -> None:
+ for module in self.modules:
+ try:
+ module.after_matrix_scan(self)
+ except Exception as err:
+ debug_error(module, 'after_matrix_scan', err)
+
+ for ext in self.extensions:
+ try:
+ ext.after_matrix_scan(self.sandbox)
+ except Exception as err:
+ debug_error(ext, 'after_matrix_scan', err)
+
+ def before_hid_send(self) -> None:
+ for module in self.modules:
+ try:
+ module.before_hid_send(self)
+ except Exception as err:
+ debug_error(module, 'before_hid_send', err)
+
+ for ext in self.extensions:
+ try:
+ ext.before_hid_send(self.sandbox)
+ except Exception as err:
+ debug_error(ext, 'before_hid_send', err)
+
+ def after_hid_send(self) -> None:
+ for module in self.modules:
+ try:
+ module.after_hid_send(self)
+ except Exception as err:
+ debug_error(module, 'after_hid_send', err)
+
+ for ext in self.extensions:
+ try:
+ ext.after_hid_send(self.sandbox)
+ except Exception as err:
+ debug_error(ext, 'after_hid_send', err)
+
+ def powersave_enable(self) -> None:
+ for module in self.modules:
+ try:
+ module.on_powersave_enable(self)
+ except Exception as err:
+ debug_error(module, 'powersave_enable', err)
+
+ for ext in self.extensions:
+ try:
+ ext.on_powersave_enable(self.sandbox)
+ except Exception as err:
+ debug_error(ext, 'powersave_enable', err)
+
+ def powersave_disable(self) -> None:
+ for module in self.modules:
+ try:
+ module.on_powersave_disable(self)
+ except Exception as err:
+ debug_error(module, 'powersave_disable', err)
+
+ for ext in self.extensions:
+ try:
+ ext.on_powersave_disable(self.sandbox)
+ except Exception as err:
+ debug_error(ext, 'powersave_disable', err)
+
+ def deinit(self) -> None:
+ for module in self.modules:
+ try:
+ module.deinit(self)
+ except Exception as err:
+ debug_error(module, 'deinit', err)
+
+ for ext in self.extensions:
+ try:
+ ext.deinit(self.sandbox)
+ except Exception as err:
+ debug_error(ext, 'deinit', err)
+
+ def go(self, hid_type=HIDModes.USB, secondary_hid_type=None, **kwargs) -> None:
+ try:
+ self._init(
+ hid_type=hid_type,
+ secondary_hid_type=secondary_hid_type,
+ **kwargs,
+ )
+ while True:
+ self._main_loop()
+ except Exception as err:
+ import traceback
+
+ traceback.print_exception(err)
+ finally:
+ debug('cleaning up...')
+ self._deinit_hid()
+ self.deinit()
+ debug('...done')
+
+ if not debug.enabled:
+ import supervisor
+
+ supervisor.reload()
+
+ def _init(
+ self,
+ hid_type: HIDModes = HIDModes.USB,
+ secondary_hid_type: Optional[HIDModes] = None,
+ **kwargs,
+ ) -> None:
+ self._go_args = kwargs
+ self.hid_type = hid_type
+ self.secondary_hid_type = secondary_hid_type
+
+ if debug.enabled:
+ debug('Initialising ', self)
+
+ self._init_hid()
+ self._init_matrix()
+ self._init_coord_mapping()
+ self.during_bootup()
+
+ if debug.enabled:
+ import gc
+
+ gc.collect()
+ debug('mem_info used:', gc.mem_alloc(), ' free:', gc.mem_free())
+
+ def _main_loop(self) -> None:
+ self.sandbox.active_layers = self.active_layers.copy()
+
+ self.before_matrix_scan()
+
+ self._process_resume_buffer()
+
+ for matrix in self.matrix:
+ update = matrix.scan_for_changes()
+ if update:
+ self.matrix_update = update
+ break
+ self.sandbox.matrix_update = self.matrix_update
+ self.sandbox.secondary_matrix_update = self.secondary_matrix_update
+
+ self.after_matrix_scan()
+
+ if self.secondary_matrix_update:
+ self.matrix_update_queue.append(self.secondary_matrix_update)
+ self.secondary_matrix_update = None
+
+ if self.matrix_update:
+ self.matrix_update_queue.append(self.matrix_update)
+ self.matrix_update = None
+
+ # only handle one key per cycle.
+ if self.matrix_update_queue:
+ self._handle_matrix_report(self.matrix_update_queue.pop(0))
+
+ self.before_hid_send()
+
+ if self.hid_pending:
+ self._send_hid()
+
+ self._process_timeouts()
+
+ if self.hid_pending:
+ self._send_hid()
+
+ self.after_hid_send()
+
+ if self._trigger_powersave_enable:
+ self.powersave_enable()
+
+ if self._trigger_powersave_disable:
+ self.powersave_disable()
diff --git a/hackpads/blipyboard/firmware/kmk/kmktime.py b/hackpads/blipyboard/firmware/kmk/kmktime.py
new file mode 100644
index 0000000000..7476c43cd4
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/kmktime.py
@@ -0,0 +1,34 @@
+from micropython import const
+from supervisor import ticks_ms
+
+_TICKS_PERIOD = const(1 << 29)
+_TICKS_MAX = const(_TICKS_PERIOD - 1)
+_TICKS_HALFPERIOD = const(_TICKS_PERIOD // 2)
+
+
+def ticks_diff(new: int, start: int) -> int:
+ diff = (new - start) & _TICKS_MAX
+ diff = ((diff + _TICKS_HALFPERIOD) & _TICKS_MAX) - _TICKS_HALFPERIOD
+ return diff
+
+
+def ticks_add(ticks: int, delta: int) -> int:
+ return (ticks + delta) % _TICKS_PERIOD
+
+
+def check_deadline(new: int, start: int, ms: int) -> int:
+ return ticks_diff(new, start) < ms
+
+
+class PeriodicTimer:
+ def __init__(self, period: int):
+ self.period = period
+ self.last_tick = ticks_ms()
+
+ def tick(self) -> bool:
+ now = ticks_ms()
+ if ticks_diff(now, self.last_tick) >= self.period:
+ self.last_tick = now
+ return True
+ else:
+ return False
diff --git a/hackpads/blipyboard/firmware/kmk/modules/__init__.py b/hackpads/blipyboard/firmware/kmk/modules/__init__.py
new file mode 100644
index 0000000000..dd587c35fc
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/__init__.py
@@ -0,0 +1,46 @@
+class InvalidExtensionEnvironment(Exception):
+ pass
+
+
+class Module:
+ '''
+ Modules differ from extensions in that they not only can read the state, but
+ are allowed to modify the state. The will be loaded on boot, and are not
+ allowed to be unloaded as they are required to continue functioning in a
+ consistant manner.
+ '''
+
+ # The below methods should be implemented by subclasses
+
+ def during_bootup(self, keyboard):
+ raise NotImplementedError
+
+ def before_matrix_scan(self, keyboard):
+ '''
+ Return value will be injected as an extra matrix update
+ '''
+ raise NotImplementedError
+
+ def after_matrix_scan(self, keyboard):
+ '''
+ Return value will be replace matrix update if supplied
+ '''
+ raise NotImplementedError
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ return key
+
+ def before_hid_send(self, keyboard):
+ raise NotImplementedError
+
+ def after_hid_send(self, keyboard):
+ raise NotImplementedError
+
+ def on_powersave_enable(self, keyboard):
+ raise NotImplementedError
+
+ def on_powersave_disable(self, keyboard):
+ raise NotImplementedError
+
+ def deinit(self, keyboard):
+ pass
diff --git a/hackpads/blipyboard/firmware/kmk/modules/adns9800.py b/hackpads/blipyboard/firmware/kmk/modules/adns9800.py
new file mode 100644
index 0000000000..6b0302332a
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/adns9800.py
@@ -0,0 +1,230 @@
+import busio
+import digitalio
+import microcontroller
+
+import time
+
+from kmk.keys import AX
+from kmk.modules import Module
+from kmk.modules.adns9800_firmware import firmware
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class REG:
+ Product_ID = 0x0
+ Revision_ID = 0x1
+ MOTION = 0x2
+ DELTA_X_L = 0x3
+ DELTA_X_H = 0x4
+ DELTA_Y_L = 0x5
+ DELTA_Y_H = 0x6
+ SQUAL = 0x7
+ PIXEL_SUM = 0x8
+ Maximum_Pixel = 0x9
+ Minimum_Pixel = 0xA
+ Shutter_Lower = 0xB
+ Shutter_Upper = 0xC
+ Frame_Period_Lower = 0xD
+ Frame_Period_Upper = 0xE
+ Configuration_I = 0xF
+ Configuration_II = 0x10
+ Frame_Capture = 0x12
+ SROM_Enable = 0x13
+ Run_Downshift = 0x14
+ Rest1_Rate = 0x15
+ Rest1_Downshift = 0x16
+ Rest2_Rate = 0x17
+ Rest2_Downshift = 0x18
+ Rest3_Rate = 0x19
+ Frame_Period_Max_Bound_Lower = 0x1A
+ Frame_Period_Max_Bound_Upper = 0x1B
+ Frame_Period_Min_Bound_Lower = 0x1C
+ Frame_Period_Min_Bound_Upper = 0x1D
+ Shutter_Max_Bound_Lower = 0x1E
+ Shutter_Max_Bound_Upper = 0x1F
+ LASER_CTRL0 = 0x20
+ Observation = 0x24
+ Data_Out_Lower = 0x25
+ Data_Out_Upper = 0x26
+ SROM_ID = 0x2A
+ Lift_Detection_Thr = 0x2E
+ Configuration_V = 0x2F
+ Configuration_IV = 0x39
+ Power_Up_Reset = 0x3A
+ Shutdown = 0x3B
+ Inverse_Product_ID = 0x3F
+ Snap_Angle = 0x42
+ Motion_Burst = 0x50
+ SROM_Load_Burst = 0x62
+ Pixel_Burst = 0x64
+
+
+class ADNS9800(Module):
+ tswr = tsww = 120
+ tsrw = tsrr = 20
+ tsrad = 100
+ tbexit = 1
+ baud = 2000000
+ cpol = 1
+ cpha = 1
+ DIR_WRITE = 0x80
+ DIR_READ = 0x7F
+
+ def __init__(self, cs, sclk, miso, mosi, invert_x=False, invert_y=False):
+ self.cs = digitalio.DigitalInOut(cs)
+ self.cs.direction = digitalio.Direction.OUTPUT
+ self.spi = busio.SPI(clock=sclk, MOSI=mosi, MISO=miso)
+ self.invert_x = invert_x
+ self.invert_y = invert_y
+
+ def adns_start(self):
+ self.cs.value = False
+
+ def adns_stop(self):
+ self.cs.value = True
+
+ def adns_write(self, reg, data):
+ while not self.spi.try_lock():
+ pass
+ try:
+ self.spi.configure(baudrate=self.baud, polarity=self.cpol, phase=self.cpha)
+ self.adns_start()
+ self.spi.write(bytes([reg | self.DIR_WRITE, data]))
+ finally:
+ self.spi.unlock()
+ self.adns_stop()
+
+ def adns_read(self, reg):
+ result = bytearray(1)
+ while not self.spi.try_lock():
+ pass
+ try:
+ self.spi.configure(baudrate=self.baud, polarity=self.cpol, phase=self.cpha)
+ self.adns_start()
+ self.spi.write(bytes([reg & self.DIR_READ]))
+ microcontroller.delay_us(self.tsrad)
+ self.spi.readinto(result)
+ finally:
+ self.spi.unlock()
+ self.adns_stop()
+
+ return result[0]
+
+ def adns_upload_srom(self):
+ while not self.spi.try_lock():
+ pass
+ try:
+ self.spi.configure(baudrate=self.baud, polarity=self.cpol, phase=self.cpha)
+ self.adns_start()
+ self.spi.write(bytes([REG.SROM_Load_Burst | self.DIR_WRITE]))
+ for b in firmware:
+ self.spi.write(bytes([b]))
+ finally:
+ self.spi.unlock()
+ self.adns_stop()
+
+ def delta_to_int(self, high, low):
+ comp = (high << 8) | low
+ if comp & 0x8000:
+ return (-1) * (0xFFFF + 1 - comp)
+ return comp
+
+ def adns_read_motion(self):
+ result = bytearray(14)
+ while not self.spi.try_lock():
+ pass
+ try:
+ self.spi.configure(baudrate=self.baud, polarity=self.cpol, phase=self.cpha)
+ self.adns_start()
+ self.spi.write(bytes([REG.Motion_Burst & self.DIR_READ]))
+ microcontroller.delay_us(self.tsrad)
+ self.spi.readinto(result)
+ finally:
+ self.spi.unlock()
+ self.adns_stop()
+ microcontroller.delay_us(self.tbexit)
+ self.adns_write(REG.MOTION, 0x0)
+ return result
+
+ def during_bootup(self, keyboard):
+
+ self.adns_write(REG.Power_Up_Reset, 0x5A)
+ time.sleep(0.1)
+ self.adns_read(REG.MOTION)
+ microcontroller.delay_us(self.tsrr)
+ self.adns_read(REG.DELTA_X_L)
+ microcontroller.delay_us(self.tsrr)
+ self.adns_read(REG.DELTA_X_H)
+ microcontroller.delay_us(self.tsrr)
+ self.adns_read(REG.DELTA_Y_L)
+ microcontroller.delay_us(self.tsrr)
+ self.adns_read(REG.DELTA_Y_H)
+ microcontroller.delay_us(self.tsrw)
+
+ self.adns_write(REG.Configuration_IV, 0x2)
+ microcontroller.delay_us(self.tsww)
+ self.adns_write(REG.SROM_Enable, 0x1D)
+ microcontroller.delay_us(1000)
+ self.adns_write(REG.SROM_Enable, 0x18)
+ microcontroller.delay_us(self.tsww)
+
+ self.adns_upload_srom()
+ microcontroller.delay_us(2000)
+
+ laser_ctrl0 = self.adns_read(REG.LASER_CTRL0)
+ microcontroller.delay_us(self.tsrw)
+ self.adns_write(REG.LASER_CTRL0, laser_ctrl0 & 0xF0)
+ microcontroller.delay_us(self.tsww)
+ self.adns_write(REG.Configuration_I, 0x10)
+ microcontroller.delay_us(self.tsww)
+
+ if debug.enabled:
+ debug('ADNS: Product ID ', hex(self.adns_read(REG.Product_ID)))
+ microcontroller.delay_us(self.tsrr)
+ debug('ADNS: Revision ID ', hex(self.adns_read(REG.Revision_ID)))
+ microcontroller.delay_us(self.tsrr)
+ debug('ADNS: SROM ID ', hex(self.adns_read(REG.SROM_ID)))
+ microcontroller.delay_us(self.tsrr)
+ if self.adns_read(REG.Observation) & 0x20:
+ debug('ADNS: Sensor is running SROM')
+ else:
+ debug('ADNS: Error! Sensor is not running SROM!')
+
+ return
+
+ def before_matrix_scan(self, keyboard):
+ motion = self.adns_read_motion()
+ if motion[0] & 0x80:
+ delta_x = self.delta_to_int(motion[3], motion[2])
+ delta_y = self.delta_to_int(motion[5], motion[4])
+
+ if self.invert_x:
+ delta_x *= -1
+ if self.invert_y:
+ delta_y *= -1
+
+ if delta_x:
+ AX.X.move(keyboard, delta_x)
+
+ if delta_y:
+ AX.Y.move(keyboard, delta_y)
+
+ if debug.enabled:
+ debug('Delta: ', delta_x, ' ', delta_y)
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/modules/analogin/__init__.py b/hackpads/blipyboard/firmware/kmk/modules/analogin/__init__.py
new file mode 100644
index 0000000000..3e3967ddbc
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/analogin/__init__.py
@@ -0,0 +1,133 @@
+from kmk.keys import KC
+from kmk.modules import Module
+from kmk.scheduler import create_task
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+def noop(*args):
+ pass
+
+
+class AnalogEvent:
+ def __init__(self, on_change=noop, on_stop=noop):
+ self._on_change = on_change
+ self._on_stop = on_stop
+
+ def on_change(self, event, keyboard):
+ self._on_change(self, event, keyboard)
+
+ def on_stop(self, event, keyboard):
+ self._on_stop(self, event, keyboard)
+
+
+class AnalogKey(AnalogEvent):
+ def __init__(self, key, threshold=127):
+ self.key = key
+ self.threshold = threshold
+ self.pressed = False
+
+ def on_change(self, event, keyboard):
+ if event.value >= self.threshold and not self.pressed:
+ self.pressed = True
+ keyboard.pre_process_key(self.key, True)
+
+ elif event.value < self.threshold and self.pressed:
+ self.pressed = False
+ keyboard.pre_process_key(self.key, False)
+
+ def on_stop(self, event, keyboard):
+ pass
+
+
+class AnalogInput:
+ def __init__(self, input, filter=lambda input: input.value >> 8):
+ self.input = input
+ self.value = 0
+ self.delta = 0
+ self.filter = filter
+
+ def update(self):
+ '''
+ Read a new value from an analogio compatible input, apply
+ transformation, then return either the new value if it changed or `None`
+ otherwise.
+ '''
+ value = self.filter(self.input)
+ self.delta = value - self.value
+ if self.delta != 0:
+ self.value = value
+ return value
+
+
+class AnalogInputs(Module):
+ def __init__(self, inputs, evtmap, update_interval=10):
+ self._active = {}
+ self.inputs = inputs
+ self.evtmap = evtmap
+ self.update_interval = update_interval
+
+ def during_bootup(self, keyboard):
+ self.task = create_task(
+ lambda: self.update(keyboard),
+ period_ms=self.update_interval,
+ )
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def update(self, keyboard):
+ for idx, input in enumerate(self.inputs):
+ value = input.update()
+
+ # No change in value: stop or pass
+ if value is None:
+ if idx in self._active:
+ if debug.enabled:
+ debug('on_stop', input, self._active[idx])
+ self._active[idx].on_stop(input, keyboard)
+ del self._active[idx]
+ continue
+
+ # Resolve event handler
+ if idx in self._active:
+ key = self._active[idx]
+ else:
+ key = None
+ for layer in keyboard.active_layers:
+ try:
+ key = self.evtmap[layer][idx]
+ except IndexError:
+ if debug.enabled:
+ debug('evtmap IndexError: idx=', idx, ' layer=', layer)
+ if key and key != KC.TRNS:
+ break
+
+ if key == KC.NO:
+ continue
+
+ # Forward change to event handler
+ try:
+ self._active[idx] = key
+ if debug.enabled:
+ debug('on_change', input, key, value)
+ key.on_change(input, keyboard)
+ except Exception as e:
+ if debug.enabled:
+ debug(type(e), ': ', e, ' in ', key.on_change)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/analogin/keys.py b/hackpads/blipyboard/firmware/kmk/modules/analogin/keys.py
new file mode 100644
index 0000000000..4f34dc15e3
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/analogin/keys.py
@@ -0,0 +1,20 @@
+from . import AnalogEvent
+
+
+class AnalogKey(AnalogEvent):
+ def __init__(self, key, threshold=127):
+ self.key = key
+ self.threshold = threshold
+ self.pressed = False
+
+ def on_change(self, event, keyboard):
+ if event.value >= self.threshold and not self.pressed:
+ self.pressed = True
+ keyboard.pre_process_key(self.key, True)
+
+ elif event.value < self.threshold and self.pressed:
+ self.pressed = False
+ keyboard.pre_process_key(self.key, False)
+
+ def on_stop(self, event, keyboard):
+ pass
diff --git a/hackpads/blipyboard/firmware/kmk/modules/autoshift.py b/hackpads/blipyboard/firmware/kmk/modules/autoshift.py
new file mode 100644
index 0000000000..44c0695b53
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/autoshift.py
@@ -0,0 +1,82 @@
+from kmk.keys import KC, KeyboardKey
+from kmk.modules import Module
+from kmk.scheduler import cancel_task, create_task
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class Autoshift(Module):
+ def __init__(self, tap_time=300):
+ self.tap_time = tap_time
+
+ self._active = False
+ self._task = None
+ self._key = None
+
+ def during_bootup(self, keyboard):
+ self._task = create_task(lambda: self._shift(keyboard), after_ms=-1)
+
+ def before_matrix_scan(self, keyboard):
+ pass
+
+ def after_matrix_scan(self, keyboard):
+ pass
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ # Unshift on any key event
+ if self._active:
+ self._unshift(keyboard)
+ return key
+
+ # Only shift from an unshifted state
+ if KC.LSFT in keyboard.keys_pressed:
+ return key
+
+ # Ignore rolls from tapped to hold
+ if not is_pressed and key is not self._key:
+ return key
+
+ # Only shift alpha keys, iff there's no pending potential shift
+ if (
+ is_pressed
+ and not self._key
+ and isinstance(key, KeyboardKey)
+ and KC.A.code <= key.code <= KC.Z.code
+ ):
+ create_task(self._task, after_ms=self.tap_time)
+ self._key = key
+ else:
+ cancel_task(self._task)
+ keyboard.resume_process_key(self, self._key, True)
+ if key is self._key:
+ keyboard.resume_process_key(self, self._key, False)
+ else:
+ keyboard.resume_process_key(self, key, True)
+ self._key = None
+
+ def before_hid_send(self, keyboard):
+ pass
+
+ def after_hid_send(self, keyboard):
+ pass
+
+ def on_powersave_enable(self, keyboard):
+ pass
+
+ def on_powersave_disable(self, keyboard):
+ pass
+
+ def _shift(self, keyboard):
+ if debug.enabled:
+ debug('activate')
+ self._active = True
+ keyboard.keys_pressed.add(KC.LSFT)
+ keyboard.resume_process_key(self, self._key, True)
+
+ def _unshift(self, keyboard):
+ if debug.enabled:
+ debug('deactivate')
+ self._active = False
+ self._key = None
+ keyboard.keys_pressed.remove(KC.LSFT)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/capsword.py b/hackpads/blipyboard/firmware/kmk/modules/capsword.py
new file mode 100644
index 0000000000..c1b44a030f
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/capsword.py
@@ -0,0 +1,102 @@
+from kmk.keys import KC, KeyboardKey, ModifierKey, make_key
+from kmk.modules import Module
+
+
+class CapsWord(Module):
+ # default timeout is 8000
+ # alphabets, numbers and few more keys will not disable capsword
+ def __init__(self, timeout=8000):
+ self._alphabets = range(KC.A.code, KC.Z.code + 1)
+ self._numbers = range(KC.N1.code, KC.N0.code + 1)
+ self.keys_ignored = [
+ KC.MINS,
+ KC.BSPC,
+ KC.UNDS,
+ ]
+ self._timeout_key = False
+ self._cw_active = False
+ self.timeout = timeout
+ make_key(
+ names=(
+ 'CAPSWORD',
+ 'CW',
+ ),
+ on_press=self.cw_pressed,
+ )
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ if not self._cw_active or key == KC.CW:
+ return key
+
+ continue_cw = False
+
+ # capitalize alphabets
+ if isinstance(key, KeyboardKey) and key.code in self._alphabets:
+ keyboard.process_key(KC.LSFT, is_pressed)
+ continue_cw = True
+ elif (
+ not isinstance(key, KeyboardKey)
+ or isinstance(key, ModifierKey)
+ or key.code in self._numbers
+ or key in self.keys_ignored
+ ):
+ continue_cw = True
+
+ # requests and cancels existing timeouts
+ if is_pressed:
+ if continue_cw:
+ self.discard_timeout(keyboard)
+ self.request_timeout(keyboard)
+ else:
+ self.process_timeout()
+
+ return key
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def process_timeout(self):
+ self._cw_active = False
+ self._timeout_key = False
+
+ def request_timeout(self, keyboard):
+ if self._cw_active:
+ if self.timeout:
+ self._timeout_key = keyboard.set_timeout(
+ self.timeout, lambda: self.process_timeout()
+ )
+
+ def discard_timeout(self, keyboard):
+ if self._timeout_key:
+ if self.timeout:
+ keyboard.cancel_timeout(self._timeout_key)
+ self._timeout_key = False
+
+ def cw_pressed(self, key, keyboard, *args, **kwargs):
+ # enables/disables capsword
+ if key == KC.CW:
+ if not self._cw_active:
+ self._cw_active = True
+ self.discard_timeout(keyboard)
+ self.request_timeout(keyboard)
+ else:
+ self.discard_timeout(keyboard)
+ self.process_timeout()
diff --git a/hackpads/blipyboard/firmware/kmk/modules/cg_swap.py b/hackpads/blipyboard/firmware/kmk/modules/cg_swap.py
new file mode 100644
index 0000000000..9dbfbc7786
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/cg_swap.py
@@ -0,0 +1,70 @@
+from kmk.keys import KC, ModifierKey, make_key
+from kmk.modules import Module
+
+
+class CgSwap(Module):
+ # default cg swap is disabled, can be eanbled too if needed
+ def __init__(self, cg_swap_enable=False):
+ self.cg_swap_enable = cg_swap_enable
+ self._cg_mapping = {
+ KC.LCTL: KC.LGUI,
+ KC.RCTL: KC.RGUI,
+ KC.LGUI: KC.LCTL,
+ KC.RGUI: KC.RCTL,
+ }
+ make_key(
+ names=('CG_SWAP',),
+ )
+ make_key(
+ names=('CG_NORM',),
+ )
+ make_key(
+ names=('CG_TOGG',),
+ )
+
+ def during_bootup(self, keyboard):
+ return
+
+ def matrix_detected_press(self, keyboard):
+ return keyboard.matrix_update is None
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ if is_pressed:
+ # enables or disables or toggles cg swap
+ if key == KC.CG_SWAP:
+ self.cg_swap_enable = True
+ elif key == KC.CG_NORM:
+ self.cg_swap_enable = False
+ elif key == KC.CG_TOGG:
+ if not self.cg_swap_enable:
+ self.cg_swap_enable = True
+ else:
+ self.cg_swap_enable = False
+ # performs cg swap
+ if (
+ self.cg_swap_enable
+ and key not in (KC.CG_SWAP, KC.CG_NORM, KC.CG_TOGG)
+ and isinstance(key, ModifierKey)
+ and key in self._cg_mapping
+ ):
+ key = self._cg_mapping.get(key)
+
+ return key
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/modules/combos.py b/hackpads/blipyboard/firmware/kmk/modules/combos.py
new file mode 100644
index 0000000000..be73c2ad91
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/combos.py
@@ -0,0 +1,330 @@
+try:
+ from typing import Optional, Tuple, Union
+except ImportError:
+ pass
+from micropython import const
+
+from kmk.keys import Key, make_key
+from kmk.kmk_keyboard import KMKKeyboard
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class _ComboState:
+ RESET = const(0)
+ MATCHING = const(1)
+ ACTIVE = const(2)
+ IDLE = const(3)
+
+
+class Combo:
+ fast_reset = False
+ per_key_timeout = False
+ timeout = 50
+ _remaining = []
+ _timeout = None
+ _state = _ComboState.IDLE
+ _match_coord = False
+
+ def __init__(
+ self,
+ match: Tuple[Union[Key, int], ...],
+ result: Key,
+ fast_reset=None,
+ per_key_timeout=None,
+ timeout=None,
+ match_coord=None,
+ ):
+ '''
+ match: tuple of keys (KC.A, KC.B)
+ result: key KC.C
+ '''
+ self.match = match
+ self.result = result
+ if fast_reset is not None:
+ self.fast_reset = fast_reset
+ if per_key_timeout is not None:
+ self.per_key_timeout = per_key_timeout
+ if timeout is not None:
+ self.timeout = timeout
+ if match_coord is not None:
+ self._match_coord = match_coord
+
+ def __repr__(self):
+ return f'{self.__class__.__name__}({list(self.match)})'
+
+ def matches(self, key: Key, int_coord: int):
+ raise NotImplementedError
+
+ def has_match(self, key: Key, int_coord: int):
+ return self._match_coord and int_coord in self.match or key in self.match
+
+ def insert(self, key: Key, int_coord: int):
+ if self._match_coord:
+ self._remaining.insert(0, int_coord)
+ else:
+ self._remaining.insert(0, key)
+
+ def reset(self):
+ self._remaining = list(self.match)
+
+
+class Chord(Combo):
+ def matches(self, key: Key, int_coord: int):
+ if not self._match_coord and key in self._remaining:
+ self._remaining.remove(key)
+ return True
+ elif self._match_coord and int_coord in self._remaining:
+ self._remaining.remove(int_coord)
+ return True
+ else:
+ return False
+
+
+class Sequence(Combo):
+ fast_reset = True
+ per_key_timeout = True
+ timeout = 1000
+
+ def matches(self, key: Key, int_coord: int):
+ if (
+ not self._match_coord and self._remaining and self._remaining[0] == key
+ ) or (
+ self._match_coord and self._remaining and self._remaining[0] == int_coord
+ ):
+ self._remaining.pop(0)
+ return True
+ else:
+ return False
+
+
+class Combos(Module):
+ def __init__(self, combos=[]):
+ self.combos = combos
+ self._key_buffer = []
+
+ make_key(names=('LEADER', 'LDR'))
+
+ def during_bootup(self, keyboard):
+ self.reset(keyboard)
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def process_key(self, keyboard, key: Key, is_pressed, int_coord):
+ if is_pressed:
+ return self.on_press(keyboard, key, int_coord)
+ else:
+ return self.on_release(keyboard, key, int_coord)
+
+ def on_press(self, keyboard: KMKKeyboard, key: Key, int_coord: Optional[int]):
+ # refill potential matches from timed-out matches
+ if self.count_matching() == 0:
+ for combo in self.combos:
+ if combo._state == _ComboState.RESET:
+ combo._state = _ComboState.MATCHING
+
+ # filter potential matches
+ for combo in self.combos:
+ if combo._state != _ComboState.MATCHING:
+ continue
+ if combo.matches(key, int_coord):
+ continue
+ combo._state = _ComboState.IDLE
+ if combo._timeout:
+ keyboard.cancel_timeout(combo._timeout)
+ combo._timeout = keyboard.set_timeout(
+ combo.timeout, lambda c=combo: self.reset_combo(keyboard, c)
+ )
+
+ match_count = self.count_matching()
+
+ if match_count:
+ # At least one combo matches current key: append key to buffer.
+ self._key_buffer.append((int_coord, key, True))
+ key = None
+
+ for first_match in self.combos:
+ if first_match._state == _ComboState.MATCHING:
+ break
+
+ # Single match left: don't wait on timeout to activate
+ if match_count == 1 and not any(first_match._remaining):
+ combo = first_match
+ self.activate(keyboard, combo)
+ if combo._timeout:
+ keyboard.cancel_timeout(combo._timeout)
+ combo._timeout = None
+ self._key_buffer = []
+ self.reset(keyboard)
+
+ # Start or reset individual combo timeouts.
+ for combo in self.combos:
+ if combo._state != _ComboState.MATCHING:
+ continue
+ if combo._timeout:
+ if combo.per_key_timeout:
+ keyboard.cancel_timeout(combo._timeout)
+ else:
+ continue
+ combo._timeout = keyboard.set_timeout(
+ combo.timeout, lambda c=combo: self.on_timeout(keyboard, c)
+ )
+ else:
+ # There's no matching combo: send and reset key buffer
+ if self._key_buffer:
+ self._key_buffer.append((int_coord, key, True))
+ self.send_key_buffer(keyboard)
+ self._key_buffer = []
+ key = None
+
+ return key
+
+ def on_release(self, keyboard: KMKKeyboard, key: Key, int_coord: Optional[int]):
+ for combo in self.combos:
+ if combo._state != _ComboState.ACTIVE:
+ continue
+ if combo.has_match(key, int_coord):
+ # Deactivate combo if it matches current key.
+ self.deactivate(keyboard, combo)
+
+ if combo.fast_reset:
+ self.reset_combo(keyboard, combo)
+ self._key_buffer = []
+ else:
+ combo.insert(key, int_coord)
+ combo._state = _ComboState.MATCHING
+
+ key = None
+ break
+
+ else:
+ # Non-active but matching combos can either activate on key release
+ # if they're the only match, or "un-match" the released key but stay
+ # matching if they're a repeatable combo.
+ for combo in self.combos:
+ if combo._state != _ComboState.MATCHING:
+ continue
+ if not combo.has_match(key, int_coord):
+ continue
+
+ # Combo matches, but first key released before timeout.
+ elif not any(combo._remaining) and self.count_matching() == 1:
+ keyboard.cancel_timeout(combo._timeout)
+ self.activate(keyboard, combo)
+ self._key_buffer = []
+ keyboard._send_hid()
+ self.deactivate(keyboard, combo)
+ if combo.fast_reset:
+ self.reset_combo(keyboard, combo)
+ else:
+ combo.insert(key, int_coord)
+ combo._state = _ComboState.MATCHING
+ self.reset(keyboard)
+
+ elif not any(combo._remaining):
+ continue
+
+ # Skip combos that allow tapping.
+ elif combo.fast_reset:
+ continue
+
+ # This was the last key released of a repeatable combo.
+ elif len(combo._remaining) == len(combo.match) - 1:
+ self.reset_combo(keyboard, combo)
+ if not self.count_matching():
+ self._key_buffer.append((int_coord, key, False))
+ self.send_key_buffer(keyboard)
+ self._key_buffer = []
+ key = None
+
+ # Anything between first and last key released.
+ else:
+ combo.insert(key, int_coord)
+
+ # Don't propagate key-release events for keys that have been
+ # buffered. Append release events only if corresponding press is in
+ # buffer.
+ pressed = self._key_buffer.count((int_coord, key, True))
+ released = self._key_buffer.count((int_coord, key, False))
+ if (pressed - released) > 0:
+ self._key_buffer.append((int_coord, key, False))
+ key = None
+
+ # Reset on non-combo key up
+ if not self.count_matching():
+ self.reset(keyboard)
+
+ return key
+
+ def on_timeout(self, keyboard, combo):
+ # If combo reaches timeout and has no remaining keys, activate it;
+ # else, drop it from the match list.
+ combo._timeout = None
+
+ if not any(combo._remaining):
+ self.activate(keyboard, combo)
+ # check if the last buffered key event was a 'release'
+ if not self._key_buffer[-1][2]:
+ keyboard._send_hid()
+ self.deactivate(keyboard, combo)
+ self._key_buffer = []
+ self.reset(keyboard)
+ else:
+ if self.count_matching() == 1:
+ # This was the last pending combo: flush key buffer.
+ self.send_key_buffer(keyboard)
+ self._key_buffer = []
+ self.reset_combo(keyboard, combo)
+
+ def send_key_buffer(self, keyboard):
+ for int_coord, key, is_pressed in self._key_buffer:
+ keyboard.resume_process_key(self, key, is_pressed, int_coord)
+
+ def activate(self, keyboard, combo):
+ if debug.enabled:
+ debug('activate', combo)
+ keyboard.resume_process_key(self, combo.result, True)
+ combo._state = _ComboState.ACTIVE
+
+ def deactivate(self, keyboard, combo):
+ if debug.enabled:
+ debug('deactivate', combo)
+ keyboard.resume_process_key(self, combo.result, False)
+ combo._state = _ComboState.IDLE
+
+ def reset_combo(self, keyboard, combo):
+ combo.reset()
+ if combo._timeout is not None:
+ keyboard.cancel_timeout(combo._timeout)
+ combo._timeout = None
+ combo._state = _ComboState.RESET
+
+ def reset(self, keyboard):
+ for combo in self.combos:
+ if combo._state != _ComboState.ACTIVE:
+ self.reset_combo(keyboard, combo)
+
+ def count_matching(self):
+ match_count = 0
+ for combo in self.combos:
+ if combo._state == _ComboState.MATCHING:
+ match_count += 1
+ return match_count
diff --git a/hackpads/blipyboard/firmware/kmk/modules/dynamic_sequences.py b/hackpads/blipyboard/firmware/kmk/modules/dynamic_sequences.py
new file mode 100644
index 0000000000..7d1ce5b658
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/dynamic_sequences.py
@@ -0,0 +1,261 @@
+from micropython import const
+from supervisor import ticks_ms
+
+from collections import namedtuple
+
+from kmk.keys import KC, Key, make_argumented_key
+from kmk.kmktime import check_deadline, ticks_diff
+from kmk.modules import Module
+
+
+class DynamicSequenceKey(Key):
+ def __init__(self, sequence_select=None, **kwargs):
+ super().__init__(**kwargs)
+ self.sequence_select = sequence_select
+
+
+class SequenceStatus:
+ STOPPED = const(0)
+ RECORDING = const(1)
+ PLAYING = const(2)
+ SET_REPEPITIONS = const(3)
+ SET_INTERVAL = const(4)
+
+
+# Keycodes for number keys
+_numbers = range(KC.N1.code, KC.N0.code + 1)
+
+SequenceFrame = namedtuple('SequenceFrame', ['keys_pressed', 'timestamp'])
+
+
+class Sequence:
+ def __init__(self):
+ self.repetitions = 1
+ self.interval = 0
+ self.sequence_data = [SequenceFrame(set(), 0) for i in range(3)]
+
+
+class DynamicSequences(Module):
+ def __init__(
+ self, slots=1, timeout=60000, key_interval=0, use_recorded_speed=False
+ ):
+ self.sequences = [Sequence() for i in range(slots)]
+ self.current_slot = self.sequences[0]
+ self.status = SequenceStatus.STOPPED
+
+ self.index = 0
+ self.start_time = 0
+ self.current_repetition = 0
+ self.last_config_frame = set()
+
+ self.timeout = timeout
+ self.key_interval = key_interval
+ self.use_recorded_speed = use_recorded_speed
+
+ # Create keycodes
+ make_argumented_key(
+ names=('RECORD_SEQUENCE',),
+ constructor=DynamicSequenceKey,
+ on_press=self._record_sequence,
+ )
+
+ make_argumented_key(
+ names=('PLAY_SEQUENCE',),
+ constructor=DynamicSequenceKey,
+ on_press=self._play_sequence,
+ )
+
+ make_argumented_key(
+ names=('SET_SEQUENCE', 'STOP_SEQUENCE'),
+ constructor=DynamicSequenceKey,
+ on_press=self._stop_sequence,
+ )
+
+ make_argumented_key(
+ names=('SET_SEQUENCE_REPETITIONS',),
+ constructor=DynamicSequenceKey,
+ on_press=self._set_sequence_repetitions,
+ )
+
+ make_argumented_key(
+ names=('SET_SEQUENCE_INTERVAL',),
+ constructor=DynamicSequenceKey,
+ on_press=self._set_sequence_interval,
+ )
+
+ def _record_sequence(self, key, keyboard, *args, **kwargs):
+ self._stop_sequence(key, keyboard)
+ self.status = SequenceStatus.RECORDING
+ self.start_time = ticks_ms()
+ self.current_slot.sequence_data = [SequenceFrame(set(), 0)]
+ self.index = 0
+
+ def _play_sequence(self, key, keyboard, *args, **kwargs):
+ self._stop_sequence(key, keyboard)
+ self.status = SequenceStatus.PLAYING
+ self.start_time = ticks_ms()
+ self.index = 0
+ self.current_repetition = 0
+
+ def _stop_sequence(self, key, keyboard, *args, **kwargs):
+ if self.status == SequenceStatus.RECORDING:
+ self.stop_recording()
+ elif self.status == SequenceStatus.SET_INTERVAL:
+ self.stop_config()
+ self.status = SequenceStatus.STOPPED
+
+ # Change sequences here because stop is always called
+ if key.sequence_select is not None:
+ self.current_slot = self.sequences[key.sequence_select]
+
+ # Configure repeat settings
+ def _set_sequence_repetitions(self, key, keyboard, *args, **kwargs):
+ self._stop_sequence(key, keyboard)
+ self.status = SequenceStatus.SET_REPEPITIONS
+ self.last_config_frame = set()
+ self.current_slot.repetitions = 0
+ self.start_time = ticks_ms()
+
+ def _set_sequence_interval(self, key, keyboard, *args, **kwargs):
+ self._stop_sequence(key, keyboard)
+ self.status = SequenceStatus.SET_INTERVAL
+ self.last_config_frame = set()
+ self.current_slot.interval = 0
+ self.start_time = ticks_ms()
+
+ # Add the current keypress state to the sequence
+ def record_frame(self, keys_pressed):
+ if self.current_slot.sequence_data[self.index].keys_pressed != keys_pressed:
+ self.index += 1
+
+ # Recorded speed
+ if self.use_recorded_speed:
+ self.current_slot.sequence_data.append(
+ SequenceFrame(
+ keys_pressed.copy(), ticks_diff(ticks_ms(), self.start_time)
+ )
+ )
+
+ # Constant speed
+ else:
+ self.current_slot.sequence_data.append(
+ SequenceFrame(keys_pressed.copy(), self.index * self.key_interval)
+ )
+
+ if not check_deadline(ticks_ms(), self.start_time, self.timeout):
+ self.stop_recording()
+
+ # Add the ending frames to the sequence
+ def stop_recording(self):
+ # Clear the remaining keys
+ self.current_slot.sequence_data.append(
+ SequenceFrame(set(), self.current_slot.sequence_data[-1].timestamp + 20)
+ )
+
+ # Wait for the specified interval
+ prev_timestamp = self.current_slot.sequence_data[-1].timestamp
+ self.current_slot.sequence_data.append(
+ SequenceFrame(
+ set(),
+ prev_timestamp + self.current_slot.interval * 1000,
+ )
+ )
+
+ self.status = SequenceStatus.STOPPED
+
+ def play_frame(self, keyboard):
+ # Send the keypresses at this point in the sequence
+ if not check_deadline(
+ ticks_ms(),
+ self.start_time,
+ self.current_slot.sequence_data[self.index].timestamp,
+ ):
+ if self.index:
+ prev = self.current_slot.sequence_data[self.index - 1].keys_pressed
+ cur = self.current_slot.sequence_data[self.index].keys_pressed
+
+ for key in prev.difference(cur):
+ keyboard.remove_key(key)
+ for key in cur.difference(prev):
+ keyboard.add_key(key)
+
+ self.index += 1
+ if self.index >= len(self.current_slot.sequence_data): # Reached the end
+ self.current_repetition += 1
+ if self.current_repetition == self.current_slot.repetitions:
+ self.status = SequenceStatus.STOPPED
+ else:
+ self.index = 0
+ self.start_time = ticks_ms()
+
+ # Configuration for repeating sequences
+ def config_mode(self, keyboard):
+ for key in keyboard.keys_pressed.difference(self.last_config_frame):
+ if key.code in _numbers:
+ digit = (key.code - KC.N1.code + 1) % 10
+ if self.status == SequenceStatus.SET_REPEPITIONS:
+ self.current_slot.repetitions = (
+ self.current_slot.repetitions * 10 + digit
+ )
+ elif self.status == SequenceStatus.SET_INTERVAL:
+ self.current_slot.interval = self.current_slot.interval * 10 + digit
+
+ elif key.code == KC.ENTER.code:
+ self.stop_config()
+
+ self.last_config_frame = keyboard.keys_pressed.copy()
+ keyboard.hid_pending = False # Disable typing
+
+ if not check_deadline(ticks_ms(), self.start_time, self.timeout):
+ self.stop_config()
+
+ # Finish configuring repetitions
+ def stop_config(self):
+ self.current_slot.sequence_data[-1] = SequenceFrame(
+ self.current_slot.sequence_data[-1].keys_pressed,
+ self.current_slot.sequence_data[-2].timestamp
+ + self.current_slot.interval * 1000,
+ )
+ self.current_slot.repetitions = max(self.current_slot.repetitions, 1)
+ self.status = SequenceStatus.STOPPED
+
+ def on_runtime_enable(self, keyboard):
+ return
+
+ def on_runtime_disable(self, keyboard):
+ return
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+
+ if not self.status:
+ return
+
+ elif self.status == SequenceStatus.RECORDING:
+ self.record_frame(keyboard.keys_pressed)
+
+ elif self.status == SequenceStatus.PLAYING:
+ self.play_frame(keyboard)
+
+ elif (
+ self.status == SequenceStatus.SET_REPEPITIONS
+ or self.status == SequenceStatus.SET_INTERVAL
+ ):
+ self.config_mode(keyboard)
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/modules/easypoint.py b/hackpads/blipyboard/firmware/kmk/modules/easypoint.py
new file mode 100644
index 0000000000..bf7023c098
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/easypoint.py
@@ -0,0 +1,130 @@
+'''
+Extension handles usage of AS5013 by AMS
+'''
+
+from supervisor import ticks_ms
+
+from kmk.keys import AX
+from kmk.modules import Module
+
+I2C_ADDRESS = 0x40
+I2X_ALT_ADDRESS = 0x41
+
+X = 0x10
+Y_RES_INT = 0x11
+
+XP = 0x12
+XN = 0x13
+YP = 0x14
+YN = 0x15
+
+M_CTRL = 0x2B
+T_CTRL = 0x2D
+
+Y_OFFSET = 17
+X_OFFSET = 7
+
+DEAD_X = 5
+DEAD_Y = 5
+
+
+class Easypoint(Module):
+ '''Module handles usage of AS5013 by AMS'''
+
+ def __init__(
+ self,
+ i2c,
+ address=I2C_ADDRESS,
+ y_offset=Y_OFFSET,
+ x_offset=X_OFFSET,
+ dead_x=DEAD_X,
+ dead_y=DEAD_Y,
+ ):
+ self._i2c_address = address
+ self._i2c_bus = i2c
+
+ # HID parameters
+ self.polling_interval = 20
+ self.last_tick = ticks_ms()
+
+ # Offsets for poor soldering
+ self.y_offset = y_offset
+ self.x_offset = x_offset
+
+ # Deadzone
+ self.dead_x = DEAD_X
+ self.dead_y = DEAD_Y
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ '''
+ Return value will be injected as an extra matrix update
+ '''
+ now = ticks_ms()
+ if now - self.last_tick < self.polling_interval:
+ return
+ self.last_tick = now
+
+ x, y = self._read_raw_state()
+
+ # I'm a shit coder, so offset is handled in software side
+ s_x = self.getSignedNumber(x, 8) - self.x_offset
+ s_y = self.getSignedNumber(y, 8) - self.y_offset
+
+ # Evaluate Deadzone
+ if s_x in range(-self.dead_x, self.dead_x) and s_y in range(
+ -self.dead_y, self.dead_y
+ ):
+ # Within bounds, just die
+ return
+ else:
+ # Set the X/Y from easypoint
+ AX.X.move(keyboard, x)
+ AX.Y.move(keyboard, y)
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def _read_raw_state(self):
+ '''Read data from AS5013'''
+ x, y = self._i2c_rdwr([X], length=2)
+ return x, y
+
+ def getSignedNumber(self, number, bitLength=8):
+ mask = (2**bitLength) - 1
+ if number & (1 << (bitLength - 1)):
+ return number | ~mask
+ else:
+ return number & mask
+
+ def _i2c_rdwr(self, data, length=1):
+ '''Write and optionally read I2C data.'''
+ while not self._i2c_bus.try_lock():
+ pass
+
+ try:
+ if length > 0:
+ result = bytearray(length)
+ self._i2c_bus.writeto_then_readfrom(
+ self._i2c_address, bytes(data), result
+ )
+ return result
+ else:
+ self._i2c_bus.writeto(self._i2c_address, bytes(data))
+ return []
+ finally:
+ self._i2c_bus.unlock()
diff --git a/hackpads/blipyboard/firmware/kmk/modules/encoder.py b/hackpads/blipyboard/firmware/kmk/modules/encoder.py
new file mode 100644
index 0000000000..ca63610a21
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/encoder.py
@@ -0,0 +1,334 @@
+# See docs/encoder.md for how to use
+
+import busio
+import digitalio
+from supervisor import ticks_ms
+
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+# NB : not using rotaryio as it requires the pins to be consecutive
+
+
+class BaseEncoder:
+
+ VELOCITY_MODE = True
+
+ def __init__(self, is_inverted=False, divisor=4):
+
+ self.is_inverted = is_inverted
+ self.divisor = divisor
+
+ self._state = None
+ self._start_state = None
+ self._direction = None
+ self._pos = 0
+ self._button_state = True
+ self._button_held = None
+ self._velocity = 0
+
+ self._movement = 0
+ self._timestamp = ticks_ms()
+
+ # callback functions on events. Need to be defined externally
+ self.on_move_do = None
+ self.on_button_do = None
+
+ def get_state(self):
+ return {
+ 'direction': self.is_inverted and -self._direction or self._direction,
+ 'position': self.is_inverted and -self._pos or self._pos,
+ 'is_pressed': not self._button_state,
+ 'velocity': self._velocity,
+ }
+
+ # Called in a loop to refresh encoder state
+
+ def update_state(self):
+ # Rotation events
+ new_state = (self.pin_a.get_value(), self.pin_b.get_value())
+
+ if new_state != self._state:
+ # encoder moved
+ self._movement += 1
+ # false / false and true / true are common half steps
+ # looking on the step just before helps determining
+ # the direction
+ if new_state[0] == new_state[1] and self._state[0] != self._state[1]:
+ if new_state[1] == self._state[0]:
+ self._direction = 1
+ else:
+ self._direction = -1
+
+ # when the encoder settles on a position (every 2 steps)
+ if new_state[0] == new_state[1]:
+ # an encoder returned to the previous
+ # position halfway, cancel rotation
+ if (
+ self._start_state[0] == new_state[0]
+ and self._start_state[1] == new_state[1]
+ and self._movement <= 2
+ ):
+ self._movement = 0
+ self._direction = 0
+
+ # when the encoder made a full loop according to its divisor
+ elif self._movement >= self.divisor - 1:
+ # 1 full step is 4 movements (2 for high-resolution encoder),
+ # however, when rotated quickly, some steps may be missed.
+ # This makes it behave more naturally
+ real_movement = self._movement // self.divisor
+ self._pos += self._direction * real_movement
+ if self.on_move_do is not None:
+ for i in range(real_movement):
+ self.on_move_do(self.get_state())
+
+ # Rotation finished, reset to identify new movement
+ self._movement = 0
+ self._direction = 0
+ self._start_state = new_state
+
+ self._state = new_state
+
+ # Velocity
+ self.velocity_event()
+
+ # Button event
+ self.button_event()
+
+ def velocity_event(self):
+ if self.VELOCITY_MODE:
+ new_timestamp = ticks_ms()
+ self._velocity = new_timestamp - self._timestamp
+ self._timestamp = new_timestamp
+
+ def button_event(self):
+ raise NotImplementedError('subclasses must override button_event()!')
+
+ # return knob velocity as milliseconds between position changes (detents)
+ # for backwards compatibility
+ def vel_report(self):
+ return self._velocity
+
+
+class GPIOEncoder(BaseEncoder):
+ def __init__(
+ self,
+ pin_a,
+ pin_b,
+ pin_button=None,
+ is_inverted=False,
+ divisor=None,
+ button_pull=digitalio.Pull.UP,
+ ):
+ super().__init__(is_inverted)
+
+ # Divisor can be 4 or 2 depending on whether the detent
+ # on the encoder is defined by 2 or 4 pulses
+ self.divisor = divisor
+
+ self.pin_a = EncoderPin(pin_a)
+ self.pin_b = EncoderPin(pin_b)
+ if pin_button:
+ self.pin_button = EncoderPin(pin_button, button_type=True, pull=button_pull)
+ else:
+ self.pin_button = None
+
+ self._state = (self.pin_a.get_value(), self.pin_b.get_value())
+ self._start_state = self._state
+
+ def button_event(self):
+ if self.pin_button:
+ new_button_state = self.pin_button.get_value()
+ if new_button_state != self._button_state:
+ self._button_state = new_button_state
+ if self.on_button_do is not None:
+ self.on_button_do(self.get_state())
+
+
+class EncoderPin:
+ def __init__(self, pin, button_type=False, pull=digitalio.Pull.UP):
+ self.pin = pin
+ self.button_type = button_type
+ self.pull = pull
+ self.prepare_pin()
+
+ def prepare_pin(self):
+ if self.pin is not None:
+ if isinstance(self.pin, digitalio.DigitalInOut):
+ self.io = self.pin
+ else:
+ self.io = digitalio.DigitalInOut(self.pin)
+ self.io.direction = digitalio.Direction.INPUT
+ self.io.pull = self.pull
+ else:
+ self.io = None
+
+ def get_value(self):
+ io = self.io
+ result = io.value
+ if digitalio.Pull.UP != io.pull:
+ result = not result
+ return result
+
+
+class I2CEncoder(BaseEncoder):
+ def __init__(self, i2c, address, is_inverted=False):
+
+ try:
+ from adafruit_seesaw import digitalio, neopixel, rotaryio, seesaw
+ except ImportError:
+ if debug.enabled:
+ debug('seesaw missing')
+ return
+
+ super().__init__(is_inverted)
+
+ self.seesaw = seesaw.Seesaw(i2c, address)
+
+ # Check for correct product
+
+ seesaw_product = (self.seesaw.get_version() >> 16) & 0xFFFF
+ if seesaw_product != 4991:
+ if debug.enabled:
+ debug('Wrong firmware loaded? Expected 4991')
+
+ self.encoder = rotaryio.IncrementalEncoder(self.seesaw)
+ self.seesaw.pin_mode(24, self.seesaw.INPUT_PULLUP)
+ self.switch = digitalio.DigitalIO(self.seesaw, 24)
+ self.pixel = neopixel.NeoPixel(self.seesaw, 6, 1)
+
+ self._state = self.encoder.position
+
+ def update_state(self):
+
+ # Rotation events
+ new_state = self.encoder.position
+ if new_state != self._state:
+ # it moves !
+ self._movement += 1
+ # false / false and true / true are common half steps
+ # looking on the step just before helps determining
+ # the direction
+ if self.encoder.position > self._state:
+ self._direction = 1
+ else:
+ self._direction = -1
+ self._state = new_state
+ self.on_move_do(self.get_state())
+
+ # Velocity
+ self.velocity_event()
+
+ # Button events
+ self.button_event()
+
+ def button_event(self):
+ if not self.switch.value and not self._button_held:
+ # Pressed
+ self._button_held = True
+ if self.on_button_do is not None:
+ self.on_button_do(self.get_state())
+
+ if self.switch.value and self._button_held:
+ # Released
+ self._button_held = False
+
+ def get_state(self):
+ return {
+ 'direction': self.is_inverted and -self._direction or self._direction,
+ 'position': self._state,
+ 'is_pressed': not self.switch.value,
+ 'is_held': self._button_held,
+ 'velocity': self._velocity,
+ }
+
+
+class EncoderHandler(Module):
+ def __init__(self):
+ self.encoders = []
+ self.pins = None
+ self.map = None
+ self.divisor = 4
+
+ def on_runtime_enable(self, keyboard):
+ return
+
+ def on_runtime_disable(self, keyboard):
+ return
+
+ def during_bootup(self, keyboard):
+ if self.pins and self.map:
+ for idx, pins in enumerate(self.pins):
+ try:
+ # Check for busio.I2C
+ if isinstance(pins[0], busio.I2C):
+ new_encoder = I2CEncoder(*pins)
+
+ # Else fall back to GPIO
+ else:
+ new_encoder = GPIOEncoder(*pins)
+ # Set default divisor if unset
+ if new_encoder.divisor is None:
+ new_encoder.divisor = self.divisor
+
+ # In our case, we need to define keybord and encoder_id for callbacks
+ new_encoder.on_move_do = lambda x, bound_idx=idx: self.on_move_do(
+ keyboard, bound_idx, x
+ )
+ new_encoder.on_button_do = (
+ lambda x, bound_idx=idx: self.on_button_do(
+ keyboard, bound_idx, x
+ )
+ )
+ self.encoders.append(new_encoder)
+ except Exception as e:
+ if debug.enabled:
+ debug(e)
+ return
+
+ def on_move_do(self, keyboard, encoder_id, state):
+ if self.map:
+ layer_id = keyboard.active_layers[0]
+ # if Left, key index 0 else key index 1
+ if state['direction'] == -1:
+ key_index = 0
+ else:
+ key_index = 1
+ key = self.map[layer_id][encoder_id][key_index]
+ keyboard.tap_key(key)
+
+ def on_button_do(self, keyboard, encoder_id, state):
+ if state['is_pressed'] is True:
+ layer_id = keyboard.active_layers[0]
+ key = self.map[layer_id][encoder_id][2]
+ keyboard.tap_key(key)
+
+ def before_matrix_scan(self, keyboard):
+ '''
+ Return value will be injected as an extra matrix update
+ '''
+ for encoder in self.encoders:
+ encoder.update_state()
+
+ return keyboard
+
+ def after_matrix_scan(self, keyboard):
+ '''
+ Return value will be replace matrix update if supplied
+ '''
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/modules/holdtap.py b/hackpads/blipyboard/firmware/kmk/modules/holdtap.py
new file mode 100644
index 0000000000..3bd6cf49a1
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/holdtap.py
@@ -0,0 +1,272 @@
+from micropython import const
+
+from kmk.keys import Key, make_argumented_key
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class ActivationType:
+ PRESSED = const(0)
+ RELEASED = const(1)
+ HOLD_TIMEOUT = const(2)
+ INTERRUPTED = const(3)
+ REPEAT = const(4)
+
+
+class HoldTapRepeat:
+ NONE = const(0)
+ TAP = const(1)
+ HOLD = const(2)
+ ALL = const(3)
+
+
+class HoldTapKeyState:
+ def __init__(self, timeout_key, *args, **kwargs):
+ self.timeout_key = timeout_key
+ self.args = args
+ self.kwargs = kwargs
+ self.activated = ActivationType.PRESSED
+
+
+class HoldTapKey(Key):
+ def __init__(
+ self,
+ tap,
+ hold,
+ prefer_hold=True,
+ tap_interrupted=False,
+ tap_time=None,
+ repeat=HoldTapRepeat.NONE,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.tap = tap
+ self.hold = hold
+ self.prefer_hold = prefer_hold
+ self.tap_interrupted = tap_interrupted
+ self.tap_time = tap_time
+ self.repeat = repeat
+
+
+class HoldTap(Module):
+ tap_time = 300
+
+ def __init__(self, _make_key=True):
+ self.key_buffer = []
+ self.key_states = {}
+
+ if _make_key:
+ make_argumented_key(
+ names=('HT',),
+ constructor=HoldTapKey,
+ on_press=self.ht_pressed,
+ on_release=self.ht_released,
+ )
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ '''Handle holdtap being interrupted by another key press/release.'''
+ current_key = key
+ send_buffer = False
+ append_buffer = False
+
+ for key, state in self.key_states.items():
+ if key == current_key:
+ continue
+ if state.activated != ActivationType.PRESSED:
+ continue
+
+ # holdtap isn't interruptable, resolves on ht_release or timeout.
+ if not key.tap_interrupted and not key.prefer_hold:
+ append_buffer = is_pressed or self.key_buffer
+ continue
+
+ # holdtap is interrupted by another key event.
+ if (is_pressed and not key.tap_interrupted) or (
+ not is_pressed and key.tap_interrupted and self.key_buffer
+ ):
+
+ keyboard.cancel_timeout(state.timeout_key)
+ self.key_states[key].activated = ActivationType.INTERRUPTED
+ self.ht_activate_on_interrupt(
+ key,
+ keyboard,
+ *state.args,
+ **state.kwargs,
+ )
+ append_buffer = True
+ send_buffer = True
+
+ # if interrupt on release: store interrupting keys until one of them
+ # is released.
+ if key.tap_interrupted and is_pressed:
+ append_buffer = True
+
+ # apply changes with 'side-effects' on key_states or the loop behaviour
+ # outside the loop.
+ if append_buffer:
+ self.key_buffer.append((int_coord, current_key, is_pressed))
+ current_key = None
+
+ if send_buffer:
+ self.send_key_buffer(keyboard)
+
+ return current_key
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def ht_pressed(self, key, keyboard, *args, **kwargs):
+ '''Unless in repeat mode, do nothing yet, action resolves when key is released, timer expires or other key is pressed.'''
+ if key in self.key_states:
+ state = self.key_states[key]
+ keyboard.cancel_timeout(self.key_states[key].timeout_key)
+
+ if state.activated == ActivationType.RELEASED:
+ state.activated = ActivationType.REPEAT
+ self.ht_activate_tap(key, keyboard, *args, **kwargs)
+ elif state.activated == ActivationType.HOLD_TIMEOUT:
+ self.ht_activate_hold(key, keyboard, *args, **kwargs)
+ elif state.activated == ActivationType.INTERRUPTED:
+ self.ht_activate_on_interrupt(key, keyboard, *args, **kwargs)
+ return
+
+ if key.tap_time is None:
+ tap_time = self.tap_time
+ else:
+ tap_time = key.tap_time
+ timeout_key = keyboard.set_timeout(
+ tap_time,
+ lambda: self.on_tap_time_expired(key, keyboard, *args, **kwargs),
+ )
+ self.key_states[key] = HoldTapKeyState(timeout_key, *args, **kwargs)
+ return keyboard
+
+ def ht_released(self, key, keyboard, *args, **kwargs):
+ '''On keyup, release mod or tap key.'''
+ if key not in self.key_states:
+ return keyboard
+
+ state = self.key_states[key]
+ keyboard.cancel_timeout(state.timeout_key)
+ repeat = key.repeat & HoldTapRepeat.TAP
+
+ if state.activated == ActivationType.HOLD_TIMEOUT:
+ # release hold
+ self.ht_deactivate_hold(key, keyboard, *args, **kwargs)
+ repeat = key.repeat & HoldTapRepeat.HOLD
+ elif state.activated == ActivationType.INTERRUPTED:
+ # release tap
+ self.ht_deactivate_on_interrupt(key, keyboard, *args, **kwargs)
+ if key.prefer_hold:
+ repeat = key.repeat & HoldTapRepeat.HOLD
+ elif state.activated == ActivationType.PRESSED:
+ # press and release tap because key released within tap time
+ self.ht_activate_tap(key, keyboard, *args, **kwargs)
+ self.send_key_buffer(keyboard)
+ self.ht_deactivate_tap(key, keyboard, *args, **kwargs)
+ state.activated = ActivationType.RELEASED
+ self.send_key_buffer(keyboard)
+ elif state.activated == ActivationType.REPEAT:
+ state.activated = ActivationType.RELEASED
+ self.ht_deactivate_tap(key, keyboard, *args, **kwargs)
+
+ # don't delete the key state right now in this case
+ if repeat:
+ if key.tap_time is None:
+ tap_time = self.tap_time
+ else:
+ tap_time = key.tap_time
+ state.timeout_key = keyboard.set_timeout(
+ tap_time, lambda: self.key_states.pop(key)
+ )
+ else:
+ del self.key_states[key]
+
+ return keyboard
+
+ def on_tap_time_expired(self, key, keyboard, *args, **kwargs):
+ '''When tap time expires activate hold if key is still being pressed.
+ Remove key if ActivationType is RELEASED.'''
+ try:
+ state = self.key_states[key]
+ except KeyError:
+ if debug.enabled:
+ debug(f'on_tap_time_expired: no such key {key}')
+ return
+
+ if self.key_states[key].activated == ActivationType.PRESSED:
+ # press hold because timer expired after tap time
+ self.key_states[key].activated = ActivationType.HOLD_TIMEOUT
+ self.ht_activate_hold(key, keyboard, *args, **kwargs)
+ self.send_key_buffer(keyboard)
+ elif state.activated == ActivationType.RELEASED:
+ self.ht_deactivate_tap(key, keyboard, *args, **kwargs)
+ del self.key_states[key]
+
+ def send_key_buffer(self, keyboard):
+ if not self.key_buffer:
+ return
+
+ reprocess = False
+ for int_coord, key, is_pressed in self.key_buffer:
+ keyboard.resume_process_key(self, key, is_pressed, int_coord, reprocess)
+ if isinstance(key, HoldTapKey):
+ reprocess = True
+
+ self.key_buffer.clear()
+
+ def ht_activate_hold(self, key, keyboard, *args, **kwargs):
+ if debug.enabled:
+ debug('ht_activate_hold')
+ keyboard.resume_process_key(self, key.hold, True)
+
+ def ht_deactivate_hold(self, key, keyboard, *args, **kwargs):
+ if debug.enabled:
+ debug('ht_deactivate_hold')
+ keyboard.resume_process_key(self, key.hold, False)
+
+ def ht_activate_tap(self, key, keyboard, *args, **kwargs):
+ if debug.enabled:
+ debug('ht_activate_tap')
+ keyboard.resume_process_key(self, key.tap, True)
+
+ def ht_deactivate_tap(self, key, keyboard, *args, **kwargs):
+ if debug.enabled:
+ debug('ht_deactivate_tap')
+ keyboard.resume_process_key(self, key.tap, False)
+
+ def ht_activate_on_interrupt(self, key, keyboard, *args, **kwargs):
+ if debug.enabled:
+ debug('ht_activate_on_interrupt')
+ if key.prefer_hold:
+ self.ht_activate_hold(key, keyboard, *args, **kwargs)
+ else:
+ self.ht_activate_tap(key, keyboard, *args, **kwargs)
+
+ def ht_deactivate_on_interrupt(self, key, keyboard, *args, **kwargs):
+ if debug.enabled:
+ debug('ht_deactivate_on_interrupt')
+ if key.prefer_hold:
+ self.ht_deactivate_hold(key, keyboard, *args, **kwargs)
+ else:
+ self.ht_deactivate_tap(key, keyboard, *args, **kwargs)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/layers.py b/hackpads/blipyboard/firmware/kmk/modules/layers.py
new file mode 100644
index 0000000000..17cf84a670
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/layers.py
@@ -0,0 +1,193 @@
+'''One layer isn't enough. Adds keys to get to more of them'''
+
+from kmk.keys import KC, Key, make_argumented_key
+from kmk.modules.holdtap import HoldTap, HoldTapKey
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+def lt_key(layer, key, prefer_hold=False, **kwargs):
+ return HoldTapKey(tap=key, hold=KC.MO(layer), prefer_hold=prefer_hold, **kwargs)
+
+
+def tt_key(layer, prefer_hold=True, **kwargs):
+ return HoldTapKey(
+ tap=KC.TG(layer),
+ hold=KC.MO(layer),
+ prefer_hold=prefer_hold,
+ **kwargs,
+ )
+
+
+class LayerKey(Key):
+ def __init__(self, layer, key=None, **kwargs):
+ super().__init__(**kwargs)
+ self.layer = layer
+ self.key = key
+
+
+class Layers(HoldTap):
+ '''Gives access to the keys used to enable the layer system'''
+
+ _active_combo = None
+
+ def __init__(self, combo_layers=None):
+ # Layers
+ super().__init__(_make_key=False)
+ self.combo_layers = combo_layers
+ make_argumented_key(
+ names=('MO',),
+ constructor=LayerKey,
+ on_press=self._mo_pressed,
+ on_release=self._mo_released,
+ )
+ make_argumented_key(
+ names=('FD',),
+ constructor=LayerKey,
+ on_press=self._fd_pressed,
+ )
+ make_argumented_key(
+ names=('DF',),
+ constructor=LayerKey,
+ on_press=self._df_pressed,
+ )
+ make_argumented_key(
+ names=('LM',),
+ constructor=LayerKey,
+ on_press=self._lm_pressed,
+ on_release=self._lm_released,
+ )
+ make_argumented_key(
+ names=('TG',),
+ constructor=LayerKey,
+ on_press=self._tg_pressed,
+ )
+ make_argumented_key(
+ names=('TO',),
+ constructor=LayerKey,
+ on_press=self._to_pressed,
+ )
+ make_argumented_key(
+ names=('LT',),
+ constructor=lt_key,
+ on_press=self.ht_pressed,
+ on_release=self.ht_released,
+ )
+ make_argumented_key(
+ names=('TT',),
+ constructor=tt_key,
+ on_press=self.ht_pressed,
+ on_release=self.ht_released,
+ )
+
+ def _fd_pressed(self, key, keyboard, *args, **kwargs):
+ '''
+ Switches the top layer
+ '''
+ self.activate_layer(keyboard, key.layer, idx=0)
+
+ def _df_pressed(self, key, keyboard, *args, **kwargs):
+ '''
+ Switches the default layer
+ '''
+ self.activate_layer(keyboard, key.layer, idx=-1)
+
+ def _mo_pressed(self, key, keyboard, *args, **kwargs):
+ '''
+ Momentarily activates layer, switches off when you let go
+ '''
+ self.activate_layer(keyboard, key.layer)
+
+ def _mo_released(self, key, keyboard, *args, **kwargs):
+ self.deactivate_layer(keyboard, key.layer)
+
+ def _lm_pressed(self, key, keyboard, *args, **kwargs):
+ '''
+ As MO(layer) but with mod active
+ '''
+ keyboard.hid_pending = True
+ keyboard.keys_pressed.add(key.key)
+ self.activate_layer(keyboard, key.layer)
+
+ def _lm_released(self, key, keyboard, *args, **kwargs):
+ '''
+ As MO(layer) but with mod active
+ '''
+ keyboard.hid_pending = True
+ keyboard.keys_pressed.discard(key.key)
+ self.deactivate_layer(keyboard, key.layer)
+
+ def _tg_pressed(self, key, keyboard, *args, **kwargs):
+ '''
+ Toggles the layer (enables it if not active, and vise versa)
+ '''
+ # See mo_released for implementation details around this
+ if key.layer in keyboard.active_layers:
+ self.deactivate_layer(keyboard, key.layer)
+ else:
+ self.activate_layer(keyboard, key.layer)
+
+ def _to_pressed(self, key, keyboard, *args, **kwargs):
+ '''
+ Activates layer and deactivates all other layers
+ '''
+ self._active_combo = None
+ keyboard.active_layers.clear()
+ self.activate_layer(keyboard, key.layer)
+
+ def _print_debug(self, keyboard):
+ if debug.enabled:
+ debug(f'active_layers={keyboard.active_layers}')
+
+ def activate_layer(self, keyboard, layer, idx=None):
+ if idx is None:
+ keyboard.active_layers.insert(0, layer)
+ else:
+ keyboard.active_layers[idx] = layer
+
+ if self.combo_layers:
+ self._activate_combo_layer(keyboard)
+
+ self._print_debug(keyboard)
+
+ def deactivate_layer(self, keyboard, layer):
+ # Remove the first instance of the target layer from the active list
+ # under almost all normal use cases, this will disable the layer (but
+ # preserve it if it was triggered as a default layer, etc.).
+ # This also resolves an issue where using DF() on a layer
+ # triggered by MO() and then defaulting to the MO()'s layer
+ # would result in no layers active.
+ if len(keyboard.active_layers) > 1:
+ try:
+ idx = keyboard.active_layers.index(layer)
+ del keyboard.active_layers[idx]
+ except ValueError:
+ if debug.enabled:
+ debug(f'_mo_released: layer {layer} not active')
+
+ if self.combo_layers:
+ self._deactivate_combo_layer(keyboard, layer)
+
+ self._print_debug(keyboard)
+
+ def _activate_combo_layer(self, keyboard):
+ if self._active_combo:
+ return
+
+ for combo, result in self.combo_layers.items():
+ matching = True
+ for layer in combo:
+ if layer not in keyboard.active_layers:
+ matching = False
+ break
+
+ if matching:
+ self._active_combo = combo
+ keyboard.active_layers.insert(0, result)
+ break
+
+ def _deactivate_combo_layer(self, keyboard, layer):
+ if self._active_combo and layer in self._active_combo:
+ keyboard.active_layers.remove(self.combo_layers[self._active_combo])
+ self._active_combo = None
diff --git a/hackpads/blipyboard/firmware/kmk/modules/macros.py b/hackpads/blipyboard/firmware/kmk/modules/macros.py
new file mode 100644
index 0000000000..be26e13f62
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/macros.py
@@ -0,0 +1,315 @@
+from micropython import const
+
+from kmk.keys import KC, Key, make_argumented_key, make_key
+from kmk.modules import Module
+from kmk.scheduler import create_task
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+_IDLE = const(0)
+_ON_PRESS = const(1)
+_ON_HOLD = const(2)
+_RELEASE = const(3)
+_ON_RELEASE = const(4)
+
+
+class MacroKey(Key):
+ def __init__(
+ self,
+ *args,
+ on_press=None,
+ on_hold=None,
+ on_release=None,
+ blocking=True,
+ _on_press=None,
+ _on_release=None,
+ ):
+ super().__init__(on_press=_on_press, on_release=_on_release)
+
+ if on_press is not None:
+ self.on_press_macro = on_press
+ else:
+ self.on_press_macro = args
+ self.on_hold_macro = on_hold
+ self.on_release_macro = on_release
+ self.blocking = blocking
+ self.state = _IDLE
+ self._task = None
+
+
+class UnicodeModeKey(Key):
+ def __init__(self, mode, **kwargs):
+ super().__init__(**kwargs)
+ self.mode = mode
+
+
+def Delay(delay):
+ return lambda keyboard: delay
+
+
+def Press(key):
+ return lambda keyboard: key.on_press(keyboard)
+
+
+def Release(key):
+ return lambda keyboard: key.on_release(keyboard)
+
+
+def Tap(key):
+ def _(keyboard):
+ key.on_press(keyboard)
+ yield
+ key.on_release(keyboard)
+
+ return _
+
+
+class UnicodeModeIBus:
+ @staticmethod
+ def pre(keyboard):
+ macro = (KC.LCTL, KC.LSFT, KC.U)
+ for k in macro:
+ k.on_press(keyboard)
+ yield
+ for k in macro:
+ k.on_release(keyboard)
+
+ @staticmethod
+ def post(keyboard):
+ KC.ENTER.on_press(keyboard)
+ yield
+ KC.ENTER.on_release(keyboard)
+
+
+class UnicodeModeMacOS:
+ @staticmethod
+ def pre(keyboard):
+ KC.LALT.on_press(keyboard)
+ yield
+
+ @staticmethod
+ def post(keyboard):
+ KC.LALT.on_release(keyboard)
+ yield
+
+
+class UnicodeModeWinC:
+ @staticmethod
+ def pre(keyboard):
+ macro = (KC.RALT, KC.U)
+ for k in macro:
+ k.on_press(keyboard)
+ yield
+ for k in macro:
+ k.on_release(keyboard)
+
+ @staticmethod
+ def post(keyboard):
+ KC.ENTER.on_press(keyboard)
+ yield
+ KC.ENTER.on_release(keyboard)
+
+
+def MacroIter(keyboard, macro, unicode_mode):
+ for item in macro:
+ if callable(item):
+ item = item(keyboard)
+
+ if item is None:
+ yield
+
+ elif isinstance(item, int):
+ yield item
+
+ elif isinstance(item, str):
+ for char in item:
+ if ord(char) <= 127:
+ # ANSII key codes
+ key = KC[char]
+ if char.isupper():
+ KC.LSHIFT.on_press(keyboard)
+ key.on_press(keyboard)
+ yield
+
+ if char.isupper():
+ KC.LSHIFT.on_release(keyboard)
+ key.on_release(keyboard)
+ yield
+
+ else:
+ # unicode code points
+ yield from unicode_mode.pre(keyboard)
+ yield
+
+ for digit in hex(ord(char))[2:]:
+ key = KC[digit]
+ key.on_press(keyboard)
+ yield
+ key.on_release(keyboard)
+ yield
+
+ yield from unicode_mode.post(keyboard)
+ yield
+
+ elif item.__class__.__name__ == 'generator':
+ yield from MacroIter(keyboard, item, unicode_mode)
+ yield
+
+ elif debug.enabled:
+ debug('unsupported macro type ', item.__class__.__name__)
+
+
+class Macros(Module):
+ def __init__(self, unicode_mode=UnicodeModeIBus, delay=10):
+ self._active = []
+ self.key_buffer = []
+ self.unicode_mode = unicode_mode
+ self.delay = delay
+
+ make_argumented_key(
+ names=('MACRO',),
+ constructor=MacroKey,
+ _on_press=self.on_press_macro,
+ _on_release=self.on_release_macro,
+ )
+ make_key(
+ names=('UC_MODE_IBUS',),
+ constructor=UnicodeModeKey,
+ mode=UnicodeModeIBus,
+ on_press=self.on_press_unicode_mode,
+ )
+ make_key(
+ names=('UC_MODE_MACOS',),
+ constructor=UnicodeModeKey,
+ mode=UnicodeModeMacOS,
+ on_press=self.on_press_unicode_mode,
+ )
+ make_key(
+ names=('UC_MODE_WINC',),
+ constructor=UnicodeModeKey,
+ mode=UnicodeModeWinC,
+ on_press=self.on_press_unicode_mode,
+ )
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ # Passthrough if there are no active macros, or the key belongs to an
+ # active macro, or all active macros or non-blocking.
+ if not self._active or key in self._active or not self._active[-1].blocking:
+ return key
+
+ self.key_buffer.append((int_coord, key, is_pressed))
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def on_press_unicode_mode(self, key, keyboard, *args, **kwargs):
+ self.unicode_mode = key.mode
+
+ def on_press_macro(self, key, keyboard, *args, **kwargs):
+ if key.state == _IDLE:
+ key.state = _ON_PRESS
+ self.process_macro_async(keyboard, key)
+ else:
+ self.key_buffer.append((args[1], key, True))
+
+ def on_release_macro(self, key, keyboard, *args, **kwargs):
+ if key.state == _ON_PRESS or key.state == _ON_HOLD:
+ key.state = _RELEASE
+ if key._task is None:
+ self.process_macro_async(keyboard, key)
+ else:
+ self.key_buffer.append((args[1], key, False))
+
+ def process_macro_async(self, keyboard, key, _iter=None):
+ # There's no active macro iterator: select the next one.
+ if _iter is None:
+ key._task = None
+
+ if key.state == _ON_PRESS:
+ self._active.append(key)
+ if (macro := key.on_press_macro) is None:
+ key.state = _ON_HOLD
+ elif debug.enabled:
+ debug('on_press')
+
+ if key.state == _ON_HOLD:
+ if (macro := key.on_hold_macro) is None:
+ return
+ elif debug.enabled:
+ debug('on_hold')
+
+ if key.state == _RELEASE:
+ key.state = _ON_RELEASE
+
+ if key.state == _ON_RELEASE:
+ if (macro := key.on_release_macro) is None:
+ macro = ()
+ elif debug.enabled:
+ debug('on_release')
+
+ _iter = MacroIter(keyboard, macro, self.unicode_mode)
+
+ # Run one step in the macro sequence.
+ delay = self.delay
+ try:
+ # any not None value the iterator yields is a delay value in ms.
+ ret = next(_iter)
+ if ret is not None:
+ delay = ret
+ keyboard._send_hid()
+
+ # The sequence has reached its end: advance the macro state.
+ except StopIteration:
+ _iter = None
+ delay = 0
+ key._task = None
+
+ if key.state == _ON_PRESS:
+ key.state = _ON_HOLD
+
+ elif key.state == _ON_RELEASE:
+ if debug.enabled:
+ debug('deactivate')
+ key.state = _IDLE
+ self._active.remove(key)
+ self.send_key_buffer(keyboard)
+ return
+
+ # Schedule the next step.
+ # Reuse existing task objects and save a couple of bytes and cycles for the gc.
+ if key._task:
+ task = key._task
+ else:
+
+ def task():
+ self.process_macro_async(keyboard, key, _iter)
+
+ key._task = create_task(task, after_ms=delay)
+
+ def send_key_buffer(self, keyboard):
+ if not self.key_buffer or self._active:
+ return
+
+ for int_coord, key, is_pressed in self.key_buffer:
+ keyboard.resume_process_key(self, key, is_pressed, int_coord, False)
+
+ self.key_buffer.clear()
diff --git a/hackpads/blipyboard/firmware/kmk/modules/midi.py b/hackpads/blipyboard/firmware/kmk/modules/midi.py
new file mode 100644
index 0000000000..ca339f983f
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/midi.py
@@ -0,0 +1,114 @@
+import adafruit_midi
+import usb_midi
+from adafruit_midi.control_change import ControlChange
+from adafruit_midi.note_off import NoteOff
+from adafruit_midi.note_on import NoteOn
+from adafruit_midi.pitch_bend import PitchBend
+from adafruit_midi.program_change import ProgramChange
+from adafruit_midi.start import Start
+from adafruit_midi.stop import Stop
+
+from kmk.keys import Key, make_argumented_key
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class MidiKey(Key):
+ def __init__(self, *args, command, channel=None, **kwargs):
+ super().__init__(**kwargs)
+ self.on_press_msg = command(*args, channel=channel)
+ self.on_release_msg = None
+
+
+def midi_note_key(note=69, velocity=127, channel=None, **kwargs):
+ key = MidiKey(note, velocity, command=NoteOn, channel=channel, **kwargs)
+ key.on_release_msg = NoteOff(note, velocity, channel=channel)
+ return key
+
+
+class MidiKeys(Module):
+ def __init__(self):
+ make_argumented_key(
+ names=('MIDI_CC',),
+ constructor=MidiKey,
+ command=ControlChange,
+ on_press=self.on_press,
+ )
+
+ make_argumented_key(
+ names=('MIDI_NOTE',),
+ constructor=midi_note_key,
+ on_press=self.on_press,
+ on_release=self.on_release,
+ )
+
+ make_argumented_key(
+ names=('MIDI_PB',),
+ constructor=MidiKey,
+ command=PitchBend,
+ on_press=self.on_press,
+ )
+
+ make_argumented_key(
+ names=('MIDI_PC',),
+ constructor=MidiKey,
+ command=ProgramChange,
+ on_press=self.on_press,
+ )
+
+ make_argumented_key(
+ names=('MIDI_START',),
+ constructor=MidiKey,
+ command=Start,
+ on_press=self.on_press,
+ )
+
+ make_argumented_key(
+ names=('MIDI_STOP',),
+ constructor=MidiKey,
+ command=Stop,
+ on_press=self.on_press,
+ )
+
+ try:
+ self.midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)
+ except IndexError:
+ self.midi = None
+ if debug.enabled:
+ debug('No midi device found.')
+
+ def during_bootup(self, keyboard):
+ return None
+
+ def before_matrix_scan(self, keyboard):
+ return None
+
+ def after_matrix_scan(self, keyboard):
+ return None
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ return key
+
+ def before_hid_send(self, keyboard):
+ return None
+
+ def after_hid_send(self, keyboard):
+ return None
+
+ def on_powersave_enable(self, keyboard):
+ return None
+
+ def on_powersave_disable(self, keyboard):
+ return None
+
+ def send(self, message):
+ if self.midi:
+ self.midi.send(message)
+
+ def on_press(self, key, keyboard, *args, **kwargs):
+ self.send(key.on_press_msg)
+
+ def on_release(self, key, keyboard, *args, **kwargs):
+ self.send(key.on_release_msg)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/mouse_jiggler.py b/hackpads/blipyboard/firmware/kmk/modules/mouse_jiggler.py
new file mode 100644
index 0000000000..d51ed73ddf
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/mouse_jiggler.py
@@ -0,0 +1,74 @@
+import random
+
+from kmk.keys import AX, make_key
+from kmk.modules import Module
+from kmk.scheduler import cancel_task, create_task
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class MouseJiggler(Module):
+ def __init__(self, period_ms=5000, move_step=1):
+ self.move_step = move_step
+ self.period_ms = period_ms
+ self._is_jiggling = False
+
+ make_key(names=('MJ_TOGGLE',), on_press=self.toggle)
+ make_key(names=('MJ_START',), on_press=self.start)
+ make_key(names=('MJ_STOP',), on_press=self.stop)
+
+ def during_bootup(self, keyboard):
+ self._task = create_task(
+ lambda: self._jiggle(keyboard),
+ after_ms=-1, # Don't start jiggling yet.
+ period_ms=self.period_ms,
+ )
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def start(self, *args, **kwargs):
+ if not self._is_jiggling:
+ self._task.restart()
+ self._is_jiggling = True
+ if debug.enabled:
+ debug('MouseJiggler started.')
+
+ def stop(self, *args, **kwargs):
+ if self._is_jiggling:
+ cancel_task(self._task)
+ self._is_jiggling = False
+ if debug.enabled:
+ debug('MouseJiggler stopped.')
+
+ def toggle(self, *args, **kwargs):
+ if self._is_jiggling:
+ self.stop(*args, **kwargs)
+ else:
+ self.start(*args, **kwargs)
+
+ @property
+ def is_jiggling(self):
+ return self._is_jiggling
+
+ def _jiggle(self, keyboard):
+ if debug.enabled:
+ debug('MouseJiggler jiggling.')
+ AX.X.move(keyboard, random.choice([-1, 1]) * self.move_step)
+ AX.Y.move(keyboard, random.choice([-1, 1]) * self.move_step)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/mouse_keys.py b/hackpads/blipyboard/firmware/kmk/modules/mouse_keys.py
new file mode 100644
index 0000000000..7ee98dc69b
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/mouse_keys.py
@@ -0,0 +1,152 @@
+from micropython import const
+
+from kmk.keys import AX, MouseKey, make_key
+from kmk.modules import Module
+from kmk.scheduler import cancel_task, create_task
+
+_MU = const(0x01)
+_MD = const(0x02)
+_ML = const(0x04)
+_MR = const(0x08)
+_WU = const(0x10)
+_WD = const(0x20)
+_WL = const(0x40)
+_WR = const(0x80)
+
+
+class MouseKeys(Module):
+ def __init__(self, max_speed=10, acc_interval=20, move_step=1):
+ self._movement = 0
+ self.max_speed = max_speed
+ self.acc_interval = acc_interval
+ self.move_step = move_step
+
+ codes = (
+ (0x01, ('MB_LMB',)),
+ (0x02, ('MB_RMB',)),
+ (0x04, ('MB_MMB',)),
+ (0x08, ('MB_BTN4',)),
+ (0x10, ('MB_BTN5',)),
+ )
+ for code, names in codes:
+ make_key(names=names, constructor=MouseKey, code=code)
+
+ keys = (
+ (('MW_UP',), self._mw_up_press, self._mw_up_release),
+ (('MW_DOWN', 'MW_DN'), self._mw_down_press, self._mw_down_release),
+ (('MW_LEFT', 'MW_LT'), self._mw_left_press, self._mw_left_release),
+ (('MW_RIGHT', 'MW_RT'), self._mw_right_press, self._mw_right_release),
+ (('MS_UP',), self._ms_up_press, self._ms_up_release),
+ (('MS_DOWN', 'MS_DN'), self._ms_down_press, self._ms_down_release),
+ (('MS_LEFT', 'MS_LT'), self._ms_left_press, self._ms_left_release),
+ (('MS_RIGHT', 'MS_RT'), self._ms_right_press, self._ms_right_release),
+ )
+ for names, on_press, on_release in keys:
+ make_key(names=names, on_press=on_press, on_release=on_release)
+
+ def during_bootup(self, keyboard):
+ self._task = create_task(
+ lambda: self._move(keyboard),
+ period_ms=self.acc_interval,
+ )
+ cancel_task(self._task)
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def _move(self, keyboard):
+ if self._movement & (_MR + _ML + _MD + _MU):
+ if self.move_step < self.max_speed:
+ self.move_step = self.move_step + 1
+ if self._movement & _MU:
+ AX.Y.move(keyboard, -self.move_step)
+ if self._movement & _MD:
+ AX.Y.move(keyboard, self.move_step)
+ if self._movement & _ML:
+ AX.X.move(keyboard, -self.move_step)
+ if self._movement & _MR:
+ AX.X.move(keyboard, self.move_step)
+
+ if self._movement & _WU:
+ AX.W.move(keyboard, 1)
+ if self._movement & _WD:
+ AX.W.move(keyboard, -1)
+ if self._movement & _WL:
+ AX.P.move(keyboard, -1)
+ if self._movement & _WR:
+ AX.P.move(keyboard, 1)
+
+ def _maybe_start_move(self, mask):
+ self._movement |= mask
+ if self._movement == mask:
+ self._task.restart()
+
+ def _maybe_stop_move(self, mask):
+ self._movement &= ~mask
+ if not self._movement & (_MR + _ML + _MD + _MU):
+ self.move_step = 1
+ if not self._movement:
+ cancel_task(self._task)
+
+ def _mw_up_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_WU)
+
+ def _mw_up_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_WU)
+
+ def _mw_down_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_WD)
+
+ def _mw_down_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_WD)
+
+ def _mw_left_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_WL)
+
+ def _mw_left_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_WL)
+
+ def _mw_right_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_WR)
+
+ def _mw_right_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_WR)
+
+ def _ms_up_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_MU)
+
+ def _ms_up_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_MU)
+
+ def _ms_down_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_MD)
+
+ def _ms_down_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_MD)
+
+ def _ms_left_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_ML)
+
+ def _ms_left_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_ML)
+
+ def _ms_right_press(self, key, keyboard, *args, **kwargs):
+ self._maybe_start_move(_MR)
+
+ def _ms_right_release(self, key, keyboard, *args, **kwargs):
+ self._maybe_stop_move(_MR)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/pimoroni_trackball.py b/hackpads/blipyboard/firmware/kmk/modules/pimoroni_trackball.py
new file mode 100644
index 0000000000..0b65388518
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/pimoroni_trackball.py
@@ -0,0 +1,318 @@
+'''
+Extension handles usage of Trackball Breakout by Pimoroni
+'''
+
+from micropython import const
+
+import math
+import struct
+from adafruit_pixelbuf import PixelBuf
+
+from kmk.keys import AX, KC, Key, make_argumented_key, make_key
+from kmk.kmktime import PeriodicTimer
+from kmk.modules import Module
+from kmk.utils import Debug
+
+_I2C_ADDRESS = const(0x0A)
+_I2C_ADDRESS_ALTERNATIVE = const(0x0B)
+
+_CHIP_ID = const(0xBA11)
+_VERSION = const(1)
+
+_REG_LED_RED = const(0x00)
+_REG_LED_GRN = const(0x01)
+_REG_LED_BLU = const(0x02)
+_REG_LED_WHT = const(0x03)
+
+_REG_LEFT = const(0x04)
+_REG_RIGHT = const(0x05)
+_REG_UP = const(0x06)
+_REG_DOWN = const(0x07)
+_REG_SWITCH = const(0x08)
+_MSK_SWITCH_STATE = const(0b10000000)
+
+_REG_USER_FLASH = const(0xD0)
+_REG_FLASH_PAGE = const(0xF0)
+_REG_INT = const(0xF9)
+_MSK_INT_TRIGGERED = const(0b00000001)
+_MSK_INT_OUT_EN = const(0b00000010)
+_REG_CHIP_ID_L = const(0xFA)
+_REG_CHIP_ID_H = const(0xFB)
+_REG_VERSION = const(0xFC)
+_REG_I2C_ADDR = const(0xFD)
+_REG_CTRL = const(0xFE)
+_MSK_CTRL_SLEEP = const(0b00000001)
+_MSK_CTRL_RESET = const(0b00000010)
+_MSK_CTRL_FREAD = const(0b00000100)
+_MSK_CTRL_FWRITE = const(0b00001000)
+
+
+debug = Debug(__name__)
+
+
+class TrackballMode:
+ '''Behaviour mode of trackball: mouse movement or vertical scroll'''
+
+ MOUSE_MODE = const(0)
+ SCROLL_MODE = const(1)
+
+
+class ScrollDirection:
+ '''Behaviour mode of scrolling: natural or reverse scrolling'''
+
+ NATURAL = const(0)
+ REVERSE = const(1)
+
+
+class TrackballHandlerKey(Key):
+ def __init__(self, handler=TrackballMode.MOUSE_MODE, **kwargs):
+ super().__init__(**kwargs)
+ self.handler = handler
+
+
+class TrackballHandler:
+ def handle(self, keyboard, trackball, x, y, switch, state):
+ raise NotImplementedError
+
+
+class PointingHandler(TrackballHandler):
+ def __init__(self, on_press=KC.MB_LMB):
+ self.on_press = on_press
+
+ def handle(self, keyboard, trackball, x, y, switch, state):
+ if x:
+ AX.X.move(keyboard, x)
+ if y:
+ AX.Y.move(keyboard, y)
+
+ if switch == 1: # Button changed state
+ keyboard.pre_process_key(self.on_press, is_pressed=state)
+
+
+class ScrollHandler(TrackballHandler):
+ def __init__(self, scroll_direction=ScrollDirection.NATURAL, on_press=KC.MB_LMB):
+ self.scroll_direction = scroll_direction
+ self.on_press = on_press
+
+ def handle(self, keyboard, trackball, x, y, switch, state):
+ if self.scroll_direction == ScrollDirection.REVERSE:
+ y = -y
+
+ if y != 0:
+ AX.W.move(keyboard, y)
+
+ if switch == 1: # Button changed state
+ keyboard.pre_process_key(self.on_press, is_pressed=state)
+
+
+class KeyHandler(TrackballHandler):
+ x = 0
+ y = 0
+
+ def __init__(self, up, right, down, left, press, axis_snap=0.25, steps=8):
+ self.up = up
+ self.right = right
+ self.down = down
+ self.left = left
+ self.press = press
+ self.axis_snap = axis_snap
+ self.steps = steps
+
+ def handle(self, keyboard, trackball, x, y, switch, state):
+ if y and abs(x / y) < self.axis_snap:
+ x = 0
+ if x and abs(y / x) < self.axis_snap:
+ y = 0
+
+ self.x += x
+ self.y += y
+ x_taps = self.x // self.steps
+ y_taps = self.y // self.steps
+ self.x %= self.steps
+ self.y %= self.steps
+ for i in range(x_taps, 0, 1):
+ keyboard.tap_key(self.left)
+ for i in range(x_taps, 0, -1):
+ keyboard.tap_key(self.right)
+ for i in range(y_taps, 0, 1):
+ keyboard.tap_key(self.up)
+ for i in range(y_taps, 0, -1):
+ keyboard.tap_key(self.down)
+ if switch and state:
+ keyboard.tap_key(self.press)
+
+
+class Trackball(Module):
+ '''Module handles usage of Trackball Breakout by Pimoroni'''
+
+ def __init__(
+ self,
+ i2c,
+ mode=TrackballMode.MOUSE_MODE,
+ address=_I2C_ADDRESS,
+ angle_offset=0,
+ handlers=None,
+ ):
+ self.angle_offset = angle_offset
+ if not handlers:
+ handlers = [PointingHandler(), ScrollHandler()]
+ if mode == TrackballMode.SCROLL_MODE:
+ handlers.reverse()
+ self._i2c_address = address
+ self._i2c_bus = i2c
+
+ self.mode = mode
+ self.handlers = handlers
+ self.current_handler = self.handlers[0]
+ self.polling_interval = 20
+
+ make_key(
+ names=('TB_MODE', 'TB_NEXT_HANDLER', 'TB_N'),
+ on_press=self._tb_handler_next_press,
+ )
+
+ make_argumented_key(
+ names=('TB_HANDLER', 'TB_H'),
+ constructor=TrackballHandlerKey,
+ on_press=self._tb_handler_press,
+ )
+
+ def during_bootup(self, keyboard):
+ chip_id = struct.unpack('= len(self.handlers):
+ next_index = 0
+ self.activate_handler(next_index)
+
+ def _read_raw_state(self):
+ '''Read up, down, left, right and switch data from trackball.'''
+ left, right, up, down, switch = self._i2c_rdwr([_REG_LEFT], 5)
+ switch_changed, switch_state = (
+ switch & ~_MSK_SWITCH_STATE,
+ (switch & _MSK_SWITCH_STATE) > 0,
+ )
+ return up, down, left, right, switch_changed, switch_state
+
+ def _i2c_rdwr(self, data, length=0):
+ '''Write and optionally read I2C data.'''
+ if not self._i2c_bus.try_lock():
+ return
+
+ try:
+ if length > 0:
+ result = bytearray(length)
+ self._i2c_bus.writeto_then_readfrom(
+ self._i2c_address, bytes(data), result
+ )
+ return list(result)
+ else:
+ self._i2c_bus.writeto(self._i2c_address, bytes(data))
+
+ return []
+
+ finally:
+ self._i2c_bus.unlock()
+
+ def _tb_handler_press(self, key, keyboard, *args, **kwargs):
+ self.activate_handler(key.handler)
+
+ def _tb_handler_next_press(self, key, keyboard, *args, **kwargs):
+ self.next_handler()
+
+ def _calculate_movement(self, raw_x, raw_y):
+ '''Calculate accelerated movement vector from raw data'''
+ if raw_x == 0 and raw_y == 0:
+ return 0, 0
+
+ scale = math.sqrt(raw_x**2 + raw_y**2)
+ x = (self.rot[0][0] * raw_x + self.rot[0][1] * raw_y) * scale
+ y = (self.rot[1][0] * raw_x + self.rot[1][1] * raw_y) * scale
+
+ return int(x), int(y)
+
+
+class TrackballPixel(PixelBuf):
+ '''PixelBuf interface for the Trackball RGBW LED'''
+
+ def __init__(self, trackball, **kwargs):
+ self.trackball = trackball
+ kwargs['byteorder'] = 'RGBW'
+ super().__init__(1, **kwargs)
+
+ def deinit(self):
+ self.trackball.set_rgbw(0, 0, 0, 0)
+
+ def _transmit(self, b):
+ self.trackball.set_rgbw(b[0], b[1], b[2], b[3])
diff --git a/hackpads/blipyboard/firmware/kmk/modules/potentiometer.py b/hackpads/blipyboard/firmware/kmk/modules/potentiometer.py
new file mode 100644
index 0000000000..03a3dc774f
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/potentiometer.py
@@ -0,0 +1,94 @@
+from analogio import AnalogIn
+from supervisor import ticks_ms
+
+from kmk.modules import Module
+
+
+class PotentiometerState:
+ def __init__(self, direction: int, position: int):
+ self.direction = direction
+ self.position = position
+
+
+class Potentiometer:
+ def __init__(self, pin, move_callback, is_inverted=False):
+ self.is_inverted = is_inverted
+ self.read_pin = AnalogIn(pin)
+ self._direction = None
+ self._pos = self.get_pos()
+ self._timestamp = ticks_ms()
+ self.cb = move_callback
+
+ # callback function on events.
+ self.on_move_do = lambda state: self.cb(state)
+
+ def get_state(self) -> PotentiometerState:
+ return PotentiometerState(
+ direction=(self.is_inverted and -self._direction or self._direction),
+ position=(self.is_inverted and -self._pos or self._pos),
+ )
+
+ def get_pos(self):
+ '''
+ Read from the analog pin assingned, truncate to 7 bits,
+ average over 10 readings, and return a value 0-127
+ '''
+ return int(sum([(self.read_pin.value >> 9) for i in range(10)]) / 10)
+
+ def update_state(self):
+ self._direction = 0
+ new_pos = self.get_pos()
+ if abs(new_pos - self._pos) > 2:
+ # movement detected!
+ if new_pos > self._pos:
+ self._direction = 1
+ else:
+ self._direction = -1
+ self._pos = new_pos
+ if self.on_move_do is not None:
+ self.on_move_do(self.get_state())
+
+
+class PotentiometerHandler(Module):
+ def __init__(self):
+ self.potentiometers = []
+ self.pins = None
+
+ def on_runtime_enable(self, keyboard):
+ return
+
+ def on_runtime_disable(self, keyboard):
+ return
+
+ def during_bootup(self, keyboard):
+ if self.pins:
+ for args in self.pins:
+ self.potentiometers.append(Potentiometer(*args))
+ return
+
+ def before_matrix_scan(self, keyboard):
+ '''
+ Return value will be injected as an extra matrix update
+ '''
+ for potentiometer in self.potentiometers:
+ potentiometer.update_state()
+
+ return keyboard
+
+ def after_matrix_scan(self, keyboard):
+ '''
+ Return value will be replace matrix update if supplied
+ '''
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/modules/power.py b/hackpads/blipyboard/firmware/kmk/modules/power.py
new file mode 100644
index 0000000000..07eca21c55
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/power.py
@@ -0,0 +1,143 @@
+import board
+import digitalio
+from supervisor import ticks_ms
+
+from time import sleep
+
+from kmk.keys import make_key
+from kmk.kmktime import check_deadline
+from kmk.modules import Module
+
+
+class Power(Module):
+ def __init__(self, powersave_pin=None):
+ self.enable = False
+ self.powersave_pin = powersave_pin # Powersave pin board object
+ self._powersave_start = ticks_ms()
+ self._usb_last_scan = ticks_ms() - 5000
+ self._psp = None # Powersave pin object
+ self._i2c = 0
+ self._i2c_deinit_count = 0
+ self._loopcounter = 0
+
+ make_key(names=('PS_TOG',), on_press=self._ps_tog)
+ make_key(names=('PS_ON',), on_press=self._ps_enable)
+ make_key(names=('PS_OFF',), on_press=self._ps_disable)
+
+ def __repr__(self):
+ return f'Power({self._to_dict()})'
+
+ def _to_dict(self):
+ return {
+ 'enable': self.enable,
+ 'powersave_pin': self.powersave_pin,
+ '_powersave_start': self._powersave_start,
+ '_usb_last_scan': self._usb_last_scan,
+ '_psp': self._psp,
+ }
+
+ def during_bootup(self, keyboard):
+ self._i2c_scan()
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ if keyboard.matrix_update or keyboard.secondary_matrix_update:
+ self.psave_time_reset()
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ if self.enable:
+ self.psleep()
+
+ def on_powersave_enable(self, keyboard):
+ '''Gives 10 cycles to allow other extensions to clean up before powersave'''
+ if self._loopcounter > 10:
+ self.enable_powersave(keyboard)
+ self._loopcounter = 0
+ else:
+ self._loopcounter += 1
+ return
+
+ def on_powersave_disable(self, keyboard):
+ self.disable_powersave(keyboard)
+ return
+
+ def enable_powersave(self, keyboard):
+ '''Enables power saving features'''
+ if self._i2c_deinit_count >= self._i2c and self.powersave_pin:
+ # Allows power save to prevent RGB drain.
+ # Example here https://docs.nicekeyboards.com/#/nice!nano/pinout_schematic
+
+ if not self._psp:
+ self._psp = digitalio.DigitalInOut(self.powersave_pin)
+ self._psp.direction = digitalio.Direction.OUTPUT
+ if self._psp:
+ self._psp.value = True
+
+ self.enable = True
+ keyboard._trigger_powersave_enable = False
+ return
+
+ def disable_powersave(self, keyboard):
+ '''Disables power saving features'''
+ if self._psp:
+ self._psp.value = False
+ # Allows power save to prevent RGB drain.
+ # Example here https://docs.nicekeyboards.com/#/nice!nano/pinout_schematic
+
+ keyboard._trigger_powersave_disable = False
+ self.enable = False
+ return
+
+ def psleep(self):
+ '''
+ Sleeps longer and longer to save power the more time in between updates.
+ '''
+ if check_deadline(ticks_ms(), self._powersave_start, 60000):
+ sleep(8 / 1000)
+ elif check_deadline(ticks_ms(), self._powersave_start, 240000) is False:
+ sleep(180 / 1000)
+ return
+
+ def psave_time_reset(self):
+ self._powersave_start = ticks_ms()
+
+ def _i2c_scan(self):
+ i2c = board.I2C()
+ while not i2c.try_lock():
+ pass
+ try:
+ self._i2c = len(i2c.scan())
+ finally:
+ i2c.unlock()
+ return
+
+ def usb_rescan_timer(self):
+ return bool(check_deadline(ticks_ms(), self._usb_last_scan, 5000) is False)
+
+ def usb_time_reset(self):
+ self._usb_last_scan = ticks_ms()
+ return
+
+ def usb_scan(self):
+ # TODO Add USB detection here. Currently lies that it's connected
+ # https://github.com/adafruit/circuitpython/pull/3513
+ return True
+
+ def _ps_tog(self, key, keyboard, *args, **kwargs):
+ if self.enable:
+ keyboard._trigger_powersave_disable = True
+ else:
+ keyboard._trigger_powersave_enable = True
+
+ def _ps_enable(self, key, keyboard, *args, **kwargs):
+ if not self.enable:
+ keyboard._trigger_powersave_enable = True
+
+ def _ps_disable(self, key, keyboard, *args, **kwargs):
+ if self.enable:
+ keyboard._trigger_powersave_disable = True
diff --git a/hackpads/blipyboard/firmware/kmk/modules/rapidfire.py b/hackpads/blipyboard/firmware/kmk/modules/rapidfire.py
new file mode 100644
index 0000000000..99c7662935
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/rapidfire.py
@@ -0,0 +1,118 @@
+from micropython import const
+
+from random import randint
+
+from kmk.keys import Key, make_argumented_key
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+_INACTIVE = const(0)
+_HOLD = const(1)
+_ACTIVE = const(2)
+
+
+class RapidFireKey(Key):
+ def __init__(
+ self,
+ key,
+ interval=100,
+ timeout=200,
+ enable_interval_randomization=False,
+ randomization_magnitude=15,
+ toggle=False,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.key = key
+ self.interval = interval
+ self.timeout = timeout
+ self.enable_interval_randomization = enable_interval_randomization
+ self.randomization_magnitude = randomization_magnitude
+ self.toggle = toggle
+ self._state = _INACTIVE
+ self._timeout = None
+
+
+class RapidFire(Module):
+ def __init__(self):
+ make_argumented_key(
+ names=('RF',),
+ constructor=RapidFireKey,
+ on_press=self._rf_pressed,
+ on_release=self._rf_released,
+ )
+
+ def _on_timer_timeout(self, key, keyboard):
+ if key._state == _HOLD:
+ key._state = _ACTIVE
+ keyboard.remove_key(key.key)
+ key._timeout = keyboard.set_timeout(
+ 1, lambda: self._on_timer_timeout(key, keyboard)
+ )
+ return
+
+ keyboard.add_key(key.key)
+ keyboard.set_timeout(1, lambda: keyboard.remove_key(key.key))
+
+ interval = key.interval
+ if key.enable_interval_randomization:
+ interval += randint(
+ -key.randomization_magnitude, key.randomization_magnitude
+ )
+ key._timeout = keyboard.set_timeout(
+ interval, lambda: self._on_timer_timeout(key, keyboard)
+ )
+
+ if debug.enabled:
+ debug(key.key, ' @', interval, 'ms')
+
+ def _rf_pressed(self, key, keyboard, *args, **kwargs):
+ if key._state == _ACTIVE:
+ self._deactivate_key(key, keyboard)
+ return
+
+ keyboard.add_key(key.key)
+ key._state = _HOLD
+ key._timeout = keyboard.set_timeout(
+ key.timeout, lambda: self._on_timer_timeout(key, keyboard)
+ )
+
+ def _rf_released(self, key, keyboard, *args, **kwargs):
+ if key._state == _ACTIVE:
+ if key.toggle:
+ return
+ key._state = _INACTIVE
+ elif key._state == _INACTIVE:
+ return
+ else:
+ keyboard.remove_key(key.key)
+
+ self._deactivate_key(key, keyboard)
+
+ def _deactivate_key(self, key, keyboard):
+ keyboard.cancel_timeout(key._timeout)
+ key._state = _INACTIVE
+ key._timeout = None
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/modules/serialace.py b/hackpads/blipyboard/firmware/kmk/modules/serialace.py
new file mode 100644
index 0000000000..c030377443
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/serialace.py
@@ -0,0 +1,63 @@
+from usb_cdc import data
+
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class SerialACE(Module):
+ buffer = bytearray()
+
+ def during_bootup(self, keyboard):
+ try:
+ data.timeout = 0
+ except AttributeError:
+ pass
+
+ def before_matrix_scan(self, keyboard):
+ pass
+
+ def after_matrix_scan(self, keyboard):
+ pass
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ return key
+
+ def before_hid_send(self, keyboard):
+ # Serial.data isn't initialized.
+ if not data:
+ return
+
+ # Nothing to parse.
+ if data.in_waiting == 0:
+ return
+
+ self.buffer.extend(data.read())
+ idx = self.buffer.find(b'\n')
+
+ # No full command yet.
+ if idx == -1:
+ return
+
+ # Split off command and evaluate.
+ line = self.buffer[:idx]
+ self.buffer = self.buffer[idx + 1 :] # noqa: E203
+
+ try:
+ if debug.enabled:
+ debug(f'eval({line})')
+ ret = eval(line, {'keyboard': keyboard})
+ data.write(bytearray(str(ret) + '\n'))
+ except Exception as err:
+ if debug.enabled:
+ debug(f'error: {err}')
+
+ def after_hid_send(self, keyboard):
+ pass
+
+ def on_powersave_enable(self, keyboard):
+ pass
+
+ def on_powersave_disable(self, keyboard):
+ pass
diff --git a/hackpads/blipyboard/firmware/kmk/modules/spacemouse_keys.py b/hackpads/blipyboard/firmware/kmk/modules/spacemouse_keys.py
new file mode 100644
index 0000000000..6984b45eca
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/spacemouse_keys.py
@@ -0,0 +1,131 @@
+from micropython import const
+
+from kmk.keys import SM, Key, SpacemouseKey, make_key
+from kmk.modules import Module
+from kmk.scheduler import cancel_task, create_task
+
+_XI = const(0x001)
+_YI = const(0x002)
+_ZI = const(0x004)
+_AI = const(0x008)
+_BI = const(0x010)
+_CI = const(0x020)
+_XD = const(0x040)
+_YD = const(0x080)
+_ZD = const(0x100)
+_AD = const(0x200)
+_BD = const(0x400)
+_CD = const(0x800)
+
+
+class SpacemouseDirectionKey(Key):
+ def __init__(self, code, **kwargs):
+ super().__init__(**kwargs)
+ self.code = code
+
+ def __repr__(self):
+ return super().__repr__() + f'(code=0x{self.code:03X})'
+
+
+class SpacemouseKeys(Module):
+ def __init__(self, max_speed=450, accel=10, timestep_ms=15):
+ self.max_speed = max_speed
+ self.accel = accel
+ self.timestep_ms = timestep_ms
+ self._movement = 0
+ self._move_step = 0
+
+ codes = (
+ (0x01, ('SM_LB', 'SM_LEFT')),
+ (0x02, ('SM_RB', 'SM_RIGHT')),
+ )
+ for code, names in codes:
+ make_key(names=names, constructor=SpacemouseKey, code=code)
+
+ keys = (
+ ('SM_XI', 'SM_X_INCREASE'),
+ ('SM_YI', 'SM_Y_INCREASE'),
+ ('SM_ZI', 'SM_Z_INCREASE'),
+ ('SM_AI', 'SM_A_INCREASE'),
+ ('SM_BI', 'SM_B_INCREASE'),
+ ('SM_CI', 'SM_C_INCREASE'),
+ ('SM_XD', 'SM_X_DECREASE'),
+ ('SM_YD', 'SM_Y_DECREASE'),
+ ('SM_ZD', 'SM_Z_DECREASE'),
+ ('SM_AD', 'SM_A_DECREASE'),
+ ('SM_BD', 'SM_B_DECREASE'),
+ ('SM_CD', 'SM_C_DECREASE'),
+ )
+ for n, names in enumerate(keys):
+ make_key(
+ names=names,
+ constructor=SpacemouseDirectionKey,
+ on_press=self._on_press,
+ on_release=self._on_release,
+ code=1 << n,
+ )
+
+ def during_bootup(self, keyboard):
+ self._task = create_task(
+ lambda: self._move(keyboard),
+ period_ms=self.timestep_ms,
+ )
+ cancel_task(self._task)
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def _move(self, keyboard):
+ if self._movement:
+ if self._move_step < self.max_speed:
+ self._move_step = min(self._move_step + self.accel, self.max_speed)
+ if self._movement & _XI:
+ SM.X.move(keyboard, self._move_step)
+ if self._movement & _YI:
+ SM.Y.move(keyboard, self._move_step)
+ if self._movement & _ZI:
+ SM.Z.move(keyboard, self._move_step)
+ if self._movement & _AI:
+ SM.A.move(keyboard, self._move_step)
+ if self._movement & _BI:
+ SM.B.move(keyboard, self._move_step)
+ if self._movement & _CI:
+ SM.C.move(keyboard, self._move_step)
+ if self._movement & _XD:
+ SM.X.move(keyboard, -self._move_step)
+ if self._movement & _YD:
+ SM.Y.move(keyboard, -self._move_step)
+ if self._movement & _ZD:
+ SM.Z.move(keyboard, -self._move_step)
+ if self._movement & _AD:
+ SM.A.move(keyboard, -self._move_step)
+ if self._movement & _BD:
+ SM.B.move(keyboard, -self._move_step)
+ if self._movement & _CD:
+ SM.C.move(keyboard, -self._move_step)
+
+ def _on_press(self, key, keyboard, *args, **kwargs):
+ self._movement |= key.code
+ if self._movement == key.code:
+ self._task.restart()
+
+ def _on_release(self, key, keyboard, *args, **kwargs):
+ self._movement &= ~key.mask
+ if not self._movement:
+ cancel_task(self._task)
+ self._move_step = 0
diff --git a/hackpads/blipyboard/firmware/kmk/modules/split.py b/hackpads/blipyboard/firmware/kmk/modules/split.py
new file mode 100644
index 0000000000..a54b3e93f0
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/split.py
@@ -0,0 +1,391 @@
+'''Enables splitting keyboards wirelessly or wired'''
+
+import busio
+from micropython import const
+from supervisor import runtime, ticks_ms
+
+from keypad import Event as KeyEvent
+from storage import getmount
+
+from kmk.hid import HIDModes
+from kmk.kmktime import check_deadline
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+class SplitSide:
+ LEFT = const(1)
+ RIGHT = const(2)
+
+
+class SplitType:
+ UART = const(1)
+ I2C = const(2) # unused
+ ONEWIRE = const(3) # unused
+ BLE = const(4)
+
+
+class Split(Module):
+ '''Enables splitting keyboards wirelessly, or wired'''
+
+ def __init__(
+ self,
+ split_flip=True,
+ split_side=None,
+ split_type=SplitType.UART,
+ split_target_left=True,
+ uart_interval=20,
+ data_pin=None,
+ data_pin2=None,
+ uart_flip=True,
+ use_pio=False,
+ ):
+ self._is_target = True
+ self._uart_buffer = []
+ self.split_flip = split_flip
+ self.split_side = split_side
+ self.split_type = split_type
+ self.split_target_left = split_target_left
+ self.split_offset = None
+ self.data_pin = data_pin
+ self.data_pin2 = data_pin2
+ self.uart_flip = uart_flip
+ self._use_pio = use_pio
+ self._uart = None
+ self._uart_interval = uart_interval
+ self.uart_header = bytearray([0xB2]) # Any non-zero byte should work
+
+ if self.split_type == SplitType.BLE:
+ try:
+ from adafruit_ble import BLERadio
+ from adafruit_ble.advertising.standard import (
+ ProvideServicesAdvertisement,
+ )
+ from adafruit_ble.services.nordic import UARTService
+
+ self.BLERadio = BLERadio
+ self.ProvideServicesAdvertisement = ProvideServicesAdvertisement
+ self.UARTService = UARTService
+ except ImportError:
+ if debug.enabled:
+ debug('BLE Import error')
+ return # BLE isn't supported on this platform
+ self._ble_last_scan = ticks_ms() - 5000
+ self._connection_count = 0
+ self._split_connected = False
+ self._uart_connection = None
+ self._advertisment = None # Seems to not be used anywhere
+ self._advertising = False
+ self._psave_enable = False
+
+ if self._use_pio:
+ from kmk.transports.pio_uart import PIO_UART
+
+ self.PIO_UART = PIO_UART
+
+ def during_bootup(self, keyboard):
+ # Set up name for target side detection and BLE advertisment
+ name = str(getmount('/').label)
+ if self.split_type == SplitType.BLE:
+ if keyboard.hid_type == HIDModes.BLE:
+ self._ble = keyboard._hid_helper.ble
+ else:
+ self._ble = self.BLERadio()
+ self._ble.name = name
+ else:
+ # Try to guess data pins if not supplied
+ if not self.data_pin:
+ self.data_pin = keyboard.data_pin
+
+ # if split side was given, find target from split_side.
+ if self.split_side == SplitSide.LEFT:
+ self._is_target = bool(self.split_target_left)
+ elif self.split_side == SplitSide.RIGHT:
+ self._is_target = not bool(self.split_target_left)
+ else:
+ # Detect split side from name
+ if (
+ self.split_type == SplitType.UART
+ or self.split_type == SplitType.ONEWIRE
+ ):
+ self._is_target = runtime.usb_connected
+ elif self.split_type == SplitType.BLE:
+ self._is_target = name.endswith('L') == self.split_target_left
+
+ if name.endswith('L'):
+ self.split_side = SplitSide.LEFT
+ elif name.endswith('R'):
+ self.split_side = SplitSide.RIGHT
+
+ if not self._is_target:
+ keyboard._hid_send_enabled = False
+
+ if self.split_offset is None:
+ self.split_offset = keyboard.matrix[-1].coord_mapping[-1] + 1
+
+ if self.split_type == SplitType.UART and self.data_pin is not None:
+ if self._is_target or not self.uart_flip:
+ if self._use_pio:
+ self._uart = self.PIO_UART(tx=self.data_pin2, rx=self.data_pin)
+ else:
+ self._uart = busio.UART(
+ tx=self.data_pin2, rx=self.data_pin, timeout=self._uart_interval
+ )
+ else:
+ if self._use_pio:
+ self._uart = self.PIO_UART(tx=self.data_pin, rx=self.data_pin2)
+ else:
+ self._uart = busio.UART(
+ tx=self.data_pin, rx=self.data_pin2, timeout=self._uart_interval
+ )
+
+ # Attempt to sanely guess a coord_mapping if one is not provided.
+ if not keyboard.coord_mapping and keyboard.row_pins and keyboard.col_pins:
+ cm = []
+
+ rows_to_calc = len(keyboard.row_pins)
+ cols_to_calc = len(keyboard.col_pins)
+
+ # Flips the col order if PCB is the same but flipped on right
+ cols_rhs = list(range(cols_to_calc))
+ if self.split_flip:
+ cols_rhs = list(reversed(cols_rhs))
+
+ for ridx in range(rows_to_calc):
+ for cidx in range(cols_to_calc):
+ cm.append(cols_to_calc * ridx + cidx)
+ for cidx in cols_rhs:
+ cm.append(cols_to_calc * (rows_to_calc + ridx) + cidx)
+
+ keyboard.coord_mapping = tuple(cm)
+
+ if not keyboard.coord_mapping and debug.enabled:
+ debug('Error: please provide coord_mapping for custom scanner')
+
+ if self.split_side == SplitSide.RIGHT:
+ offset = self.split_offset
+ for matrix in keyboard.matrix:
+ matrix.offset = offset
+ offset += matrix.key_count
+
+ def before_matrix_scan(self, keyboard):
+ if self.split_type == SplitType.BLE:
+ self._check_all_connections(keyboard)
+ self._receive_ble(keyboard)
+ elif self.split_type == SplitType.UART:
+ if self._is_target or self.data_pin2:
+ self._receive_uart(keyboard)
+ elif self.split_type == SplitType.ONEWIRE:
+ pass # Protocol needs written
+ return
+
+ def after_matrix_scan(self, keyboard):
+ if keyboard.matrix_update:
+ if self.split_type == SplitType.UART:
+ if not self._is_target or self.data_pin2:
+ self._send_uart(keyboard.matrix_update)
+ else:
+ pass # explicit pass just for dev sanity...
+ elif self.split_type == SplitType.BLE:
+ self._send_ble(keyboard.matrix_update)
+ elif self.split_type == SplitType.ONEWIRE:
+ pass # Protocol needs written
+ else:
+ if debug.enabled:
+ debug('Unexpected case in after_matrix_scan')
+
+ return
+
+ def before_hid_send(self, keyboard):
+ if not self._is_target:
+ keyboard.hid_pending = False
+
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ if self.split_type == SplitType.BLE:
+ if self._uart_connection and not self._psave_enable:
+ self._uart_connection.connection_interval = self._uart_interval
+ self._psave_enable = True
+
+ def on_powersave_disable(self, keyboard):
+ if self.split_type == SplitType.BLE:
+ if self._uart_connection and self._psave_enable:
+ self._uart_connection.connection_interval = 11.25
+ self._psave_enable = False
+
+ def _check_all_connections(self, keyboard):
+ '''Validates the correct number of BLE connections'''
+ self._previous_connection_count = self._connection_count
+ self._connection_count = len(self._ble.connections)
+ if self._is_target:
+ if self._advertising or not self._check_if_split_connected():
+ self._target_advertise()
+ elif self._connection_count < 2 and keyboard.hid_type == HIDModes.BLE:
+ keyboard._hid_helper.start_advertising()
+
+ elif not self._is_target and self._connection_count < 1:
+ self._initiator_scan()
+
+ def _check_if_split_connected(self):
+ # I'm looking for a way how to recognize which connection is on and which one off
+ # For now, I found that service name relation to having other CP device
+ if self._connection_count == 0:
+ return False
+ if self._connection_count == 2:
+ self._split_connected = True
+ return True
+
+ # Polling this takes some time so I check only if connection_count changed
+ if self._previous_connection_count == self._connection_count:
+ return self._split_connected
+
+ bleio_connection = self._ble.connections[0]._bleio_connection
+ connection_services = bleio_connection.discover_remote_services()
+ for service in connection_services:
+ if str(service.uuid).startswith("UUID('adaf0001"):
+ self._split_connected = True
+ return True
+ return False
+
+ def _initiator_scan(self):
+ '''Scans for target device'''
+ self._uart = None
+ self._uart_connection = None
+ # See if any existing connections are providing UARTService.
+ self._connection_count = len(self._ble.connections)
+ if self._connection_count > 0 and not self._uart:
+ for connection in self._ble.connections:
+ if self.UARTService in connection:
+ self._uart_connection = connection
+ self._uart_connection.connection_interval = 11.25
+ self._uart = self._uart_connection[self.UARTService]
+ break
+
+ if not self._uart:
+ if debug.enabled:
+ debug('Scanning')
+ self._ble.stop_scan()
+ for adv in self._ble.start_scan(
+ self.ProvideServicesAdvertisement, timeout=20
+ ):
+ if debug.enabled:
+ debug('Scanning')
+ if self.UARTService in adv.services and adv.rssi > -70:
+ self._uart_connection = self._ble.connect(adv)
+ self._uart_connection.connection_interval = 11.25
+ self._uart = self._uart_connection[self.UARTService]
+ self._ble.stop_scan()
+ if debug.enabled:
+ debug('Scan complete')
+ break
+ self._ble.stop_scan()
+
+ def _target_advertise(self):
+ '''Advertises the target for the initiator to find'''
+ # Give previous advertising some time to complete
+ if self._advertising:
+ if self._check_if_split_connected():
+ if debug.enabled:
+ debug('Advertising complete')
+ self._ble.stop_advertising()
+ self._advertising = False
+ return
+
+ if not self.ble_rescan_timer():
+ return
+
+ if debug.enabled:
+ debug('Advertising not answered')
+
+ self._ble.stop_advertising()
+ if debug.enabled:
+ debug('Advertising')
+ # Uart must not change on this connection if reconnecting
+ if not self._uart:
+ self._uart = self.UARTService()
+ advertisement = self.ProvideServicesAdvertisement(self._uart)
+
+ self._ble.start_advertising(advertisement)
+ self._advertising = True
+ self.ble_time_reset()
+
+ def ble_rescan_timer(self):
+ '''If true, the rescan timer is up'''
+ return not bool(check_deadline(ticks_ms(), self._ble_last_scan, 5000))
+
+ def ble_time_reset(self):
+ '''Resets the rescan timer'''
+ self._ble_last_scan = ticks_ms()
+
+ def _serialize_update(self, update):
+ buffer = bytearray(2)
+ buffer[0] = update.key_number
+ buffer[1] = update.pressed
+ return buffer
+
+ def _deserialize_update(self, update):
+ kevent = KeyEvent(key_number=update[0], pressed=update[1])
+ return kevent
+
+ def _send_ble(self, update):
+ if self._uart:
+ try:
+ self._uart.write(self._serialize_update(update))
+ except OSError:
+ try:
+ self._uart.disconnect()
+ except: # noqa: E722
+ if debug.enabled:
+ debug('UART disconnect failed')
+
+ if debug.enabled:
+ debug('Connection error')
+ self._uart_connection = None
+ self._uart = None
+
+ def _receive_ble(self, keyboard):
+ if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
+ while self._uart.in_waiting >= 2:
+ update = self._deserialize_update(self._uart.read(2))
+ self._uart_buffer.append(update)
+ if self._uart_buffer:
+ keyboard.secondary_matrix_update = self._uart_buffer.pop(0)
+
+ def _checksum(self, update):
+ checksum = bytes([sum(update) & 0xFF])
+
+ return checksum
+
+ def _send_uart(self, update):
+ # Change offsets depending on where the data is going to match the correct
+ # matrix location of the receiever
+ if self._uart is not None:
+ update = self._serialize_update(update)
+ self._uart.write(self.uart_header)
+ self._uart.write(update)
+ self._uart.write(self._checksum(update))
+
+ def _receive_uart(self, keyboard):
+ if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
+ if self._uart.in_waiting >= 60:
+ # This is a dirty hack to prevent crashes in unrealistic cases
+ import microcontroller
+
+ microcontroller.reset()
+
+ while self._uart.in_waiting >= 4:
+ # Check the header
+ if self._uart.read(1) == self.uart_header:
+ update = self._uart.read(2)
+
+ # check the checksum
+ if self._checksum(update) == self._uart.read(1):
+ self._uart_buffer.append(self._deserialize_update(update))
+ if self._uart_buffer:
+ keyboard.secondary_matrix_update = self._uart_buffer.pop(0)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/steno.py b/hackpads/blipyboard/firmware/kmk/modules/steno.py
new file mode 100644
index 0000000000..bd93da2e12
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/steno.py
@@ -0,0 +1,107 @@
+import usb_cdc
+
+from kmk.keys import make_key
+from kmk.modules import Module
+
+# key order from https://github.com/openstenoproject/plover/blob/main/plover/machine/geminipr.py
+# do not rearrange
+STENO_KEYS = (
+ 'STN_FN',
+ 'STN_N1',
+ 'STN_N2',
+ 'STN_N3',
+ 'STN_N4',
+ 'STN_N5',
+ 'STN_N6',
+ 'STN_LS1',
+ 'STN_LS2',
+ 'STN_LT',
+ 'STN_LK',
+ 'STN_LP',
+ 'STN_LW',
+ 'STN_LH',
+ 'STN_LR',
+ 'STN_A',
+ 'STN_O',
+ 'STN_AS1',
+ 'STN_AS2',
+ 'STN_RES1',
+ 'STN_RES2',
+ 'STN_PWR',
+ 'STN_AS3',
+ 'STN_AS4',
+ 'STN_E',
+ 'STN_U',
+ 'STN_RF',
+ 'STN_RR',
+ 'STN_RP',
+ 'STN_RB',
+ 'STN_RL',
+ 'STN_RG',
+ 'STN_RT',
+ 'STN_RS',
+ 'STN_RD',
+ 'STN_N7',
+ 'STN_N8',
+ 'STN_N9',
+ 'STN_NA',
+ 'STN_NB',
+ 'STN_NC',
+ 'STN_RZ',
+)
+
+
+class Steno(Module):
+ def __init__(self):
+ self._should_write = False
+
+ self._buffer = bytearray(6)
+ self._initialize_buffer()
+
+ for idx, key in enumerate(STENO_KEYS):
+ make_key(
+ code=((idx // 7) << 8) | (0x40 >> (idx % 7)),
+ names=(key,),
+ on_press=self._steno_press,
+ on_release=self._steno_release,
+ )
+
+ def _initialize_buffer(self):
+ self._buffer[:] = b'\x80\x00\x00\x00\x00\x00'
+
+ # flip a key's bit in the buffer
+ def _steno_press(self, key, *_):
+ self._should_write = True
+ self._buffer[key.code >> 8] |= key.code & 0xFF
+
+ # send all keys that were pressed, and reset the buffer
+ def _steno_release(self, *_):
+ if self._should_write:
+ usb_cdc.data.write(self._buffer)
+
+ self._should_write = False
+ self._initialize_buffer()
+
+ def during_bootup(self, keyboard):
+ pass
+
+ def before_matrix_scan(self, keyboard):
+ pass
+
+ def after_matrix_scan(self, keyboard):
+ pass
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ return key
+
+ def before_hid_send(self, keyboard):
+ pass
+
+ def after_hid_send(self, keyboard):
+ pass
+
+ def on_powersave_enable(self, keyboard):
+ pass
+
+ def on_powersave_disable(self, keyboard):
+ pass
diff --git a/hackpads/blipyboard/firmware/kmk/modules/sticky_keys.py b/hackpads/blipyboard/firmware/kmk/modules/sticky_keys.py
new file mode 100644
index 0000000000..a7ea848b3a
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/sticky_keys.py
@@ -0,0 +1,151 @@
+from micropython import const
+
+from kmk.keys import Key, make_argumented_key
+from kmk.modules import Module
+from kmk.utils import Debug
+
+debug = Debug(__name__)
+
+
+_SK_IDLE = const(0)
+_SK_PRESSED = const(1)
+_SK_RELEASED = const(2)
+_SK_HOLD = const(3)
+_SK_STICKY = const(4)
+
+
+class StickyKey(Key):
+ def __init__(self, key, defer_release=False, retap_cancel=True, **kwargs):
+ super().__init__(**kwargs)
+ self.key = key
+ self.defer_release = defer_release
+ self.timeout = None
+ self.state = _SK_IDLE
+ self.retap_cancel = retap_cancel
+
+
+class StickyKeys(Module):
+ def __init__(self, release_after=1000):
+ self.active_keys = []
+ self.release_after = release_after
+
+ make_argumented_key(
+ names=('SK', 'STICKY'),
+ constructor=StickyKey,
+ on_press=self.on_press,
+ on_release=self.on_release,
+ )
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def process_key(self, keyboard, current_key, is_pressed, int_coord):
+ delay_current = False
+
+ for key in self.active_keys.copy():
+ # Ignore keys that will resolve to and emit a different key
+ # eventually, potentially triggering twice.
+ # Handle interactions among sticky keys (stacking) in `on_press`
+ # instead of `process_key` to avoid race conditions / causal
+ # reordering when resetting timeouts.
+ if (
+ isinstance(current_key, StickyKey)
+ or current_key.__class__.__name__ == 'TapDanceKey'
+ or current_key.__class__.__name__ == 'HoldTapKey'
+ or current_key.__class__.__name__ == 'LayerTapKeyMeta'
+ ):
+ continue
+
+ if key.state == _SK_PRESSED and is_pressed:
+ key.state = _SK_HOLD
+ elif key.state == _SK_RELEASED and is_pressed:
+ key.state = _SK_STICKY
+ elif key.state == _SK_STICKY:
+ # Defer sticky release until last other key is released.
+ if key.defer_release:
+ if not is_pressed and len(keyboard._coordkeys_pressed) == 0:
+ self.deactivate(keyboard, key)
+ # Release sticky key; if it's a new key pressed: delay
+ # propagation until after the sticky release.
+ else:
+ self.deactivate(keyboard, key)
+ delay_current = is_pressed
+
+ if delay_current:
+ keyboard.resume_process_key(self, current_key, is_pressed, int_coord, False)
+ else:
+ return current_key
+
+ def set_timeout(self, keyboard, key):
+ key.timeout = keyboard.set_timeout(
+ self.release_after,
+ lambda: self.on_release_after(keyboard, key),
+ )
+
+ def on_press(self, key, keyboard, *args, **kwargs):
+ # Let sticky keys stack while renewing timeouts.
+ for sk in self.active_keys:
+ keyboard.cancel_timeout(sk.timeout)
+
+ # If active sticky key is tapped again, cancel.
+ if key.retap_cancel and (key.state == _SK_RELEASED or key.state == _SK_STICKY):
+ self.deactivate(keyboard, key)
+ # Reset on repeated taps.
+ elif key.state != _SK_IDLE:
+ key.state = _SK_PRESSED
+ else:
+ self.activate(keyboard, key)
+
+ for sk in self.active_keys:
+ self.set_timeout(keyboard, sk)
+
+ def on_release(self, key, keyboard, *args, **kwargs):
+ # No interrupt or timeout happend, mark key as RELEASED, ready to get
+ # STICKY.
+ if key.state == _SK_PRESSED:
+ key.state = _SK_RELEASED
+ # Key in HOLD state is handled like a regular release.
+ elif key.state == _SK_HOLD:
+ keyboard.cancel_timeout(key.timeout)
+ self.deactivate(keyboard, key)
+
+ def on_release_after(self, keyboard, key):
+ # Key is still pressed but nothing else happend: set to HOLD.
+ if key.state == _SK_PRESSED:
+ key.state = _SK_HOLD
+ keyboard.cancel_timeout(key.timeout)
+ # Key got released but nothing else happend: deactivate.
+ elif key.state == _SK_RELEASED:
+ self.deactivate(keyboard, key)
+
+ def activate(self, keyboard, key):
+ if debug.enabled:
+ debug('activate')
+ key.state = _SK_PRESSED
+ self.active_keys.insert(0, key)
+ keyboard.resume_process_key(self, key.key, True)
+
+ def deactivate(self, keyboard, key):
+ if debug.enabled:
+ debug('deactivate')
+ key.state = _SK_IDLE
+ self.active_keys.remove(key)
+ keyboard.resume_process_key(self, key.key, False)
diff --git a/hackpads/blipyboard/firmware/kmk/modules/sticky_mod.py b/hackpads/blipyboard/firmware/kmk/modules/sticky_mod.py
new file mode 100644
index 0000000000..0896b14fdb
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/sticky_mod.py
@@ -0,0 +1,64 @@
+from kmk.keys import Key, make_argumented_key
+from kmk.modules import Module
+
+
+class StickyModKey(Key):
+ def __init__(self, key, mod, **kwargs):
+ super().__init__(**kwargs)
+ self.key = key
+ self.mod = mod
+
+
+class StickyMod(Module):
+ def __init__(self):
+ self._active = False
+ self._active_key = None
+ make_argumented_key(
+ names=('SM',),
+ constructor=StickyModKey,
+ on_press=self.sm_pressed,
+ on_release=self.sm_released,
+ )
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ # release previous key if any other key is pressed
+ if self._active and self._active_key is not None:
+ self.release_key(keyboard, self._active_key)
+
+ return key
+
+ def before_hid_send(self, keyboard):
+ return
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
+
+ def release_key(self, keyboard, key):
+ keyboard.process_key(key.mod, False)
+ self._active = False
+ self._active_key = None
+
+ def sm_pressed(self, key, keyboard, *args, **kwargs):
+ keyboard.process_key(key.mod, True)
+ keyboard.process_key(key.key, True)
+ self._active_key = key
+
+ def sm_released(self, key, keyboard, *args, **kwargs):
+ keyboard.process_key(key.key, False)
+ self._active_key = key
+ self._active = True
diff --git a/hackpads/blipyboard/firmware/kmk/modules/string_substitution.py b/hackpads/blipyboard/firmware/kmk/modules/string_substitution.py
new file mode 100644
index 0000000000..c5d2e35265
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/string_substitution.py
@@ -0,0 +1,229 @@
+try:
+ from typing import Optional
+except ImportError:
+ # we're not in a dev environment, so we don't need to worry about typing
+ pass
+from micropython import const
+
+from kmk.keys import KC, Key, ModifiedKey, ModifierKey
+from kmk.modules import Module
+
+
+class State:
+ LISTENING = const(0)
+ DELETING = const(1)
+ SENDING = const(2)
+ IGNORING = const(3)
+
+
+class Character:
+ '''Helper class for making a left-shifted key identical to a right-shifted key'''
+
+ is_shifted: bool = False
+
+ def __init__(self, key_code: Key, is_shifted: bool) -> None:
+ self.is_shifted = is_shifted
+ self.key_code = KC.LSHIFT(key_code) if is_shifted else key_code
+
+ def __eq__(self, other: any) -> bool: # type: ignore
+ try:
+ if isinstance(self.key_code, ModifiedKey):
+ return (
+ self.key_code.key.code == other.key_code.key.code
+ and self.is_shifted == other.is_shifted
+ )
+ return (
+ self.key_code.code == other.key_code.code
+ and self.is_shifted == other.is_shifted
+ )
+ except AttributeError:
+ return False
+
+
+class Phrase:
+ '''Manages a collection of characters and keeps an index of them so that potential matches can be tracked'''
+
+ def __init__(self, string: str) -> None:
+ self._characters: list[Character] = []
+ self._index: int = 0
+ for char in string:
+ key_code = KC[char]
+ if key_code == KC.NO:
+ raise ValueError(f'Invalid character in dictionary: {char}')
+ shifted = char.isupper() or (
+ isinstance(key_code, ModifiedKey) and key_code.modifier.code == 0x02
+ )
+ self._characters.append(Character(key_code, shifted))
+
+ def next_character(self) -> None:
+ '''Increment the current index for this phrase'''
+ if not self.index_at_end():
+ self._index += 1
+
+ def get_character_at_index(self, index: int) -> Character:
+ '''Returns the character at the given index'''
+ return self._characters[index]
+
+ def get_character_at_current_index(self) -> Character:
+ '''Returns the character at the current index for this phrase'''
+ return self._characters[self._index]
+
+ def reset_index(self) -> None:
+ '''Reset the index to the start of the phrase'''
+ self._index = 0
+
+ def index_at_end(self) -> bool:
+ '''Returns True if the index is at the end of the phrase'''
+ return self._index == len(self._characters)
+
+ def character_is_at_current_index(self, character) -> bool:
+ '''Returns True if the given character is the next character in the phrase'''
+ return self.get_character_at_current_index() == character
+
+
+class Rule:
+ '''Represents the relationship between a phrase to be substituted and its substitution'''
+
+ def __init__(self, to_substitute: Phrase, substitution: Phrase) -> None:
+ self.to_substitute: Phrase = to_substitute
+ self.substitution: Phrase = substitution
+
+ def restart(self) -> None:
+ '''Resets this rule's to_substitute and substitution phrases'''
+ self.to_substitute.reset_index()
+ self.substitution.reset_index()
+
+
+class StringSubstitution(Module):
+ _shifted: bool = False
+ _rules: list = []
+ _state: State = State.LISTENING
+ _matched_rule: Optional[Phrase] = None
+ _active_modifiers: list[ModifierKey] = []
+
+ def __init__(
+ self,
+ dictionary: dict,
+ ):
+ for key, value in dictionary.items():
+ self._rules.append(Rule(Phrase(key), Phrase(value)))
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ if key is KC.LSFT or key is KC.RSFT:
+ if is_pressed:
+ self._shifted = True
+ else:
+ self._shifted = False
+
+ # control ignoring state if the key is a non-shift modifier
+ elif type(key) is ModifierKey:
+ if is_pressed and key not in self._active_modifiers:
+ self._active_modifiers.append(key)
+ self._state = State.IGNORING
+ elif key in self._active_modifiers:
+ self._active_modifiers.remove(key)
+ if not self._active_modifiers:
+ self._state = State.LISTENING
+ # reset rules because pressing a modifier combination
+ # should interrupt any current matches
+ for rule in self._rules:
+ rule.restart()
+
+ if not self._state == State.LISTENING:
+ return key
+
+ if is_pressed:
+ character = Character(key, self._shifted)
+
+ # run through the dictionary to check for a possible match on each new keypress
+ for rule in self._rules:
+ if rule.to_substitute.character_is_at_current_index(character):
+ rule.to_substitute.next_character()
+ else:
+ rule.restart()
+ # if character is not a match at the current index,
+ # it could still be a match at the start of the sequence
+ # so redo the check after resetting the sequence
+ if rule.to_substitute.character_is_at_current_index(character):
+ rule.to_substitute.next_character()
+ # we've matched all of the characters in a phrase to be substituted
+ if rule.to_substitute.index_at_end():
+ rule.restart()
+ # set the phrase indexes to where they differ
+ # so that only the characters that differ are replaced
+ for character in rule.to_substitute._characters:
+ if (
+ character
+ == rule.substitution.get_character_at_current_index()
+ ):
+ rule.to_substitute.next_character()
+ rule.substitution.next_character()
+ else:
+ break
+ if rule.to_substitute.index_at_end():
+ break
+ self._matched_rule = rule
+ self._state = State.DELETING
+ # if we have a match there's no reason to continue the full key processing, so return out
+ return
+ return key
+
+ def during_bootup(self, keyboard):
+ return
+
+ def before_matrix_scan(self, keyboard):
+ return
+
+ def before_hid_send(self, keyboard):
+
+ if self._state == State.LISTENING:
+ return
+
+ if self._state == State.DELETING:
+ # force-release modifiers so sending the replacement text doesn't interact with them
+ # it should not be possible for any modifiers other than shift to be held upon rule activation
+ # as a modified key won't send a keycode that is matched against the user's dictionary,
+ # but, just in case, we'll release those too
+ modifiers_to_release = [
+ KC.LSFT,
+ KC.RSFT,
+ KC.LCTL,
+ KC.LGUI,
+ KC.LALT,
+ KC.RCTL,
+ KC.RGUI,
+ KC.RALT,
+ ]
+ for modifier in modifiers_to_release:
+ keyboard.remove_key(modifier)
+
+ # send backspace taps equivalent to the length of the phrase to be substituted
+ to_substitute: Phrase = self._matched_rule.to_substitute # type: ignore
+ to_substitute.next_character()
+ if not to_substitute.index_at_end():
+ keyboard.tap_key(KC.BSPC)
+ else:
+ self._state = State.SENDING
+
+ if self._state == State.SENDING:
+ substitution = self._matched_rule.substitution # type: ignore
+ if not substitution.index_at_end():
+ keyboard.tap_key(substitution.get_character_at_current_index().key_code)
+ substitution.next_character()
+ else:
+ self._state = State.LISTENING
+ self._matched_rule = None
+ for rule in self._rules:
+ rule.restart()
+
+ def after_hid_send(self, keyboard):
+ return
+
+ def on_powersave_enable(self, keyboard):
+ return
+
+ def on_powersave_disable(self, keyboard):
+ return
+
+ def after_matrix_scan(self, keyboard):
+ return
diff --git a/hackpads/blipyboard/firmware/kmk/modules/tapdance.py b/hackpads/blipyboard/firmware/kmk/modules/tapdance.py
new file mode 100644
index 0000000000..2b6cba6c55
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/modules/tapdance.py
@@ -0,0 +1,121 @@
+from kmk.keys import Key, make_argumented_key
+from kmk.modules.holdtap import ActivationType, HoldTap, HoldTapKey
+
+
+class TapDanceKey(Key):
+ def __init__(self, *keys, tap_time=None, **kwargs):
+ '''
+ Any key in the tapdance sequence that is not already a holdtap
+ key gets converted to a holdtap key with identical tap and hold
+ attributes.
+ '''
+ super().__init__(**kwargs)
+ self.tap_time = tap_time
+ self.keys = []
+
+ for key in keys:
+ if not isinstance(key, HoldTapKey):
+ ht_key = HoldTapKey(
+ tap=key,
+ hold=key,
+ prefer_hold=True,
+ tap_interrupted=False,
+ tap_time=self.tap_time,
+ )
+ self.keys.append(ht_key)
+ else:
+ self.keys.append(key)
+ self.keys = tuple(self.keys)
+
+
+class TapDance(HoldTap):
+ def __init__(self):
+ super().__init__(_make_key=False)
+ make_argumented_key(
+ names=('TD',),
+ constructor=TapDanceKey,
+ on_press=self.td_pressed,
+ on_release=self.td_released,
+ )
+
+ self.td_counts = {}
+
+ def process_key(self, keyboard, key, is_pressed, int_coord):
+ if isinstance(key, TapDanceKey):
+ if key in self.td_counts:
+ return key
+
+ for _key, state in self.key_states.copy().items():
+ if state.activated == ActivationType.RELEASED:
+ keyboard.cancel_timeout(state.timeout_key)
+ self.ht_activate_tap(_key, keyboard)
+ self.send_key_buffer(keyboard)
+ self.ht_deactivate_tap(_key, keyboard)
+ keyboard.resume_process_key(self, key, is_pressed, int_coord)
+ key = None
+
+ del self.key_states[_key]
+ del self.td_counts[state.tap_dance]
+
+ if key:
+ key = super().process_key(keyboard, key, is_pressed, int_coord)
+
+ return key
+
+ def td_pressed(self, key, keyboard, *args, **kwargs):
+ # active tap dance
+ if key in self.td_counts:
+ count = self.td_counts[key]
+ kc = key.keys[count]
+ keyboard.cancel_timeout(self.key_states[kc].timeout_key)
+
+ count += 1
+
+ # Tap dance reached the end of the list: send last tap in sequence
+ # and start from the beginning.
+ if count >= len(key.keys):
+ self.key_states[kc].activated = ActivationType.RELEASED
+ self.on_tap_time_expired(kc, keyboard)
+ count = 0
+ else:
+ del self.key_states[kc]
+
+ # new tap dance
+ else:
+ count = 0
+
+ current_key = key.keys[count]
+
+ self.ht_pressed(current_key, keyboard, *args, **kwargs)
+ self.td_counts[key] = count
+
+ # Add the active tap dance to key_states; `on_tap_time_expired` needs
+ # the back-reference.
+ self.key_states[current_key].tap_dance = key
+
+ def td_released(self, key, keyboard, *args, **kwargs):
+ kc = key.keys[self.td_counts[key]]
+ state = self.key_states[kc]
+ if state.activated == ActivationType.HOLD_TIMEOUT:
+ # release hold
+ self.ht_deactivate_hold(kc, keyboard, *args, **kwargs)
+ del self.key_states[kc]
+ del self.td_counts[key]
+ elif state.activated == ActivationType.INTERRUPTED:
+ # release tap
+ self.ht_deactivate_on_interrupt(kc, keyboard, *args, **kwargs)
+ del self.key_states[kc]
+ del self.td_counts[key]
+ else:
+ # keep counting
+ state.activated = ActivationType.RELEASED
+
+ def on_tap_time_expired(self, key, keyboard, *args, **kwargs):
+ # Note: the `key` argument is the current holdtap key in the sequence,
+ # not the tapdance key.
+ state = self.key_states[key]
+ if state.activated == ActivationType.RELEASED:
+ self.ht_activate_tap(key, keyboard, *args, **kwargs)
+ self.send_key_buffer(keyboard)
+ del self.td_counts[state.tap_dance]
+ super().on_tap_time_expired(key, keyboard, *args, **kwargs)
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/avr_promicro.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/avr_promicro.py
new file mode 100644
index 0000000000..e8396b6a91
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/avr_promicro.py
@@ -0,0 +1,20 @@
+translate = {
+ 'D3': 0,
+ 'D2': 1,
+ 'D1': 4,
+ 'D0': 5,
+ 'D4': 6,
+ 'C6': 7,
+ 'D7': 8,
+ 'E6': 9,
+ 'B4': 10,
+ 'B5': 11,
+ 'B6': 12,
+ 'B2': 13,
+ 'B3': 14,
+ 'B1': 15,
+ 'F7': 16,
+ 'F6': 17,
+ 'F5': 18,
+ 'F4': 19,
+}
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/bitc_promicro.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/bitc_promicro.py
new file mode 100644
index 0000000000..8c2bcf152b
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/bitc_promicro.py
@@ -0,0 +1,32 @@
+import board
+
+# Bit-C-Pro RP2040 pinout for reference, see https://nullbits.co/bit-c-pro/
+# (unused)
+pinout = [
+ board.D0, # Enc 3
+ board.D1, # Enc 3
+ None, # GND
+ None, # GND
+ board.D2, # Enc 2
+ board.D3, # Enc 2
+ board.D4, # Row 4 + breakout SDA
+ board.D5, # Row 3 + breakout SCL
+ board.D6, # Row 2
+ board.D7, # Row 1
+ board.D8, # Enc 1
+ board.D9, # Enc 1
+ # Unconnected breakout pins D11, D12, GND, D13, D14
+ board.D21, # WS2812 LEDs labeled D10/GP21 but only board.D21 is defined
+ board.D23, # MOSI - Enc 0
+ board.D20, # MISO - Enc 0
+ board.D22, # SCK - Row 0
+ board.D26, # A0 - Col 3
+ board.D27, # A1 - Col 2
+ board.D28, # A2 - Col 1
+ board.D29, # A3 - Col 0
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # RAW
+]
+# also defined: board.LED_RED, board.LED_GREEN, and board.LED_BLUE == board.LED
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/boardsource_blok.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/boardsource_blok.py
new file mode 100644
index 0000000000..713cbe15ad
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/boardsource_blok.py
@@ -0,0 +1,28 @@
+import board
+
+pinout = [
+ board.TX,
+ board.RX,
+ None, # GND
+ None, # GND
+ board.SDA,
+ board.SCL,
+ board.GP04,
+ board.GP05,
+ board.GP06,
+ board.GP07,
+ board.GP08,
+ board.GP09,
+ board.GP21,
+ board.GP23,
+ board.GP20,
+ board.GP22,
+ board.GP26,
+ board.GP27,
+ board.GP28,
+ board.GP29,
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # RAW
+]
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/elite_pi.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/elite_pi.py
new file mode 100644
index 0000000000..6f1173a7b9
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/elite_pi.py
@@ -0,0 +1,28 @@
+import board
+
+pinout = [
+ board.D0,
+ board.D1,
+ None, # GND
+ None, # GND
+ board.D2,
+ board.D3,
+ board.D4,
+ board.D5,
+ board.D6,
+ board.D7,
+ board.D8,
+ board.D9,
+ board.D21,
+ board.D23,
+ board.D20,
+ board.D22,
+ board.D26,
+ board.D27,
+ board.D28,
+ board.D29,
+ None, # VCC
+ None, # RUN
+ None, # GND
+ None, # RAW
+]
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/frood.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/frood.py
new file mode 100644
index 0000000000..c45a2d04e0
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/frood.py
@@ -0,0 +1,33 @@
+import board
+
+pinout = [
+ board.TX,
+ board.RX,
+ None, # GND
+ None, # GND
+ board.D2,
+ board.D3,
+ board.D4,
+ board.D5,
+ board.D6,
+ board.D7,
+ board.D8,
+ board.D9,
+ board.D12,
+ board.D13,
+ board.D14,
+ board.D15,
+ board.D16,
+ board.D21,
+ board.MOSI,
+ board.MISO,
+ board.SCK,
+ board.D26,
+ board.D27,
+ board.D28,
+ board.D29,
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # RAW
+]
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/helios.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/helios.py
new file mode 100644
index 0000000000..6924254cdc
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/helios.py
@@ -0,0 +1,28 @@
+import board
+
+pinout = [
+ board.TX,
+ board.RX,
+ None, # GND
+ None, # GND
+ board.GP2,
+ board.GP3,
+ board.GP4,
+ board.GP5,
+ board.GP6,
+ board.GP7,
+ board.GP8,
+ board.GP9,
+ board.CS,
+ board.SDO,
+ board.SDI,
+ board.SCK,
+ board.GP26,
+ board.GP27,
+ board.GP28,
+ board.GP29,
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # RAW
+]
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/kb2040.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/kb2040.py
new file mode 100644
index 0000000000..363de3d2fe
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/kb2040.py
@@ -0,0 +1,28 @@
+import board
+
+pinout = [
+ board.D0,
+ board.D1,
+ None, # GND
+ None, # GND
+ board.D2,
+ board.D3,
+ board.D4,
+ board.D5,
+ board.D6,
+ board.D7,
+ board.D8,
+ board.D9,
+ board.D10,
+ board.MOSI,
+ board.MISO,
+ board.SCK,
+ board.A0,
+ board.A1,
+ board.A2,
+ board.A3,
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # RAW
+]
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/liatris.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/liatris.py
new file mode 100644
index 0000000000..b65af7ed21
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/liatris.py
@@ -0,0 +1,43 @@
+import board
+
+pinout = [
+ # Left, top->bottom
+ board.TX,
+ board.RX,
+ None, # GND
+ None, # GND
+ board.SDA,
+ board.SCL,
+ board.D4,
+ board.D5, # C6
+ board.D6, # D7
+ board.D7, # E6
+ board.D8, # B4
+ board.D9, # B5
+ # Right, bottom->top
+ board.D21, # B6
+ board.D23, # B2
+ board.D20, # B3
+ board.D22, # B1
+ board.D26, # F7
+ board.D27, # F6
+ board.D28, # F5
+ board.D29, # F4
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # RAW
+ # Bottom, left->right
+ board.D12,
+ board.D13,
+ board.D14,
+ board.D15,
+ board.D16,
+ # Internal
+ board.NEOPIXEL,
+ board.VBUS_SENSE,
+ board.POWER_LED,
+ board.I2C,
+ board.SPI,
+ board.UART,
+]
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/nice_nano.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/nice_nano.py
new file mode 100644
index 0000000000..36d5f13092
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/nice_nano.py
@@ -0,0 +1,28 @@
+import board
+
+pinout = [
+ board.TX,
+ board.RX,
+ None, # GND
+ None, # GND
+ board.SDA,
+ board.SCL,
+ board.P0_22,
+ board.P0_24,
+ board.P1_00,
+ board.P0_11,
+ board.P1_04,
+ board.P1_06,
+ board.P0_09,
+ board.P0_10,
+ board.P1_11,
+ board.P1_13,
+ board.P1_15,
+ board.P0_02,
+ board.P0_29,
+ board.P0_31,
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # Battery+
+]
diff --git a/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/sparkfun_promicro_rp2040.py b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/sparkfun_promicro_rp2040.py
new file mode 100644
index 0000000000..13b1098940
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/quickpin/pro_micro/sparkfun_promicro_rp2040.py
@@ -0,0 +1,28 @@
+import board
+
+pinout = [
+ board.TX,
+ board.RX,
+ None, # GND
+ None, # GND
+ board.D2,
+ board.D3,
+ board.D4,
+ board.D5,
+ board.D6,
+ board.D7,
+ board.D8,
+ board.D9,
+ board.D21,
+ board.MOSI,
+ board.MISO,
+ board.SCK,
+ board.D26,
+ board.D27,
+ board.D28,
+ board.D29,
+ None, # 3.3v
+ None, # RST
+ None, # GND
+ None, # RAW
+]
diff --git a/hackpads/blipyboard/firmware/kmk/scanners/__init__.py b/hackpads/blipyboard/firmware/kmk/scanners/__init__.py
new file mode 100644
index 0000000000..bf6edba974
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/scanners/__init__.py
@@ -0,0 +1,38 @@
+class DiodeOrientation:
+ '''
+ Orientation of diodes on handwired boards. You can think of:
+ COLUMNS = vertical
+ ROWS = horizontal
+
+ COL2ROW and ROW2COL are equivalent to their meanings in QMK.
+ '''
+
+ COLUMNS = 1
+ ROWS = 0
+ COL2ROW = COLUMNS
+ ROW2COL = ROWS
+
+
+class Scanner:
+ '''
+ Base class for scanners.
+ '''
+
+ # for split keyboards, the offset value will be assigned in Split module
+ offset = 0
+
+ @property
+ def coord_mapping(self):
+ return tuple(range(self.offset, self.offset + self.key_count))
+
+ @property
+ def key_count(self):
+ raise NotImplementedError
+
+ def scan_for_changes(self):
+ '''
+ Scan for key events and return a key report if an event exists.
+
+ The key report is a byte array with contents [row, col, True if pressed else False]
+ '''
+ raise NotImplementedError
diff --git a/hackpads/blipyboard/firmware/kmk/scanners/digitalio.py b/hackpads/blipyboard/firmware/kmk/scanners/digitalio.py
new file mode 100644
index 0000000000..73ffb611d2
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/scanners/digitalio.py
@@ -0,0 +1,144 @@
+import digitalio
+
+from keypad import Event as KeyEvent
+
+from kmk.scanners import DiodeOrientation, Scanner
+
+
+def ensure_DIO(x):
+ # __class__.__name__ is used instead of isinstance as the MCP230xx lib
+ # does not use the digitalio.DigitalInOut, but rather a self defined one:
+ # https://github.com/adafruit/Adafruit_CircuitPython_MCP230xx/blob/3f04abbd65ba5fa938fcb04b99e92ae48a8c9406/adafruit_mcp230xx/digital_inout.py#L33
+ if x.__class__.__name__ == 'DigitalInOut':
+ return x
+ else:
+ return digitalio.DigitalInOut(x)
+
+
+class MatrixScanner(Scanner):
+ def __init__(
+ self,
+ cols,
+ rows,
+ diode_orientation=DiodeOrientation.COL2ROW,
+ pull=digitalio.Pull.UP,
+ rollover_cols_every_rows=None,
+ offset=0,
+ ):
+ self.len_cols = len(cols)
+ self.len_rows = len(rows)
+ self.pull = pull
+ self.offset = offset
+
+ # A pin cannot be both a row and column, detect this by combining the
+ # two tuples into a set and validating that the length did not drop
+ #
+ # repr() hackery is because CircuitPython Pin objects are not hashable
+ unique_pins = {repr(c) for c in cols} | {repr(r) for r in rows}
+ assert (
+ len(unique_pins) == self.len_cols + self.len_rows
+ ), 'Cannot use a pin as both a column and row'
+ del unique_pins
+
+ self.diode_orientation = diode_orientation
+
+ if self.diode_orientation == DiodeOrientation.COL2ROW:
+ self.anodes = [ensure_DIO(x) for x in cols]
+ self.cathodes = [ensure_DIO(x) for x in rows]
+ self.translate_coords = True
+ elif self.diode_orientation == DiodeOrientation.ROW2COL:
+ self.anodes = [ensure_DIO(x) for x in rows]
+ self.cathodes = [ensure_DIO(x) for x in cols]
+ self.translate_coords = False
+ else:
+ raise ValueError(f'Invalid DiodeOrientation: {self.diode_orienttaion}')
+
+ if self.pull == digitalio.Pull.DOWN:
+ self.outputs = self.anodes
+ self.inputs = self.cathodes
+ elif self.pull == digitalio.Pull.UP:
+ self.outputs = self.cathodes
+ self.inputs = self.anodes
+ self.translate_coords = not self.translate_coords
+ else:
+ raise ValueError(f'Invalid pull: {self.pull}')
+
+ for pin in self.outputs:
+ pin.switch_to_output()
+
+ for pin in self.inputs:
+ pin.switch_to_input(pull=self.pull)
+
+ self.rollover_cols_every_rows = rollover_cols_every_rows
+ if self.rollover_cols_every_rows is None:
+ self.rollover_cols_every_rows = self.len_rows
+
+ self._key_count = self.len_cols * self.len_rows
+ initial_state_value = b'\x01' if self.pull is digitalio.Pull.UP else b'\x00'
+ self.state = bytearray(initial_state_value) * self.key_count
+
+ @property
+ def key_count(self):
+ return self._key_count
+
+ def scan_for_changes(self):
+ '''
+ Poll the matrix for changes and return either None (if nothing updated)
+ or a bytearray (reused in later runs so copy this if you need the raw
+ array itself for some crazy reason) consisting of (row, col, pressed)
+ which are (int, int, bool)
+ '''
+ ba_idx = 0
+ any_changed = False
+
+ for oidx, opin in enumerate(self.outputs):
+ opin.value = self.pull is not digitalio.Pull.UP
+
+ for iidx, ipin in enumerate(self.inputs):
+ # cast to int to avoid
+ #
+ # >>> xyz = bytearray(3)
+ # >>> xyz[2] = True
+ # Traceback (most recent call last):
+ # File "", line 1, in
+ # OverflowError: value would overflow a 1 byte buffer
+ #
+ # I haven't dived too far into what causes this, but it's
+ # almost certainly because bool types in Python aren't just
+ # aliases to int values, but are proper pseudo-types
+ new_val = int(ipin.value)
+ old_val = self.state[ba_idx]
+
+ if old_val != new_val:
+ if self.translate_coords:
+ new_oidx = oidx + self.len_cols * (
+ iidx // self.rollover_cols_every_rows
+ )
+ new_iidx = iidx - self.rollover_cols_every_rows * (
+ iidx // self.rollover_cols_every_rows
+ )
+
+ row = new_iidx
+ col = new_oidx
+ else:
+ row = oidx
+ col = iidx
+
+ if self.pull is digitalio.Pull.UP:
+ pressed = not new_val
+ else:
+ pressed = new_val
+ self.state[ba_idx] = new_val
+
+ any_changed = True
+ break
+
+ ba_idx += 1
+
+ opin.value = self.pull is digitalio.Pull.UP
+ if any_changed:
+ break
+
+ if any_changed:
+ key_number = self.len_cols * row + col + self.offset
+ return KeyEvent(key_number, pressed)
diff --git a/hackpads/blipyboard/firmware/kmk/scanners/encoder.py b/hackpads/blipyboard/firmware/kmk/scanners/encoder.py
new file mode 100644
index 0000000000..301ebb6a44
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/scanners/encoder.py
@@ -0,0 +1,43 @@
+import keypad
+import rotaryio
+
+from kmk.scanners import Scanner
+
+
+class RotaryioEncoder(Scanner):
+ def __init__(self, pin_a, pin_b, divisor=4):
+ self.encoder = rotaryio.IncrementalEncoder(pin_a, pin_b, divisor)
+ self.position = 0
+ self._pressed = False
+ self._queue = []
+
+ @property
+ def key_count(self):
+ return 2
+
+ def scan_for_changes(self):
+ position = self.encoder.position
+
+ if position != self.position:
+ self._queue.append(position - self.position)
+ self.position = position
+
+ if not self._queue:
+ return
+
+ key_number = self.offset
+ if self._queue[0] > 0:
+ key_number += 1
+
+ if self._pressed:
+ self._queue[0] -= 1 if self._queue[0] > 0 else -1
+
+ if self._queue[0] == 0:
+ self._queue.pop(0)
+
+ self._pressed = False
+
+ else:
+ self._pressed = True
+
+ return keypad.Event(key_number, self._pressed)
diff --git a/hackpads/blipyboard/firmware/kmk/scanners/keypad.py b/hackpads/blipyboard/firmware/kmk/scanners/keypad.py
new file mode 100644
index 0000000000..a02c119c58
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/scanners/keypad.py
@@ -0,0 +1,59 @@
+import keypad
+
+from kmk.scanners import Scanner
+
+
+class KeypadScanner(Scanner):
+ '''
+ Translation layer around a CircuitPython 7 keypad scanner.
+
+ :param pin_map: A sequence of (row, column) tuples for each key.
+ :param kp: An instance of the keypad class.
+ '''
+
+ @property
+ def key_count(self):
+ return self.keypad.key_count
+
+ def scan_for_changes(self):
+ '''
+ Scan for key events and return a key report if an event exists.
+
+ The key report is a byte array with contents [row, col, True if pressed else False]
+ '''
+ ev = self.keypad.events.get()
+ if ev and self.offset:
+ return keypad.Event(ev.key_number + self.offset, ev.pressed)
+ return ev
+
+
+class MatrixScanner(KeypadScanner):
+ '''
+ Row/Column matrix using the CircuitPython 7 keypad scanner.
+
+ :param row_pins: A sequence of pins used for rows.
+ :param col_pins: A sequence of pins used for columns.
+ :param direction: The diode orientation of the matrix.
+ '''
+
+ def __init__(self, *args, **kwargs):
+ self.keypad = keypad.KeyMatrix(*args, **kwargs)
+ super().__init__()
+
+
+class KeysScanner(KeypadScanner):
+ '''
+ GPIO-per-key 'matrix' using the native CircuitPython 7 keypad scanner.
+
+ :param pins: An array of arrays of CircuitPython Pin objects, such that pins[r][c] is the pin for row r, column c.
+ '''
+
+ def __init__(self, *args, **kwargs):
+ self.keypad = keypad.Keys(*args, **kwargs)
+ super().__init__()
+
+
+class ShiftRegisterKeys(KeypadScanner):
+ def __init__(self, *args, **kwargs):
+ self.keypad = keypad.ShiftRegisterKeys(*args, **kwargs)
+ super().__init__()
diff --git a/hackpads/blipyboard/firmware/kmk/scheduler.py b/hackpads/blipyboard/firmware/kmk/scheduler.py
new file mode 100644
index 0000000000..066d08cd93
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/scheduler.py
@@ -0,0 +1,75 @@
+'''
+Here we're abusing _asyncios TaskQueue to implement a very simple priority
+queue task scheduler.
+Despite documentation, Circuitpython doesn't usually ship with a min-heap
+module; it does however implement a pairing-heap for `TaskQueue` in native code.
+'''
+
+try:
+ from typing import Callable
+except ImportError:
+ pass
+
+from supervisor import ticks_ms
+
+from _asyncio import Task, TaskQueue
+
+from kmk.kmktime import ticks_add, ticks_diff
+
+_task_queue = TaskQueue()
+
+
+class PeriodicTaskMeta:
+ def __init__(self, func: Callable[[None], None], period: int) -> None:
+ self._task = Task(self.call)
+ self._coro = func
+ self.period = period
+
+ def call(self) -> None:
+ after_ms = ticks_add(self._task.ph_key, self.period)
+ _task_queue.push(self._task, after_ms)
+ self._coro()
+
+ def restart(self) -> None:
+ _task_queue.push(self._task)
+
+
+def create_task(
+ func: [Callable[[None], None], Task, PeriodicTaskMeta],
+ *,
+ after_ms: int = 0,
+ period_ms: int = 0,
+) -> [Task, PeriodicTaskMeta]:
+ if isinstance(func, Task):
+ t = r = func
+ elif isinstance(func, PeriodicTaskMeta):
+ r = func
+ t = r._task
+ elif period_ms:
+ r = PeriodicTaskMeta(func, period_ms)
+ t = r._task
+ else:
+ t = r = Task(func)
+
+ if after_ms > 0:
+ _task_queue.push(t, ticks_add(ticks_ms(), after_ms))
+ elif after_ms == 0:
+ _task_queue.push(t)
+
+ return r
+
+
+def get_due_task() -> [Callable, None]:
+ now = ticks_ms()
+ while True:
+ t = _task_queue.peek()
+ if not t or ticks_diff(t.ph_key, now) > 0:
+ break
+ _task_queue.pop()
+ yield t.coro
+
+
+def cancel_task(t: [Task, PeriodicTaskMeta]) -> None:
+ if isinstance(t, PeriodicTaskMeta):
+ t = t._task
+ _task_queue.remove(t)
diff --git a/hackpads/blipyboard/firmware/kmk/transports/__init__.py b/hackpads/blipyboard/firmware/kmk/transports/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/hackpads/blipyboard/firmware/kmk/transports/pio_uart.py b/hackpads/blipyboard/firmware/kmk/transports/pio_uart.py
new file mode 100644
index 0000000000..108d9b46c6
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/transports/pio_uart.py
@@ -0,0 +1,93 @@
+'''
+Circuit Python wrapper around PIO implementation of UART
+Original source of these examples: https://github.com/adafruit/Adafruit_CircuitPython_PIOASM/tree/main/examples (MIT)
+'''
+
+import rp2pio
+from array import array
+
+'''
+.program uart_tx
+.side_set 1 opt
+; An 8n1 UART transmit program.
+; OUT pin 0 and side-set pin 0 are both mapped to UART TX pin.
+ pull side 1 [7] ; Assert stop bit, or stall with line in idle state
+ set x, 7 side 0 [7] ; Preload bit counter, assert start bit for 8 clocks
+bitloop: ; This loop will run 8 times (8n1 UART)
+ out pins, 1 ; Shift 1 bit from OSR to the first OUT pin
+ jmp x-- bitloop [6] ; Each loop iteration is 8 cycles.
+
+; compiles to:
+'''
+tx_code = array('H', [40864, 63271, 24577, 1602])
+
+
+'''
+.program uart_rx_mini
+
+; Minimum viable 8n1 UART receiver. Wait for the start bit, then sample 8 bits
+; with the correct timing.
+; IN pin 0 is mapped to the GPIO used as UART RX.
+; Autopush must be enabled, with a threshold of 8.
+
+ wait 0 pin 0 ; Wait for start bit
+ set x, 7 [10] ; Preload bit counter, delay until eye of first data bit
+bitloop: ; Loop 8 times
+ in pins, 1 ; Sample data
+ jmp x-- bitloop [6] ; Each iteration is 8 cycles
+
+; compiles to:
+'''
+rx_code = array('H', [8224, 59943, 16385, 1602])
+
+
+class PIO_UART:
+ def __init__(self, *, tx, rx, baudrate=9600):
+ if tx:
+ self.tx_pio = rp2pio.StateMachine(
+ tx_code,
+ first_out_pin=tx,
+ first_sideset_pin=tx,
+ frequency=8 * baudrate,
+ initial_sideset_pin_state=1,
+ initial_sideset_pin_direction=1,
+ initial_out_pin_state=1,
+ initial_out_pin_direction=1,
+ sideset_enable=True,
+ )
+ if rx:
+ self.rx_pio = rp2pio.StateMachine(
+ rx_code,
+ first_in_pin=rx,
+ frequency=8 * baudrate,
+ auto_push=True,
+ push_threshold=8,
+ )
+
+ @property
+ def timeout(self):
+ return 0
+
+ @property
+ def baudrate(self):
+ return self.tx_pio.frequency // 8
+
+ @baudrate.setter
+ def baudrate(self, frequency):
+ self.tx_pio.frequency = frequency * 8
+ self.rx_pio.frequency = frequency * 8
+
+ def write(self, buf):
+ return self.tx_pio.write(buf)
+
+ @property
+ def in_waiting(self):
+ return self.rx_pio.in_waiting
+
+ def read(self, n):
+ b = bytearray(n)
+ n = self.rx_pio.readinto(b)
+ return b[:n]
+
+ def readinto(self, buf):
+ return self.rx_pio.readinto(buf)
diff --git a/hackpads/blipyboard/firmware/kmk/utils.py b/hackpads/blipyboard/firmware/kmk/utils.py
new file mode 100644
index 0000000000..e0830d9d23
--- /dev/null
+++ b/hackpads/blipyboard/firmware/kmk/utils.py
@@ -0,0 +1,49 @@
+try:
+ from typing import Optional
+except ImportError:
+ pass
+
+from supervisor import ticks_ms
+
+from usb_cdc import console
+
+
+def clamp(x: int, bottom: int = 0, top: int = 100) -> int:
+ return min(max(bottom, x), top)
+
+
+_debug_enabled = None
+
+
+class Debug:
+ '''default usage:
+ debug = Debug(__name__)
+ '''
+
+ def __init__(self, name: str = __name__):
+ self.name = name
+
+ def __call__(self, *message: str, name: Optional[str] = None) -> None:
+ if not name:
+ name = self.name
+ print(ticks_ms(), end=' ')
+ print(name, end=': ')
+ print(*message, sep='')
+
+ @property
+ def enabled(self) -> bool:
+ global _debug_enabled
+ if (
+ _debug_enabled is None
+ and console
+ and console.connected
+ and console.out_waiting == 0
+ ):
+ return True
+ return bool(_debug_enabled)
+
+ @enabled.setter
+ def enabled(self, enabled: bool):
+ global _debug_enabled
+ _debug_enabled = enabled
+ self('debug.enabled=', enabled)
diff --git a/hackpads/blipyboard/firmware/main.py b/hackpads/blipyboard/firmware/main.py
new file mode 100644
index 0000000000..c6ecf440c9
--- /dev/null
+++ b/hackpads/blipyboard/firmware/main.py
@@ -0,0 +1,96 @@
+# You import all the IOs of your board
+import board
+import busio
+
+# These are imports from the kmk library
+from kmk.kmk_keyboard import KMKKeyboard
+from kmk.scanners.keypad import KeysScanner
+from kmk.keys import KC
+from kmk.modules.macros import Press, Release, Tap, Macros
+from kmk.modules.encoder import EncoderHandler
+from kmk.extensions.mouse_keys import MouseKeys
+from kmk.extensions.rgb import RGB
+from kmk.extensions.display.ssd1306 import SSD1306
+from kmk.extensions.display import Display, ImageEntry, TextEntry
+from kmk.scanners.matrix import MatrixScanner
+
+
+col1 = board.GP29
+col2 = board.GP28
+col3 = board.GP27
+col4 = board.GP26
+row1 = board.GP4
+row2 = board.GP0
+SDA = board.GP6
+SCL = board.GP7
+EC11A = board.GP2
+EC11B = board.GP1
+
+# This is the main instance of your keyboard
+keyboard = KMKKeyboard()
+mouse_keys = MouseKeys()
+keyboard.extensions.append(mouse_keys)
+
+# Add the macro extension
+macros = Macros()
+keyboard.modules.append(macros)
+
+encoder_handler = EncoderHandler()
+
+keyboard.modules.append(encoder_handler)
+encoder_handler.pins = ((EC11A, EC11B),)
+encoder_handler.map = [((KC.VOLU, KC.VOLD),)]
+
+rgb = RGB(pixel_pin=board.GP3,
+ num_pixels=8,
+ rgb_order=(1,0,2),
+
+ )
+keyboard.extensions.append(rgb)
+
+i2c_bus = busio.I2C(SCL, SDA)
+driver = SSD1306(i2c=i2c_bus)
+
+display = Display(
+ # Mandatory:
+ display=driver,
+ # Optional:
+ width=128, # screen size
+ height=32, # screen size
+ flip = False, # flips your display content
+ flip_left = False, # flips your display content on left side split
+ flip_right = False, # flips your display content on right side split
+ brightness=1, # initial screen brightness level
+)
+
+display.entries = [
+ ImageEntry(image="me.bmp", x=0, y=0, layer=0),
+]
+keyboard.extensions.append(display)
+
+
+# Define your pins here!
+ROW_PINS = [row1, row2]
+COL_PINS = [col1, col2, col3, col4]
+
+
+keyboard.matrix = MatrixScanner(
+ columns=COL_PINS,
+ rows=ROW_PINS,
+)
+
+keyboard.keymap = [
+ [
+ KC.MPRV, KC.MPLY, KC.MNXT, MouseKeys.LEFT_BUTTON,
+ KC.LCTL(KC.C), KC.LCTL(KC.V), KC.MACRO("jxcai534@gmail.com"), MouseKeys.LEFT_BUTTON,
+ ]
+]
+
+# Here you define the buttons corresponding to the pins
+# Look here for keycodes: https://github.com/KMKfw/kmk_firmware/blob/main/docs/en/keycodes.md
+# And here for macros: https://github.com/KMKfw/kmk_firmware/blob/main/docs/en/macros.md
+
+
+# Start kmk!
+if __name__ == '__main__':
+ keyboard.go()
\ No newline at end of file
diff --git a/hackpads/blipyboard/pcb/hackpad copy.kicad_pcb b/hackpads/blipyboard/pcb/hackpad copy.kicad_pcb
new file mode 100644
index 0000000000..f8947724b8
--- /dev/null
+++ b/hackpads/blipyboard/pcb/hackpad copy.kicad_pcb
@@ -0,0 +1,11929 @@
+(kicad_pcb
+ (version 20240108)
+ (generator "pcbnew")
+ (generator_version "8.0")
+ (general
+ (thickness 1.6)
+ (legacy_teardrops no)
+ )
+ (paper "A4")
+ (layers
+ (0 "F.Cu" signal)
+ (31 "B.Cu" signal)
+ (32 "B.Adhes" user "B.Adhesive")
+ (33 "F.Adhes" user "F.Adhesive")
+ (34 "B.Paste" user)
+ (35 "F.Paste" user)
+ (36 "B.SilkS" user "B.Silkscreen")
+ (37 "F.SilkS" user "F.Silkscreen")
+ (38 "B.Mask" user)
+ (39 "F.Mask" user)
+ (40 "Dwgs.User" user "User.Drawings")
+ (41 "Cmts.User" user "User.Comments")
+ (42 "Eco1.User" user "User.Eco1")
+ (43 "Eco2.User" user "User.Eco2")
+ (44 "Edge.Cuts" user)
+ (45 "Margin" user)
+ (46 "B.CrtYd" user "B.Courtyard")
+ (47 "F.CrtYd" user "F.Courtyard")
+ (48 "B.Fab" user)
+ (49 "F.Fab" user)
+ (50 "User.1" user)
+ (51 "User.2" user)
+ (52 "User.3" user)
+ (53 "User.4" user)
+ (54 "User.5" user)
+ (55 "User.6" user)
+ (56 "User.7" user)
+ (57 "User.8" user)
+ (58 "User.9" user)
+ )
+ (setup
+ (pad_to_mask_clearance 0)
+ (allow_soldermask_bridges_in_footprints no)
+ (grid_origin 91.295 68.105)
+ (pcbplotparams
+ (layerselection 0x00010fc_ffffffff)
+ (plot_on_all_layers_selection 0x0000000_00000000)
+ (disableapertmacros no)
+ (usegerberextensions no)
+ (usegerberattributes yes)
+ (usegerberadvancedattributes yes)
+ (creategerberjobfile yes)
+ (dashed_line_dash_ratio 12.000000)
+ (dashed_line_gap_ratio 3.000000)
+ (svgprecision 4)
+ (plotframeref no)
+ (viasonmask no)
+ (mode 1)
+ (useauxorigin no)
+ (hpglpennumber 1)
+ (hpglpenspeed 20)
+ (hpglpendiameter 15.000000)
+ (pdf_front_fp_property_popups yes)
+ (pdf_back_fp_property_popups yes)
+ (dxfpolygonmode yes)
+ (dxfimperialunits yes)
+ (dxfusepcbnewfont yes)
+ (psnegative no)
+ (psa4output no)
+ (plotreference yes)
+ (plotvalue yes)
+ (plotfptext yes)
+ (plotinvisibletext no)
+ (sketchpadsonfab no)
+ (subtractmaskfromsilk no)
+ (outputformat 1)
+ (mirror no)
+ (drillshape 1)
+ (scaleselection 1)
+ (outputdirectory "")
+ )
+ )
+ (net 0 "")
+ (net 1 "+5V")
+ (net 2 "NEOPIXEL")
+ (net 3 "Net-(D1-DOUT)")
+ (net 4 "GND")
+ (net 5 "Net-(D11-DIN)")
+ (net 6 "Net-(D11-DOUT)")
+ (net 7 "SDA")
+ (net 8 "SCL")
+ (net 9 "3V3")
+ (net 10 "Net-(D3-A)")
+ (net 11 "col2")
+ (net 12 "Net-(D4-A)")
+ (net 13 "Net-(D5-A)")
+ (net 14 "col3")
+ (net 15 "Net-(D6-A)")
+ (net 16 "Net-(D7-A)")
+ (net 17 "Net-(D8-A)")
+ (net 18 "col4")
+ (net 19 "Net-(D9-A)")
+ (net 20 "Net-(D10-A)")
+ (net 21 "row2")
+ (net 22 "row1")
+ (net 23 "ROUTPUT")
+ (net 24 "RINPUT")
+ (net 25 "EC11A")
+ (net 26 "EC11B")
+ (net 27 "Net-(D14-DOUT)")
+ (net 28 "Net-(D15-DOUT)")
+ (net 29 "Net-(D16-DOUT)")
+ (net 30 "unconnected-(D17-DOUT-Pad1)")
+ (net 31 "Net-(D13-DOUT)")
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "219a831b-5fb5-4df8-a3f8-0ca655046c72")
+ (at 109.395 83.185)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW7"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "8c652338-13cd-4ef7-80ae-5da756c836a8")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -14.065 12.954 0)
+ (layer "F.Fab")
+ (uuid "747b3270-3da7-453a-bae6-69a55a26799c")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "3bf2b549-4289-4c9c-a479-0ed63023a83c")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "0864276f-6221-40c3-979d-d4f7b4b42029")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "45a5aaf6-23ba-4abf-89c7-30a752f5e66e")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/4e64b0d4-0bf5-4a85-844f-860d31b1043a")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "7216c875-ba2a-43e9-890f-8afd8023d886")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "51ded169-8d69-4caf-ba05-9d3630175f57")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "91d050ef-b30a-473f-8da5-a551f91797e9")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "ad4f1eba-9ced-4721-8b22-5ea02636d25c")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "77dd61ad-be9d-49c1-9913-ea6e0989318d")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "a62b832d-c4a4-41b8-a671-be63b31382be")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "214fbcd3-b43c-4a26-bfc4-7642cf217249")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "409dc611-ec2e-4a09-b2c2-8ede1bd5946b")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "df4a459e-1028-418c-82e1-e48741b71bb4")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "f1612bfd-29e0-4b3b-85c4-439eeaf87e9b")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "5fd980ac-829e-461e-b578-9f545c914ae8")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "d408877c-a966-4058-a449-2eecc441cd4c")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "e86f3f72-82dd-431b-a632-1e9a9a0dbc1d")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "abd0dae4-db96-4125-8b64-052f563121b2")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "e5e3256f-80eb-4711-827e-be70e0fae54f")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "203ce818-f5f9-4e99-8f16-9bd7f677c73d")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "6f08ec7b-6480-4acd-9dd5-a0300f58fe08")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "4ab9f0b9-1f18-4ba1-9d10-88846c2e65c7")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "784eb149-9030-49e2-8ccd-66b8ce34e748")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "3d8a1b8c-14d0-414c-8cfa-a494c7d5c1a4")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 18 "col4")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "3408ecab-90b9-4abc-8f2d-07a72129b842")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 19 "Net-(D9-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "bfe78acb-6281-4bd6-8139-fc5d28d2f0ac")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "264dacda-88da-4349-979b-e9d7c5163cac")
+ (at 42.72 102.235)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW1"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "6ca9af1f-2cf9-49eb-ba6d-9b05b98034fd")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -2.54 12.954 0)
+ (layer "F.Fab")
+ (uuid "413b4bd0-11d4-44a4-abf0-8fb114eebb2e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "3a890b65-3444-4296-be91-8b4f5c574118")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "841a0b97-1589-4dd4-be8e-04ed7bbb269f")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "04b4ddc6-24d3-4491-9a64-3e454f1b9280")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/261f75ab-c061-46a1-9759-af1f257be337")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "f398ff45-f550-4e65-b77a-23d38edc2381")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "251cf32e-619f-4da1-ba57-771e7bb87018")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "5096067f-a137-40b1-a91b-b4c461dcc505")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "474bf111-8f3e-4710-bf1e-481b8dc6e472")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "2658eef0-c82f-427c-8e23-8c7faa50dbe3")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "d4b2c647-8836-4a2e-a158-07395968c901")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "f4e672f9-697c-47f0-8f4c-587ff2b4d600")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "01fd775d-c344-432f-b2ef-8f8bacac53ad")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "9dc128f6-f1be-4ac6-8bdf-66777ce0ff93")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "0f3516c9-708a-4949-b133-ce96536c2efa")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "db97b555-c1ce-4adc-8113-bb4fd58c4006")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "c477f503-cdbf-4067-b810-1e84e0d5a7c0")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "88c3e6dd-9c40-4030-ba19-b07acbf87316")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "fb5e119d-d753-4a12-a977-f2085d2ce377")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "74dcdedd-6e8e-4212-82c0-74bf508a2c4a")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ac18a3a7-23c8-4230-ae82-b5ceb9001fff")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "4ca3c568-b19c-45b5-8ee0-a37e282cce68")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "f2f89b8f-c9c9-4634-a542-432899287c65")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "0c83a546-00bc-4fec-87d5-dd5669730901")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "244b3e69-6c6d-445b-aae0-81bcdaa141b0")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 24 "RINPUT")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "ef524698-f182-4cac-a1b4-f93caddc09bb")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 10 "Net-(D3-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "7d541c37-e87d-4f98-85c8-681a8c64d1f5")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "2df93757-142d-489c-9505-e60661c725f6")
+ (at 61.77 83.185)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW5"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "895a1282-f1f2-4391-aa33-5579f3c174a1")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -2.54 12.954 0)
+ (layer "F.Fab")
+ (uuid "07cefb64-5e0d-45e7-aad7-bfa8afa33eae")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "d9bbbf7c-f7b2-40b2-9024-e8714e7ea9ca")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b54f2a3d-a568-4bbd-8944-ac2cc41b39d6")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b31e7002-5c6e-4318-a8fa-64516aec6d8c")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/f09b3314-d915-403a-ab16-16fc4614b166")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "cc9a2305-df23-4a15-bce3-1aab0fe69bc3")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "d3d8ad74-5d16-4327-bfaa-2b1d1fd5417d")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b4ea4cc7-825d-40b8-9d02-9b41bd19ebbd")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "266ebc55-aacc-42f3-b473-1ad7dc84afd8")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "c856b37d-0dcc-4ec3-ab8b-1fde6858c1e5")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "5bc60201-6f00-4669-ad19-de9c7a7db90a")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "c7838ad5-7849-4b9e-84fe-57d56cf2aa63")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "5873c662-4824-4791-a95c-bc8ae47de621")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "9e09bef0-945d-44c4-8440-3b39bdf1d326")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e22b571f-d680-4295-884e-73b31a32e626")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "d5c2d366-76ff-4a70-9133-ca39fb0fec71")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "87d2cc7d-cc2a-4a3d-a5d4-d29e65fe44c3")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b800d40b-9dbb-4157-88c1-add9636abbdd")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "03c05000-869c-45a3-a4ce-70a1db97cbba")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "a71ce4f5-a28b-416e-b897-4ebf6cfd1fef")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b731c640-ba86-4243-89fa-c73861c6d652")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "78aac48e-749c-4f9a-9333-b429bc1122be")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "2c15a108-0801-45aa-8e6f-8abbd44a9a45")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "9cec6ff0-dbb0-4d6f-be1c-c7c336522d0b")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "17e069c1-f22c-4d7d-9651-48216f20e966")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 11 "col2")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "ec01de05-d1f9-46ef-a253-663a9683da38")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 16 "Net-(D7-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "4a069af5-82d2-4280-b385-f7c1133bbc96")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "32027f1c-a5a6-4325-bcb1-9537a7096dc5")
+ (at 49.725 111.235 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D3"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "e66ae99f-2efc-45a7-9268-0337c9ecf837")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "2a36d356-d106-4e5d-9903-bf6690ec8d92")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "266c3b43-4d07-4af8-8d20-712744bbb49d")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "76c31f6a-775d-4f93-96a7-f9ef7454c5e5")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "bd8b968b-2a15-4192-b347-6c3929497755")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "1a175cb3-c94c-4660-8aa7-b6c99453d5b5")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "a8547e69-a676-4910-8d97-c67ab9a17716")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/0182b48c-fe8b-47ef-8be4-7fa0b56081bd")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "d6c1b703-5228-4aeb-be59-9cc7b58d7c30")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "2c7e30bc-a0dd-4c2f-ad8e-e2b7bcfaa089")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "a44389e1-3139-429d-8e82-7472811f3c5f")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "42b69dcd-3653-40bf-8c20-778d2d52e07d")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c11c487c-374b-4586-afe7-d6855e597ed8")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c9752238-da35-48c8-bb37-d58d871ff3e1")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "2fa289ca-1771-469e-b932-cab15a139daf")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "63112816-ebbe-4fd7-9694-8277072a2248")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "6a84d4e7-e3db-4e59-9cde-4ca7923b7953")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "d670adc7-c0a1-428c-8b09-eccf06708762")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "070debb5-6df6-46e8-b583-b4178c65582f")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e8a83788-9683-4f18-818c-a3f62d818f3f")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "27496a77-a3b8-4105-8c3e-b8ad2059f7d3")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ecae459d-ea6c-4014-b0d1-fdb285b78479")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1c2897e9-3eab-4eb5-8a2c-7e870e32bc01")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "0c605497-2775-4479-b29b-b65291b6e25c")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "2d2689f0-0774-43e9-8173-9259fd5a3724")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "135c148a-d538-4ad4-9ffb-e9ba4a1a7fcc")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1d8a4517-7c12-415d-934e-0188799e9d61")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "7d5e543a-bfb6-4453-8812-4de4c6604ce8")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "80db46c2-452d-4a95-bfac-d00c46ba7a55")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "a4b9f56d-ea12-4439-b72d-bf0f6ad60c21")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "2146be1f-7554-4ea4-bd28-93abf38552ca")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "685388df-7515-4225-8764-6a331ff65df4")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "9f4ae749-b1da-409d-84c6-2bea450fe56c")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 21 "row2")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "84117f8e-d3a9-4c1d-a590-cd099a39db2d")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 10 "Net-(D3-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "b808040e-d3c5-4fbc-8e6f-6b4cee593ff5")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "48e8f561-784d-4974-84c4-0b45e67b0265")
+ (at 87.855 92.275 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D8"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "aa420aa5-3848-4760-b327-39cd85dce12a")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "5072ba5f-4893-4060-90fd-8d3a01f6abe6")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "25ec59bc-cf30-4591-b679-d5ef9c170d10")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "19fea905-1a0f-4cde-bcb6-cf8874172a41")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "254033ea-e5b8-4e2f-836e-c7c34a887dc4")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "69b915e6-e1c6-4f54-a678-5a390d005816")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "eb47b5ce-defb-42f6-8bbf-0aabf5e1d031")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/554ad5aa-fcfb-4528-b5bb-4feac667d765")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9ba46c83-bf45-4e70-8728-47f916ef46d6")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "53b4aae4-fa06-4246-b4bc-a3fd781e5827")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "3d5ff8f7-5d27-481c-b2c7-006b4d20236e")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c897801c-9977-4cc8-b824-053f5f0a4d82")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b9df3a64-b57b-414a-8619-2dd7fb143d01")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "cd31a077-935f-4477-aed1-9868e90c0db5")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9c080fbf-5fc9-4c18-9dac-76123503b7f9")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b4bff95b-f44a-47a4-938a-d41aaed28d9b")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e3086263-6b1d-4c75-bafc-701723ff17f2")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e34af85c-ac24-421d-aaf3-0598cd3d1954")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "f57b8031-5044-4c58-b118-b14fb51297d7")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "afab5a74-7289-4a07-a498-522454ab1cb8")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "b3c79efa-cfa1-4415-87f8-831897aaaa85")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "bc8c0346-734b-497d-b7d8-83c6c4cdb868")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "03505b0b-5e4e-4849-b59a-9044e33901cb")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b518fb36-94fe-46b0-9bd1-55f505357abf")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "5d073726-27a6-4dc4-9834-badfb8946ad0")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "0606dbb9-c9fe-489c-9706-2d74c57b8dba")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "452799fd-6bfd-4b88-8a20-9aa99507c671")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c86d1108-eb47-4f53-bc4a-12ae201cb9c3")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "d7f20ffb-88cb-4fe2-9f4b-175992a6f0db")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "bad98010-5806-4e2c-a587-69d11dd06fd7")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "50ec668a-25a7-47e7-8676-275140a31b91")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "50eee923-b898-4d3b-8f95-7f22d82749e5")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "9f86d8a3-d933-41ae-977f-037fb34dfb46")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 22 "row1")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "ecb6d6cb-dcd1-4437-a5dd-ff05c495576d")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 17 "Net-(D8-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "4c6e0b59-5b74-44c6-90e5-7fb90f0ba199")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "4f7cf52f-bd4c-4358-af75-ac246f61a9f3")
+ (at 87.865 111.275 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D5"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "fcf7afc9-ec44-4d83-94f8-bb2bdbd1ab81")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "d8e2d527-76f0-48d8-a1d5-d576b17715b5")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "56be824e-0eeb-45c9-a3d9-20b8940d80c5")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b7a3ec84-500d-463f-bbbd-0d86c7c929af")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "5cc0f5b1-7e0d-42f8-af3d-25784318fc36")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b27494c4-a9fd-4e09-bf6d-99ac7c4b927b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "316cf41e-673c-4463-9cdc-70d4e9ea51cf")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/8f9dee36-bcf8-4199-b179-81a96b947127")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "f80a5d4a-32ab-4716-93ba-670839e391f3")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "baa46d61-0afb-4bc8-b45c-51e9f90d7788")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "84c65bf7-3899-4ef0-b45a-ba387da4becb")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9b41c538-bf0d-4366-bc0a-e3d8094a1e94")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "a2ffb3c0-5512-4ad9-b264-50809bba6498")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "05ae5be1-efba-4c9e-8732-b0e647120045")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "2133fecd-9dad-45fb-ab01-788333534e7f")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9a23f858-0186-409f-9458-184bd67a61fc")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "54c941af-7b5a-450c-a7f4-66816a9f0566")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "f5a71200-25f6-45fc-a863-d8f217b1bd3d")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "7c6e9c89-36f1-4ace-afdf-6ba6b7a2ffa6")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e22ae283-839d-4556-849b-11afd581aa01")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "d290c4dc-5b5b-4b78-8c57-95f01c58b39d")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "96b1d36e-09d2-47f5-a838-3abfc74f8500")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1b590de4-b4d6-489b-b290-b362df47703f")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b32e9720-f182-4050-a74a-206749098d28")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "573fff21-4445-45b9-952d-b88932ff88f3")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "4e2f962f-1b91-473a-b4b3-c9f7ae6025da")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "e7389050-b30c-403c-bd5a-409943928e93")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "6d56190f-6d1c-4be6-ae06-1da54ad2794c")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f760dd6a-8548-4e6b-9c80-a304624cba65")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "7e02ac2f-93d1-4362-a874-4da1358d659d")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "4482e7bc-fd6c-42d2-9126-6f9c5006016b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "5a2a7252-5f13-48b5-bf6b-93163d3ad205")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "d30ea979-ce18-4c42-82ae-b62c13cc284f")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 21 "row2")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "03e2715b-59aa-40bb-a699-35676b4fa23f")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 13 "Net-(D5-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "8a628e9e-e07b-49bb-b31b-320cc4f1b22e")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "52148390-c0ae-4e35-95e2-6703d897e606")
+ (at 109.395 102.235)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW8"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "1bcbb0d5-2dd2-473a-a9d5-6e0857ac1f02")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -2.54 12.954 0)
+ (layer "F.Fab")
+ (uuid "42fb4977-8775-4cf6-8181-33f9a712d403")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b71cb3ca-148a-4400-b07a-2452c9296308")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "9c0f28fe-79af-45c3-8a11-1a2a2b54782b")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "68babb3e-a539-42bb-be6b-21aaedabb00b")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/ff8dd6cf-a205-43c4-8cd2-4c561b3f0627")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9a48261a-c120-45ad-a1da-770965e3f776")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "14ca507d-04dd-467d-bbb6-0d3ada664ac6")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "7f943822-42c5-4cb4-bc00-db377c3261cd")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c7a44f36-03d4-4d60-bbc7-eae9e7c9c1d1")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "d33244b9-bf4a-48c6-990b-c232111656c6")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "8ef31b7d-f685-42a8-8a5d-fc50333211d2")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "b6148718-47e1-4563-8114-394c8566c98a")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "d85c90ef-c5be-4b53-9889-1d5c92c7c38f")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "df663dc8-4de2-49cb-8194-fb2f29c96e67")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "55e21753-41c6-48cd-86ba-3ce54f162304")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "255ea05e-c663-47f4-a553-a3024f9ecc5b")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "60f6fd94-168a-4cb4-951b-8cdf02a7dcf9")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "6c06380b-7f4d-4b1a-a6e6-31c5cc048b0b")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ce81fd19-6d97-45e0-8ac3-24088679e90d")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "5d912ae1-60b2-4487-a82c-c943cd07b98d")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "33479773-4738-4708-9e1e-b76b86a10920")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "124d276a-2d22-4115-a9f4-07d21396dbdf")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "af396020-4310-4e0b-8086-c6d18f8d04b7")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "3fcdf2b1-96b0-44c1-b75a-91ce23f9c29f")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "871ad02c-33a7-405d-befb-651b884b2bbe")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 18 "col4")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "a6bb4851-0870-4dab-abb5-1f48abf238d7")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 20 "Net-(D10-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "8c078eba-cf48-4776-b4d6-d2fe8d5de06b")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "5ca1989f-d015-4849-bc68-85122f3ead7a")
+ (at 78.28 97.79)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D11"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "bb186867-4fef-4dad-8610-580fb8edeb1b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "7fdfa381-1ee3-4129-9b94-ca7035c86d40")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "a2947bcc-e9d6-4096-a85a-3f0dc8a2cd5d")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "28eb7cea-a07f-4028-acff-0db33f32307a")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "a5cb67cc-9986-4acf-9336-9f4683e69432")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/92960efb-0266-4005-bd5f-7ae1803b9af7")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "4176c160-10e6-4724-b659-d1cad6588b03")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "54e83edc-f815-4e5d-a318-164fbe424cfc")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "884fbf97-3376-4ad1-93fa-dc496c133824")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e5527c5a-84f5-4336-9ba2-f5adf266ccc0")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "78c2af6a-7f3e-4b20-9a63-d86442235994")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "7dcb1bc9-c679-4a7e-b629-97f09ad49d09")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "44972403-2e90-4711-9e51-3adc7ba27c11")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "769c817a-4f99-42bd-9079-6344efe56f95")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "81efd66f-99d7-442c-a5a5-a22fbe07c0dd")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "fa0ea829-d9cb-484c-9281-875536b69cca")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "87e5d3c8-e9b3-424a-a7fe-9f9db39552e0")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ede6bcd5-9c9a-45c1-a2a5-3ceb22ecd8be")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "7304cb67-fe58-4ff4-be0e-284222f83409")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "a861a4e9-6bae-4de5-be69-6688918ffecd")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "042c25e0-6d34-469c-8589-ca77c55c67a9")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 6 "Net-(D11-DOUT)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "ec915f6b-52ca-42d6-b26d-0aee3a2715e9")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "67b6cf38-32cb-4f97-a0a5-d6af3f03757a")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 5 "Net-(D11-DIN)")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "f7c384c6-805d-4eed-bc56-ba628fd1963c")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "73a15d5f-e3e7-43f9-891d-cb472a7f4c6b")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "6afe5cbc-8191-4d10-9898-221b49b5c052")
+ (at 80.82 102.235)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW3"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "ab534baf-bf3b-4893-a86c-95635a5fba9d")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -2.54 12.954 0)
+ (layer "F.Fab")
+ (uuid "66b3524f-746e-4bcd-9198-d1a43f0e2711")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "e36476de-d0cc-4caf-bbbd-4ace46e091ff")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "47496eec-09ff-41a8-965c-883fe738f1c5")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "30dba0d5-f74e-45c6-8bfb-48009b275928")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/c5f1d131-52fa-4aab-92d1-4f7d6a77768d")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "1d3f6944-38f7-4ba8-a554-dcc0c0401f53")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9df3ca72-d10c-4fda-99ad-f80df9d23031")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "7b93bdd5-c5a3-4a0d-aa41-377a487e1923")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "34709ef3-0586-4c1b-95aa-ce638af4d6c4")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "3cd2933b-c7dd-4f19-acc2-ec140d6545c3")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "b1758c21-449e-45cc-b68c-bd1b336319b9")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "b10e2819-7761-4338-9cf7-9b564adce15d")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "8ca3fb80-c4f3-49f9-a0c4-7ccb9bf7b30d")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "ed49f628-2c84-4c5b-8416-cb7196f575f2")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "ec481661-c7a6-4293-bd39-5ac4d89314c0")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "ce16d4ac-4061-4410-a869-46d376a91c6a")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e656f64e-a3ff-48ca-a44c-c72fcd8853c3")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "905ea28a-f4ee-4866-a1a1-df45c810521d")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "7c7e4972-bb96-4564-a7e3-a1d208a92963")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1c63f2d7-9a6c-455d-b11b-ae71c74ebe5b")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ad7c8b76-1113-4c63-8b76-8ca84f8f5483")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "90aafdc7-2d5a-4239-9d95-76c7f40e42a7")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "6ae47548-f7d2-4891-bdd7-b4def95012f7")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "2b1aa634-a4e5-43e5-bcf6-9be28f46cfdd")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "7c3f6390-eef1-445a-af72-ff74b700f7ed")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 14 "col3")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "40e1bcb2-6d9b-45e3-a318-5739ac78881d")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 13 "Net-(D5-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "afb6fc14-a142-4b74-a0ed-cf0f7c04f1e6")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "6bce9aa2-7748-4157-ba36-ee3282fb0bbe")
+ (at 40.18 97.725)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D1"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "a1b00c65-2abe-41cc-8863-abb4cd2d28e2")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "b0c1df76-67dd-4599-b962-9b5ba83ba6c7")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "6e6359b4-88c3-48ca-a5f9-ffe640a718d1")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "9b76a101-a813-40e2-a2d5-11b6c87ba9a4")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "6029299b-be1a-4e8c-8232-981b1942221b")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/d54e5a7f-7f39-41b2-a0c7-e86fcb28a10b")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "6140b0f2-62b3-40f3-8ea3-af933f62b16d")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "bc387e1f-f8ee-4053-9be0-e24171a86665")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "14b15a08-4f2b-4d9c-a4f3-03c1e1b42443")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "f09ad0a5-5bbb-475a-8b46-a25d325609cb")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "9921a0b2-eedd-49aa-95f3-0e24d1b5e6ae")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e197d134-a4be-4c2b-8c96-f0353f235fe7")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "a1df14ce-377f-4bbc-aa95-ccff1d70dbde")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "4f1c5058-bbdc-45a6-98a6-94f477841170")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ee604daa-db99-4f8e-9843-f6fe47805689")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "5a9991da-4c52-4a36-954f-a0d2146b884e")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c598a615-41e7-43a8-bde7-bf88dae92005")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1f354721-7c56-428e-8e10-4e03e41fd515")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "f102e9d1-7e68-461a-9f35-0d49c6e92291")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "f829f040-5eaf-41f5-9164-b480dcb9ce5e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "acde226e-f175-4d35-9ce6-5da8c6de49a5")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 3 "Net-(D1-DOUT)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "3a718054-fcc1-472c-9d53-b359c9af49c4")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "e5b16c8f-184a-4e2a-bdc9-63baa5c109e4")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 2 "NEOPIXEL")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "21207f95-41b6-42fc-8dc0-74b383bb261b")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "8073e8af-af68-4c8c-9aef-04dda85fb637")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "6d1cac2e-65e9-41d8-b42d-ff8d2cf95034")
+ (at 78.28 116.84)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D15"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "7ce55b26-5cd3-451e-b91d-24c8b2f2afbb")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "c4bd3de4-24cc-4ac7-856a-796e9fde7499")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "30592ca1-a7ce-4ed0-8cc2-90b297636e40")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "8fccc43c-b484-469b-88ea-d4269cd86f60")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "7066850a-2205-4aea-90e2-105a979d7d90")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/ee596f9f-bf74-4da1-9666-bf7b9b49cced")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c626ee64-baf1-4254-a4b6-c1dd726572fb")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "7905e2d4-b8f9-4cff-9d04-db8d34baf68a")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "00bfce3a-e994-4c13-ab52-2bc8ed027bca")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "22dd5a36-0620-4ccb-8997-4445cdfe03a0")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "06bc7e96-da28-4afe-86c2-fd69f689f4a1")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e413984a-9c30-4090-9f24-57eaf0adcbfe")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "b2d21ce8-f499-44b6-bab1-a499071f0d8a")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "035811cb-4713-4c15-acf8-7fa2bdf089e3")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "829cea22-8177-4ec1-a346-7ec7c99155e7")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "58f0c540-5aea-4b72-b97c-f36a8440ab11")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "a40ea2f7-02f5-42cd-a163-9dda8c0a16b7")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "0c14d84f-9e5f-4c15-ab0d-110eb5660285")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "28508569-37de-4acf-b467-9b6b9a3c1307")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "9a847fa1-26b3-4cf8-8186-cdb668f4bbcc")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "5bde5eeb-29f6-460c-8297-74b85b2d6617")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 28 "Net-(D15-DOUT)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "eab0bf53-f738-41b1-8b33-1a0876800e7a")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "d1698d2a-cd3c-446b-bce0-9d8f04d36eec")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 27 "Net-(D14-DOUT)")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "925277d0-2f0e-4b03-9fa3-147d7d58c350")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "75196128-9cfc-476e-b138-f08c34851530")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "6eeebc77-9a52-48ce-9da9-6cb497b29c84")
+ (at 80.82 83.185)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW6"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "72c681d7-4b89-4dfd-9737-2fe421a49b2f")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -2.54 12.954 0)
+ (layer "F.Fab")
+ (uuid "ad8658b4-a5e6-4683-82cc-ed6b47a7b14a")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "cc25ba28-1e5a-4958-866f-27c7925d9594")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "93325404-ddc1-4704-8ba3-a6da7307e26e")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "d1814c3d-bc73-475d-bee2-2437e060b849")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/758505f7-d3d8-4901-9513-5d620fdca2ab")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "7f74f0af-e8bb-4ab8-9e3c-6f298b03466f")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e768a993-9a6c-457c-82cc-c419663ce9d1")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "96cbbfb4-4197-4219-9368-cbd0db53b0de")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "48e5b9eb-7fd4-44e4-85b4-32da48d1a259")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "38acc2aa-ecb6-4e22-b0d0-be2670c61eea")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "342aa784-8324-4666-9465-8f3e4322e6c8")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "f7a68bbf-7373-4cb8-8736-e9e1ada7c947")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "f3f30046-f173-4630-af2b-56f14f6f930e")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "219c7d52-1c20-47f9-826f-0e2599e6edd8")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "8bb573db-6c76-43bf-8d86-3786e2f003e7")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "4d607dbf-c4a5-43ba-aa0f-6916caa489c1")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "2b63b9dc-6470-442c-aa72-beb9c80ba589")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "efe9e44c-6c42-4ad8-a9fd-32a6e7756eae")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "623f5024-e55d-4f1c-aa9f-af56c8ab64a4")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "78914ee8-725a-4590-b608-e4bdbd809832")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "de433380-5c3b-4721-bc07-34dacb8f97b2")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "c9ab11d9-f925-4b97-ba14-e5ff4eae678c")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "4953aace-25f0-4a99-855c-58c86e3f1f58")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "b9cabeb8-122e-4e6c-b0d1-f2f8fcbf161d")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "c98fc875-feb8-4e40-aecc-ae02900b59a7")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 14 "col3")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "911d1efb-b838-48a8-898a-b8e247199a4c")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 17 "Net-(D8-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "72188047-daec-4160-b7d4-d1daddb746c2")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "718d7ee5-0b1f-49b8-850b-341ab422d0ca")
+ (at 68.705 111.365 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D4"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "2ed4516f-f910-40fa-9680-fb4e313e504f")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "202d0168-5bdf-4181-b376-2591f5eeadf7")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "d9b4ad5e-461d-4e1e-ae45-05899b6b743c")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "685df99c-dd47-4154-8f5b-e435f6c39fc6")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "fbb7761c-bba7-4282-a5e0-fd932512f9a2")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "43bd6fb5-be48-43dd-94fb-b38875c75398")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "55b33ced-0cfc-461f-8bcb-e5dd91f0600c")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/4e988283-ea88-4926-a401-acf7a0415ab1")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "fb982846-edf3-444c-9c59-e80f01b415dc")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0127dc0a-92cd-4a31-b848-6927b3b20551")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0510a3f0-21a8-46b0-ba83-ff9b1a7c7b52")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "8e8a63d9-a761-4f85-94c6-112746e981cc")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0d5599b1-6fa7-4ca0-86a4-e3636971c1ac")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "15eda833-f259-4d14-a3c2-b002bd525fbb")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "f1a79e02-8e2c-452d-8a2f-2598c92f1f38")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "a097c039-f801-4ea0-bb4c-6b97a48cc2ff")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e7f7f6cc-fbdb-492f-8557-07ad556a88da")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "ad458ace-d283-49fb-93e6-c06e5d62f559")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "2e202359-0b37-417f-84a3-e10d80801f84")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "688696f5-34cf-430e-9af2-1d851af05a6f")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "ba9668ac-5e22-46d1-8b90-097ebd954678")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "bebd7f59-7c99-43c4-b147-dd0c958ad919")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b763877d-ed99-4ee4-ab43-e5c162d740cc")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1f81bae8-5a62-45ca-9cd7-2692e6cdbceb")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "05e753da-f013-4086-abdf-0d3fb5303a68")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "00c2539f-0dad-4ee9-b707-e28099ae3b1c")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "dd74612c-c0d7-4174-bd53-748bd51b6ef8")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ba8d3c8c-97ee-4aee-b57f-cf13f66dcc6e")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b28c4349-844f-43a1-8d14-270fb568919e")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "e601afa2-686d-44f9-9553-74875917b92e")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "64f25fba-7233-4a22-9dd7-d750481fb16f")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "72cbedcb-f96d-4dd8-a4f0-3e1c89033e32")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "ed4f3226-7f14-459c-869d-410900f37a46")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 21 "row2")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "0270ba23-ab01-4a78-b091-04d9dd71c5ab")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 12 "Net-(D4-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "599e29ea-e3d8-48c0-95d9-7427e2ec1080")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "73a83eaa-3bbd-41b7-9fd4-c48b0a7a3376")
+ (at 97.33 92.235 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D9"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "edfa6920-0a52-4d02-ae06-e8c0ab8e1b96")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "d2846827-519e-4a90-97ba-cd2647ba8e6e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "fc8e6dd2-e9dd-4863-a7c4-b6df8d9f5a34")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "5eff59e8-34bd-4ec4-a6ac-74ddcaf0f796")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "c493d969-46ca-44b3-a5c5-df79132b09fb")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "7f2303db-d5d4-4303-bf42-86fa55c4a24e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "2b573892-459e-4c1c-8970-33bbadaf501e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/492b14a3-196e-491e-8781-0d6aedc31079")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c5ff6eb1-4cc0-463b-9a2e-06e06cb39b0a")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "89e70472-7b1e-4dc6-935b-ce39a1b69918")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "861f473d-de70-4d9e-927c-41eda4ef8367")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b45de780-111a-43c3-a889-2e2c3b235f74")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "92202b04-6085-49fa-a628-3a5f896b4604")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "75abf829-5283-444f-8da3-fd6530c46b03")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "ef658d03-ea50-4a01-abf8-50f165f25fe8")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9d87a075-24ec-4882-b964-905b30957b70")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "87eaea0a-988e-4421-814c-e183f2ae68f9")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "d5902a65-97fe-41e9-97b8-5b26d5b7538f")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "d8461768-2c9f-4eaf-99d9-cfd84daf71e5")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "aba5fcf9-86b0-4cf2-9c77-af52fd443a8e")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "6b5cff98-1f14-4c58-a5a0-873a0b8bb023")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c0934932-74f3-4171-a5e9-2e605eecd2b0")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "0e2f5b47-50d6-47bb-a64c-6ddb06aa6966")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "fde8db9a-94c1-4c1c-80f9-c95d915628d0")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "7d678357-c94e-48f4-9198-6db3c45d22ef")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c0d74142-52b7-45e0-9910-ddd782ed2475")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "d2462143-b756-4eeb-9529-19ce42399a76")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "5c3436bc-4ce2-42cb-b07a-7ec2b22fe4cb")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ba743340-3996-40d3-8fdf-6a2e2b774b12")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c5b88083-ff27-4bf1-9818-4d2467540cbd")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "dc3c9c57-d620-443e-8cd3-20a28c887bdf")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "b682b505-3647-4bf4-b6f5-02402c35d655")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "cc1cb4ec-51f5-4879-ad45-14e49c77d180")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 22 "row1")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "f39f3543-38f7-407d-98df-8ac1a7c859a7")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 19 "Net-(D9-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "448e1088-ad97-4041-a529-84ae98c51b11")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "821ddc22-0ac5-47d3-9e57-09afea9388fe")
+ (at 97.33 111.345 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D10"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "246e6fc8-91f6-4200-92c3-5e43ce697dcb")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.4375 90)
+ (layer "F.Fab")
+ (uuid "8bf1d4f3-a7f9-4eea-9118-4dcec7e56f15")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "4e456140-0207-49b5-a8e4-b77e2c8b6870")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "f238ed57-c03b-45c0-893c-6efaa6df4cc2")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "5271da28-c167-4711-b748-74b0f76cc503")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "f1c4a3f8-e80f-49d7-a95a-6d668473da28")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "ead4b776-9d28-4ca5-874b-17f6a2206838")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/ac02af9b-38a1-4956-b4e5-3c84756921e8")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c2fb1b76-1d27-4a23-b027-8c9d2868a2ac")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "8f93260a-8138-4d1e-b8e2-4b3ccb665ce8")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9f1b6a9d-e855-4f52-865f-5c74b82d24c0")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "6e5ec6ab-2c7d-4253-9e6b-84424af6b910")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "cc695376-47bb-47bb-9c3e-312753a81b1c")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e0244ee8-cdf5-4b23-a39c-5adea48436cd")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e7326958-f16e-47b0-8654-de85ccd3d338")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "d7805b62-674f-4c94-8f73-264b0a1bb57d")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "ec7ca5e8-429b-43b6-89fb-4efc4cbc83c3")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "b0cdf489-cd72-4625-9b12-8b4308ea4098")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "de9759eb-8a50-4ab6-af1d-c47a8440e18d")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "8bf5b61a-9568-451e-b79b-0a23625b9c8c")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "0f80526c-5bef-4744-88d3-8ec92ba2f985")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "cde88fe7-bf2a-4eb7-b995-a02129ead0be")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1d91e513-8605-47b8-ae42-17df1848d35f")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "204d01c7-6317-43be-864c-05f8e22f99df")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "4deca5f9-40e0-47f2-bae0-0ab415e6b0ac")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "20263b7d-25f5-4de6-a459-c7eba0a5b730")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "6863e79b-1458-4bab-938b-4758c2b06d92")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "766a7509-4ee4-4e83-9f4a-75d85cafa786")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f18d602e-e148-4d68-ace7-77002569eb94")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "de58b478-5679-44cb-afca-db1ee206c4e6")
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "4bf5c634-9325-4a2a-8c3f-2e575316b3f6")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "fd21b42b-aa10-419a-9582-06910a5a5c1e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 21 "row2")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "c7499220-fd90-461b-844f-2aeb3ec1471b")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 20 "Net-(D10-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "9af1be36-3723-44c3-a8b0-18e0f531d51c")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "ScottoKeebs_Components:OLED_128x32"
+ (layer "F.Cu")
+ (uuid "85d6685c-cf07-4816-bc60-e8324770d987")
+ (at 53.295 62.105)
+ (property "Reference" "J2"
+ (at 7.75 10 0)
+ (layer "F.SilkS")
+ (hide yes)
+ (uuid "9365d19f-fc81-4ae8-b590-928f3fef3b06")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "OLED_128x32"
+ (at 5.75 5.75 0)
+ (layer "F.Fab")
+ (uuid "519d279b-bfad-4880-8f21-f76cd6720113")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "ScottoKeebs_Components:OLED_128x32"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "2e7696c1-1a77-4613-ba6b-56b395302558")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "ad2c62f4-1f3d-4c49-b711-b002f6fee476")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "8ef5eeb4-1eaf-4a4f-8d9c-fb782de4a757")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/55d70023-2f4f-4dd3-9cd5-34beea9f5bfe")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole exclude_from_pos_files)
+ (fp_line
+ (start 0 0)
+ (end 0 12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "e20c6952-6ba0-4e18-b9d7-0814b5576beb")
+ )
+ (fp_line
+ (start 0 0)
+ (end 38 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "a939661a-7136-45aa-be94-11a2eae88bbf")
+ )
+ (fp_line
+ (start 5.75 0)
+ (end 5.75 12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "b01c9166-5924-4a3d-8e1f-639a35ee6e0a")
+ )
+ (fp_line
+ (start 7.06 2.22)
+ (end 7.06 7.74)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "5ad62415-acca-43e9-837e-141df771526e")
+ )
+ (fp_line
+ (start 7.06 2.22)
+ (end 29.44 2.22)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "7ac3cdbc-6421-44fb-87e3-62e936dfa5d0")
+ )
+ (fp_line
+ (start 7.06 7.74)
+ (end 29.44 7.74)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "dd89928e-7cfe-4ee0-bcdb-6b7629849369")
+ )
+ (fp_line
+ (start 29.44 7.74)
+ (end 29.44 2.22)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "5eaea357-a779-4430-8426-a487b9b21c17")
+ )
+ (fp_line
+ (start 35.75 0)
+ (end 35.75 12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "1add5625-06cc-49af-bc25-963be1fbd762")
+ )
+ (fp_line
+ (start 38 0)
+ (end 38 12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "696a6435-c3c9-48f9-a997-b48695111f35")
+ )
+ (fp_line
+ (start 38 12)
+ (end 0 12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "501d0638-50a6-4174-8c36-70f7846dd94f")
+ )
+ (pad "1" thru_hole rect
+ (at 1.6 9.8 180)
+ (size 1.7 1.7)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 4 "GND")
+ (pinfunction "GND")
+ (pintype "power_in")
+ (uuid "68cfb900-f4b1-4623-ac88-50b21d772cf3")
+ )
+ (pad "2" thru_hole oval
+ (at 1.6 7.26 180)
+ (size 1.7 1.7)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 9 "3V3")
+ (pinfunction "VCC")
+ (pintype "power_in")
+ (uuid "c84d1895-915c-48ff-9f00-08ed2d5ee5cc")
+ )
+ (pad "3" thru_hole oval
+ (at 1.6 4.72 180)
+ (size 1.7 1.7)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 8 "SCL")
+ (pinfunction "SCL")
+ (pintype "input")
+ (uuid "160c88a5-a114-4f08-a3fb-c814a3aad3dc")
+ )
+ (pad "4" thru_hole oval
+ (at 1.6 2.18 180)
+ (size 1.7 1.7)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 7 "SDA")
+ (pinfunction "SDA")
+ (pintype "bidirectional")
+ (uuid "789d3010-f469-4246-8580-134a1dfcd95a")
+ )
+ (model "${SCOTTOKEEBS_KICAD}/3dmodels/ScottoKeebs_Components.3dshapes/OLED_128x32.step"
+ (offset
+ (xyz 19 -6 2.5)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "8bac1b76-36e4-48cc-932f-539feaff9457")
+ (at 40.3925 116.84)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D17"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "2a087d40-75aa-4b9d-9745-4d37d93c2f4b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "d9139622-37d7-4c3f-88ad-196803a4088e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "118feb60-54b8-4217-a4e4-9bdcb377e2ad")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "d9f7d9fe-865a-4b0f-9de2-7fb7dcb04ca0")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "57b8de4f-3b79-416e-8ad1-f8c825b95a0a")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/f4b5d257-d254-4ca9-8510-b7d538e00f6e")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "336fad22-7f42-4edb-b0d7-54e2f329e629")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "4c8f705a-5f36-4ea9-b41d-67ef2a6599c8")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "4d3fc2c6-c0f9-40b1-81f2-505f040cb9ec")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "4de780f4-c2b1-4479-8568-c237bde7147e")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "a9b7ccbf-4bfc-41be-ae6e-d41e27427d2a")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "ec4df499-8386-42e2-b323-a6797b7dab66")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "2675d3b7-bc4e-4105-897d-203b9cf34587")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "4da20ce4-1500-450a-9dc3-5b993d338fcf")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "9ef1eab5-886d-44e8-8d84-bb0e2b5b0a18")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ae3c9157-819a-4d61-a534-41683a4c2a82")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "e676791c-2430-4267-b486-4aa51986c259")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c2cc1ae5-66b4-41e5-bfd3-7a367c454b29")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "e35f4803-9225-4c76-b3ed-15e2cb501929")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "034186cb-237e-425d-aa85-9765d36c37cf")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "1783232c-d683-416f-8bc4-a53bc3b83647")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 30 "unconnected-(D17-DOUT-Pad1)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "84ad5f2c-8292-41ad-9c50-696e9dfbe449")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "6a02cb83-8bc4-4bd8-a6f4-6b1f79289a66")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 29 "Net-(D16-DOUT)")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "6b4b15f6-0728-48cd-8911-06b830ba6b00")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "57f2c916-16ed-4589-bb24-1365daedbabd")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "93146d38-658e-4f12-8b8a-96178cfa0384")
+ (at 42.72 83.185)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW4"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "3f546249-bec1-4719-8846-75416c9a3578")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -2.54 12.954 0)
+ (layer "F.Fab")
+ (uuid "26f37e44-13f2-4831-a2d7-cbe369cbdd5b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "1693faa1-5d85-4aaf-a53d-344a19a608ef")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "e51a8d20-4524-4e0f-b6a3-e2c09907efe8")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b098e28e-5c6d-4790-aadc-695f10fafde2")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/5f4c010a-8b72-4d09-b514-c1bed217a028")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "ba21cc00-7a9d-4e09-8f8a-d06f96c6298b")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e5886e30-f9d5-4c28-a883-b80967ab5511")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e7aac9f7-1adf-4a9e-9145-a5c290a9d4d9")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "f3221518-dcbd-4988-9aef-7e6ee1ee12ba")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "ffa799fd-ad3e-4c4c-8da2-21177a0393a5")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "a465918a-3b7b-445e-88e2-e7db5acd9457")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "d730f345-aba2-4d3f-a1fb-dd5b29b67c41")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "b8170f1d-0106-474b-8856-9d3cb8237eb8")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "dd63e032-0d20-4676-992e-2bd8f86e6502")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "1f99a120-39c2-4bc9-944b-153f39f0f172")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "8b2bf216-5488-4e0d-8d8a-65c41fda1ef3")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "7169d4b8-91ef-4852-beb2-2f14cba1a869")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "7df7169a-8f38-4cc9-9dd2-bfe4c1f213bd")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "a34723ec-4a7c-4dc8-b604-500f305c70fe")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "9ebb41ae-b611-4ef9-9539-efa8581895b3")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "50ec2314-f143-42e4-af5d-625fef3a2283")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "1ca530eb-0950-4220-be8f-2b4b0b2356f4")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "49d98d86-5eeb-41cc-9465-91ee1938658f")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "285f89ca-2f69-4d1e-be94-2aab622c2a07")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "a349dcc6-9300-4a78-a199-a48af78c69ce")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 24 "RINPUT")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "1b18fae0-183b-448c-85fa-53afb54c8ee0")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 15 "Net-(D6-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "f45fd00e-419a-4075-8d34-73e450a38ab6")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "960c91f0-e41b-4f41-9ce5-04c6ba701ed9")
+ (at 59.23 116.84)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D16"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "26ee7e86-e564-4563-ab9e-fc70ed23bc55")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "3e03bbe8-eef0-421b-a753-3c33a82cf293")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "835099d1-ccec-49f3-90a4-c20b631925b1")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b41f1f8b-7600-4717-afb8-dd9446df5a1d")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "e95538c5-4b06-4426-b347-71a29c1e53ed")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/f5eb316a-048e-4ccd-b0dd-9ce11e5a2036")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9f599367-0e46-46af-9100-059a0078c9cd")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e8a11bbd-d64f-4e1a-a243-663d451b12f0")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "7fbcd5c5-6d04-4eba-9c59-316ae7458b95")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "007bbaf0-3dc0-40c0-b433-d87adf2c6bd7")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "9bab1b88-84db-4fac-824d-274303769a3b")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "d12e8014-ec0e-47b2-a8e4-c4e4b1af63bd")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "fad2d297-699e-4f1e-9195-4ac7d844a8b9")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "9763d2ac-125e-4dae-94ea-bca9c5db76aa")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "3bf21419-7fe4-4c80-a04b-f0c1600f4372")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "46656c03-ef15-46c6-a4b7-7b5dfce5a27b")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "e6c2a864-93bc-433a-a6d3-70ca8c0c3d96")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b23fdd5f-0567-4c40-9ad1-d4a263debc20")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "7f1c00ef-76a3-46ea-a71f-aacc3545fb68")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "92f4c3dd-dfcb-4112-9eba-495e5d2f9015")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "a3bf1fd1-0a52-4e10-bfab-aa90fee8569d")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 29 "Net-(D16-DOUT)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "7428a131-21ee-40fb-a326-9cc14e0f8fa4")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "0ad7cc9d-813d-4b6d-ad73-b5bd58800150")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 28 "Net-(D15-DOUT)")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "0619273f-d08f-4fdf-868b-27eaa919d451")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "0b8d32f6-cecb-40c4-a87b-53019d91afd4")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "96adb5d4-ac3b-4cb8-a431-fdba793ec0d9")
+ (at 94.415 72.745 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D12"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "8b0a8ddd-2815-4cfe-aff8-be314d6fddc9")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "7c19b220-2e07-4156-b93d-9cd52ed1540b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b8e8ae93-2b2a-4870-ab61-dc224ff4501b")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "593871e7-4a0a-4cc6-b3e0-4ab4c5936a5e")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "5f3ff987-1e93-4aa7-939d-3a1703c70e9e")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "9e724cdf-1555-4f7f-b1a9-978945710407")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "eab2f0fe-35ee-4ec7-b53d-8390a2a05187")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/d2757a62-5fd6-436f-a272-edfa97e09620")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0c345471-79d7-4f00-ba5f-89f65403a56f")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "5397f66e-88b6-4c65-9c15-ed7a9fe8a679")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "500ef684-b155-4fcc-87fb-3b24328c8a4f")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c77874ed-286c-49d1-91c8-137171a263c7")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "ba5da4c9-605a-4b5f-89fa-54ba9ee262fd")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b806f257-3994-495f-a285-803961cc54a9")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "74c320b3-dd49-4b0e-a280-6a943408607e")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "bea0b8b3-2530-4ac7-8dbb-b8a15a463550")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "acfe99f3-71b7-4b29-a506-44cc73f32be2")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "e99d2348-a402-41c3-a81f-8f1ba83279aa")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "06b551be-b8b1-4541-a30e-7dfaf338b86c")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "a6e566d5-d10c-402e-9d7c-96f9e0b70684")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "1ee3f40b-3c73-4e51-837f-48a2d8b09b1d")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ac187709-ee24-4e27-a0bc-7eb5f255e384")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "b32f0a10-983c-4d97-88cc-3f9d4c5ad055")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "0683f93e-2ccf-490c-a5c3-1d2c48f12b2f")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "bfccf5d3-16a9-49ac-b5e0-6ed80f9e661a")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1f0917ec-2865-460c-8b27-8f0ca45b78df")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "45ff2dc1-2346-45fd-94ca-e2b621fa0f5e")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "25118eda-097e-4459-8d4f-8759b7f8ce9a")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "95033819-0423-4d47-82df-f93de9c365ef")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "66a441da-9c50-4caa-ad6f-eac0447b5b88")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "fd896ae8-fff2-42de-bc11-26ddc3b1e8d5")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "27b4a4c2-98c1-473a-a7b9-94c2b8354541")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "d851706e-3d40-4ab5-9343-2056c6245fce")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 22 "row1")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "94aa06ba-8eab-4533-966a-dc8fc7b2fb23")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 23 "ROUTPUT")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "8460a113-42bb-4d13-8a58-87462df22df6")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Rotary_Encoder:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm"
+ (layer "F.Cu")
+ (uuid "98c38131-8248-4aff-ad97-9d3b124f908d")
+ (at 99.535 65.605)
+ (descr "Alps rotary encoder, EC12E... with switch, vertical shaft, http://www.alps.com/prod/info/E/HTML/Encoder/Incremental/EC11/EC11E15204A3.html")
+ (tags "rotary encoder")
+ (property "Reference" "SW9"
+ (at 2.8 -4.7 0)
+ (layer "F.SilkS")
+ (uuid "2d86e4e0-866f-408f-858f-96d5526d023f")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "RotaryEncoder_Switch"
+ (at 7.5 10.4 0)
+ (layer "F.Fab")
+ (uuid "7ccbcc02-6d22-4069-afe9-e53124b16729")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Rotary_Encoder:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "eef2883b-9f2e-4a2a-a376-25431f3d0edb")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "7f27e42f-d875-481e-95ee-11a9dc49fffd")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Rotary encoder, dual channel, incremental quadrate outputs, with switch"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "d4f51181-3f6c-4304-9b56-002ccddea151")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "RotaryEncoder*Switch*")
+ (path "/1f3b652e-8c8b-49f0-b2ef-8372bc3bab18")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -0.3 -1.6)
+ (end 0.3 -1.6)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "48652801-3c79-4d8b-b0b4-41ab9f774762")
+ )
+ (fp_line
+ (start 0 -1.3)
+ (end -0.3 -1.6)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "976d90ed-9cf9-4aeb-ba09-9c6048f4115a")
+ )
+ (fp_line
+ (start 0.3 -1.6)
+ (end 0 -1.3)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "626ea92c-caed-4a69-918d-6fc73403cd19")
+ )
+ (fp_line
+ (start 1.4 -3.4)
+ (end 1.4 8.4)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "d6484d87-265c-4467-927f-01eafc17cf58")
+ )
+ (fp_line
+ (start 5.5 -3.4)
+ (end 1.4 -3.4)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "259d3317-6f03-4e75-9cfb-4802050c1377")
+ )
+ (fp_line
+ (start 5.5 8.4)
+ (end 1.4 8.4)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "7d023cc7-0a82-45c2-bb16-1fee04993749")
+ )
+ (fp_line
+ (start 7 2.5)
+ (end 8 2.5)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "47141eac-9c97-4012-830a-1575e20145a9")
+ )
+ (fp_line
+ (start 7.5 2)
+ (end 7.5 3)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "2990fa3e-909b-47e6-a523-7c09272a9e83")
+ )
+ (fp_line
+ (start 9.5 -3.4)
+ (end 13.6 -3.4)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0b0a6a08-efef-4965-b722-91aefce2d084")
+ )
+ (fp_line
+ (start 13.6 -3.4)
+ (end 13.6 -1)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "8325aa08-15b4-4af2-8bcb-ded52103bd58")
+ )
+ (fp_line
+ (start 13.6 1.2)
+ (end 13.6 3.8)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "4dcb6eb9-d0d4-4701-b558-5b11a1dfe2ec")
+ )
+ (fp_line
+ (start 13.6 6)
+ (end 13.6 8.4)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "5b7438bf-91e6-4f50-9848-408b8807512d")
+ )
+ (fp_line
+ (start 13.6 8.4)
+ (end 9.5 8.4)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "33cb1365-cd41-4da0-bde3-db2269482693")
+ )
+ (fp_circle
+ (center 7.5 2.5)
+ (end 10.5 2.5)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.SilkS")
+ (uuid "15f4f0fb-3329-4e57-9176-eb5b4cf7fc5c")
+ )
+ (fp_line
+ (start -1.5 -4.6)
+ (end -1.5 9.6)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "86754928-2ecf-4b7f-8c57-6c305466231b")
+ )
+ (fp_line
+ (start -1.5 -4.6)
+ (end 16 -4.6)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "0b11bb71-1ac0-4b08-a7ec-ab4105bad21d")
+ )
+ (fp_line
+ (start 16 9.6)
+ (end -1.5 9.6)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "77ad0108-d1fd-4e60-ab93-7610a2ea8d3b")
+ )
+ (fp_line
+ (start 16 9.6)
+ (end 16 -4.6)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "a358bc76-5935-4de5-90f1-6cdf62fadc49")
+ )
+ (fp_line
+ (start 1.5 -2.2)
+ (end 2.5 -3.3)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "3adf693d-61a3-44a9-850a-6b4b8b03f201")
+ )
+ (fp_line
+ (start 1.5 8.3)
+ (end 1.5 -2.2)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "478076ec-ce14-495a-ba38-650b9a002260")
+ )
+ (fp_line
+ (start 2.5 -3.3)
+ (end 13.5 -3.3)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1f59e833-8a4c-410e-876f-2965872dca8f")
+ )
+ (fp_line
+ (start 4.5 2.5)
+ (end 10.5 2.5)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "86d5a0d5-1b1f-4226-8ad1-126bc6cb03c2")
+ )
+ (fp_line
+ (start 7.5 -0.5)
+ (end 7.5 5.5)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "0455bf6f-3c40-4771-a1a2-d72fd15e9dbf")
+ )
+ (fp_line
+ (start 13.5 -3.3)
+ (end 13.5 8.3)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "3cf80e99-57fa-4019-a0b9-8fd068b5e03c")
+ )
+ (fp_line
+ (start 13.5 8.3)
+ (end 1.5 8.3)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "9d7f09fc-92dc-4b4a-ab12-45755c5164b5")
+ )
+ (fp_circle
+ (center 7.5 2.5)
+ (end 10.5 2.5)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "58d35c42-8c7d-422d-b23c-50b57435c44b")
+ )
+ (fp_text user "${REFERENCE}"
+ (at 11.1 6.3 0)
+ (layer "F.Fab")
+ (uuid "1188831a-280c-4dc5-a3a8-0596f1974b36")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "A" thru_hole rect
+ (at 0 0)
+ (size 2 2)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 26 "EC11B")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "2cc6f930-5e58-4e78-8a4a-524102973320")
+ )
+ (pad "B" thru_hole circle
+ (at 0 5)
+ (size 2 2)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 25 "EC11A")
+ (pinfunction "B")
+ (pintype "passive")
+ (uuid "e2fb3e85-f86a-4242-8083-fb9c9c8bfc68")
+ )
+ (pad "C" thru_hole circle
+ (at 0 2.5)
+ (size 2 2)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 4 "GND")
+ (pinfunction "C")
+ (pintype "passive")
+ (uuid "48ecb0c9-52c7-4093-8cc8-53ecaf2a5186")
+ )
+ (pad "MP" thru_hole rect
+ (at 7.5 -3.1)
+ (size 3.2 2)
+ (drill oval 2.8 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (uuid "35f40f6d-92a5-48de-a1f6-22cf831b0774")
+ )
+ (pad "MP" thru_hole rect
+ (at 7.5 8.1)
+ (size 3.2 2)
+ (drill oval 2.8 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (uuid "14f0413d-4c26-4828-9b09-f69d60f854a8")
+ )
+ (pad "S1" thru_hole circle
+ (at 14.5 5)
+ (size 2 2)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 24 "RINPUT")
+ (pinfunction "S1")
+ (pintype "passive")
+ (uuid "90693088-711d-4091-a211-cd19244a443b")
+ )
+ (pad "S2" thru_hole circle
+ (at 14.5 0)
+ (size 2 2)
+ (drill 1)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 23 "ROUTPUT")
+ (pinfunction "S2")
+ (pintype "passive")
+ (uuid "f96972ac-c1a0-4d33-bf19-b7cf1d3f0449")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Rotary_Encoder.3dshapes/RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (layer "F.Cu")
+ (uuid "a62dc78c-b5c7-4ee5-91fd-68fb19a1ca39")
+ (at 61.77 102.235)
+ (descr "Cherry MX keyswitch, 1.00u, PCB mount, http://cherryamericas.com/wp-content/uploads/2014/12/mx_cat.pdf")
+ (tags "Cherry MX keyswitch 1.00u PCB")
+ (property "Reference" "SW2"
+ (at -2.54 -2.794 0)
+ (layer "F.SilkS")
+ (uuid "602b7923-9117-43d8-adb2-d94a633a124a")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at -2.54 12.954 0)
+ (layer "F.Fab")
+ (uuid "85da86e2-6dfe-43e5-870d-4ecdb5ea9287")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "eb7ca1df-c645-42fe-aee0-8a0aef1ed629")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "649e1c9c-23c3-4ee8-a7aa-30d38cd748ef")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "f33fc17c-b2ac-4441-8ca0-0c3b5ced0f62")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/c222d41d-1ea9-43a3-bed7-12de2759d5b3")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start -9.525 -1.905)
+ (end 4.445 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e60751c0-b047-434d-af20-64977884840f")
+ )
+ (fp_line
+ (start -9.525 12.065)
+ (end -9.525 -1.905)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "274473a4-b50d-4368-a5ec-2dc51b08c08f")
+ )
+ (fp_line
+ (start 4.445 -1.905)
+ (end 4.445 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e0514019-6636-4c68-b347-cf1b7afacd92")
+ )
+ (fp_line
+ (start 4.445 12.065)
+ (end -9.525 12.065)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "43f5e4d0-360c-4f01-ba5e-d7c9ab7de6ec")
+ )
+ (fp_line
+ (start -12.065 -4.445)
+ (end 6.985 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "99a6d5bb-a70b-4f64-81ca-256c938cc7b6")
+ )
+ (fp_line
+ (start -12.065 14.605)
+ (end -12.065 -4.445)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "701b6fc8-128a-454a-876e-48e67691e704")
+ )
+ (fp_line
+ (start 6.985 -4.445)
+ (end 6.985 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "3c06d162-5d79-4968-aeee-483cad1537e0")
+ )
+ (fp_line
+ (start 6.985 14.605)
+ (end -12.065 14.605)
+ (stroke
+ (width 0.15)
+ (type solid)
+ )
+ (layer "Dwgs.User")
+ (uuid "ff6b0c6a-12f8-4a9b-9e64-c933d3f9d28a")
+ )
+ (fp_line
+ (start -9.14 -1.52)
+ (end 4.06 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "b3a1f6cd-4f39-4eb8-b63f-07cfa8096460")
+ )
+ (fp_line
+ (start -9.14 11.68)
+ (end -9.14 -1.52)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "c6882147-0456-4cbb-bb31-c91ac19ac950")
+ )
+ (fp_line
+ (start 4.06 -1.52)
+ (end 4.06 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "9de7d9d0-5521-4863-93fc-65ecfc27fe81")
+ )
+ (fp_line
+ (start 4.06 11.68)
+ (end -9.14 11.68)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "3454e0c2-d134-45d7-b488-4384063d31e3")
+ )
+ (fp_line
+ (start -8.89 -1.27)
+ (end 3.81 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "6100ca0b-5e80-4e32-ae12-e947eaa98d76")
+ )
+ (fp_line
+ (start -8.89 11.43)
+ (end -8.89 -1.27)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f207b9a0-80ad-438c-af2f-aad0041aade5")
+ )
+ (fp_line
+ (start 3.81 -1.27)
+ (end 3.81 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c6b41cf6-0fb3-457e-95af-ad4d0cbc80e6")
+ )
+ (fp_line
+ (start 3.81 11.43)
+ (end -8.89 11.43)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "17ee8657-178a-4cdb-8a87-2c9e0dcbff4a")
+ )
+ (fp_text user "${REFERENCE}"
+ (at -2.54 -2.794 0)
+ (layer "F.Fab")
+ (uuid "b7675f49-05f7-4ba0-8a68-965a9bd6003e")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "" np_thru_hole circle
+ (at -7.62 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "08560537-02bd-48f2-aabd-50419dc6deb2")
+ )
+ (pad "" np_thru_hole circle
+ (at -2.54 5.08)
+ (size 4 4)
+ (drill 4)
+ (layers "*.Cu" "*.Mask")
+ (uuid "80f88bba-24a8-4c57-83c3-665664749755")
+ )
+ (pad "" np_thru_hole circle
+ (at 2.54 5.08)
+ (size 1.7 1.7)
+ (drill 1.7)
+ (layers "*.Cu" "*.Mask")
+ (uuid "bd54332b-d38c-44c0-8a87-46d1a1036077")
+ )
+ (pad "1" thru_hole circle
+ (at 0 0)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 11 "col2")
+ (pinfunction "1")
+ (pintype "passive")
+ (uuid "9c17e9c4-e154-4347-a499-730b6c6d30ca")
+ )
+ (pad "2" thru_hole circle
+ (at -6.35 2.54)
+ (size 2.2 2.2)
+ (drill 1.5)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 12 "Net-(D4-A)")
+ (pinfunction "2")
+ (pintype "passive")
+ (uuid "ba300425-46f6-4e1f-bf88-9389f30e3825")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Button_Switch_Keyboard.3dshapes/SW_Cherry_MX_1.00u_PCB.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "a86c1ea8-17d2-430e-83e5-42723ee521ae")
+ (at 106.855 97.79)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D13"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "c32d5780-3a08-45e7-a499-f78aeb03d5c2")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "32293a99-46c6-486b-a8cf-a86e9747e695")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "bb6a57d3-ac34-4b3b-955f-380d8713a7c5")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "c68adc7d-3a98-465f-86ad-dc059a9ea094")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "00e326e9-849b-443e-8a15-ab81d70b8a8a")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/d7e2a864-424f-46fb-b7ff-7fca8ee5a421")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "505e3884-ffc3-477a-b1c0-bf133c3a3d59")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b5d08171-4429-4964-996d-82ae497f3288")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "bedc17ad-91d5-41f8-ba7d-bff5c83dff61")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "adf40ce7-a87b-4e8c-9edd-19cee3780780")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "7fc5ca83-3ce2-45c9-b8a3-b1c784a22782")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "c28b300e-5169-43e1-9630-715e607b719f")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "83e76327-7e60-4de1-b634-53a5123000ef")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "3a3f3de0-96ea-4902-aa48-1702f8c65a22")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f62c6528-a1ab-4b00-82b9-0473b4288461")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "0a98f79f-24a2-4ce2-af1d-4628fc79e3e6")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "a65ffefa-c6cd-4a7b-b08b-fc642df9b91c")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "6a965fa2-5544-4295-ba3c-cebbc95d282e")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "7350ecc5-e0a2-4573-bd34-7efb724da986")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "11afeecb-5533-43e0-855e-fef75567db3d")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "ac01b331-fe93-47c0-83bc-2738d55168ec")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 31 "Net-(D13-DOUT)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "30357cb7-d54a-46a0-93eb-9d74ba88c199")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "e07ec879-d73c-4bae-9e89-f13d5ae792ae")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 6 "Net-(D11-DOUT)")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "bd25cffb-0f15-456d-bb3d-3c556a452ccb")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "b92f4987-4141-4eb8-9ab9-c7be9d52a1a0")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "ab34cc27-e556-4f7e-8144-f739f4517739")
+ (at 49.725 92.185 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D6"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "9bb04749-9be5-4058-bc0d-2458a2f8826c")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "103667b8-f553-473c-80e4-144b3a5e4446")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "3c1d2335-9e8c-4a39-88a5-1076e019ef5d")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "22d92657-b435-4010-a755-6767fa01337d")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "0bbe035b-e9c6-4fec-8ebb-f66213d9b9b3")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "b856ef5f-0193-4a3d-b721-f10a1ec8ebe3")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "48d4b7c1-23c6-48ad-9f19-8e7202bb785b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/9beb8400-f418-49d3-8d9b-ca8a6e3d55a9")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "c0881f15-5953-4eb5-b649-ee620bb66c33")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "8849c905-114e-4e6b-b5d2-47e0b0dab820")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "3fb5ff3a-9994-4898-82e9-666d8a1e0d27")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0f1a08d8-8a4b-4fff-9cc6-724f102d7bdc")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "6e4265bf-b3a4-4981-9020-d7db5ca47588")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e525e8ce-9225-4ebb-b46a-9644dc1ef955")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "dd351a11-e981-498f-b70f-7875adc2569c")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "797de5d2-99ff-40ed-a144-9373dd798a20")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "afe37023-18ed-4230-81aa-de087dbdb0fb")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "fbd58fbb-5068-4534-b774-9df49ce106eb")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "f16ae6ab-9efd-4f26-8d23-5e92b186f179")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "a40e9f0b-8128-4386-9299-5d7d1b486ccb")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "22a655f8-6909-4fe3-9a5d-aeedc8795541")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ee818a10-1067-41b4-81ce-8b5da3860ad8")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f13b65e1-a9b5-4033-b284-dfec47e72cfe")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "d86d751c-b7f9-4bde-b0bf-b58f40625448")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1e6453b4-9e5d-4415-aa0b-332793104c07")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "ba44803e-8593-4a59-938a-7fc3c01aad0a")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "50244bd6-9d55-4938-b2e9-0d0e10148127")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "d2403f93-cad1-40ac-ae4d-bc24bc5d0cab")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "3e6055f2-7512-41bf-94aa-f3170fa63f4c")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f285cc42-f6f8-4288-b474-e4ea887838c5")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "de3147d3-d110-41c5-b30f-96095b694674")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "5e05e7a6-629c-4bd2-acca-e878c6d669ff")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "99efa540-027f-49e2-a212-1bcfefd95a59")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 22 "row1")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "5b6b9450-b0ce-4a38-b5e0-ee436bc55b04")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 15 "Net-(D6-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "59524adc-067b-4add-9c5c-430c4687d71c")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Seeed Studio XIAO Series Library:XIAO-RP2040-DIP"
+ (layer "F.Cu")
+ (uuid "bcea09c0-f550-4317-96fc-95fd84eedb4c")
+ (at 40.205 68.205)
+ (property "Reference" "U1"
+ (at -8.5 -12 0)
+ (unlocked yes)
+ (layer "F.SilkS")
+ (uuid "2d2438f0-fa08-4953-aa03-635d3e756e7d")
+ (effects
+ (font
+ (size 0.635 0.635)
+ (thickness 0.1016)
+ )
+ )
+ )
+ (property "Value" "XIAO-RP2040-DIP"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (uuid "1a9dbdf5-f73d-4b7d-963b-2f65daefe5fb")
+ (effects
+ (font
+ (size 0.635 0.635)
+ (thickness 0.1016)
+ )
+ )
+ )
+ (property "Footprint" "Seeed Studio XIAO Series Library:XIAO-RP2040-DIP"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "543e5114-bd24-4c2d-9554-29a3857a0216")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "c217a96f-64c2-4b7a-b323-84551cf3f9d7")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "1f5e0e17-eb08-4b24-8525-74f7f79c9ecb")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (path "/35a068e0-5f88-40dc-ba2a-cf656c23bdce")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -8.89 8.509)
+ (end -8.89 -8.636)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "fda4fb3c-64fc-40c2-afe2-dde6be344abd")
+ )
+ (fp_line
+ (start -6.985 10.414)
+ (end 6.985 10.414)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "d54257fd-4672-4599-a34d-6d4a925412e7")
+ )
+ (fp_line
+ (start -4.495 -10.541)
+ (end -4.491272 -11.451272)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0977885a-147f-448b-824c-91b6c6cca012")
+ )
+ (fp_line
+ (start -3.991272 -11.951)
+ (end 4.004 -11.951)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "f3e61c13-a212-4235-94b4-62feef731848")
+ )
+ (fp_line
+ (start 4.504 -11.451)
+ (end 4.504 -10.541)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "62022e13-cd81-4194-9f7c-92818d586bc8")
+ )
+ (fp_line
+ (start 6.985 -10.541)
+ (end -6.985 -10.541)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "e1bc6c08-703b-4a62-8974-2955f97783d5")
+ )
+ (fp_line
+ (start 6.985 -10.541)
+ (end -6.985 -10.541)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "6706b7a9-0aa6-4c66-9135-8ed273384558")
+ )
+ (fp_line
+ (start 8.89 8.509)
+ (end 8.89 -8.636)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "3058988f-12d5-4aea-92fc-c6ad808ae747")
+ )
+ (fp_arc
+ (start -8.89 -8.636)
+ (mid -8.332038 -9.983038)
+ (end -6.985 -10.541)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "0d89b76d-a63a-4950-a34b-4f69e606afdc")
+ )
+ (fp_arc
+ (start -6.985 10.414)
+ (mid -8.332038 9.856038)
+ (end -8.89 8.509)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "6127b326-769c-4475-ba1d-c9f288bb9a8c")
+ )
+ (fp_arc
+ (start -4.491272 -11.451272)
+ (mid -4.344724 -11.804644)
+ (end -3.991272 -11.951)
+ (stroke
+ (width 0.127)
+ (type default)
+ )
+ (layer "F.SilkS")
+ (uuid "659dfe95-8125-4cc8-aa68-0bd3fcfbf688")
+ )
+ (fp_arc
+ (start 4.004 -11.951)
+ (mid 4.357553 -11.804553)
+ (end 4.504 -11.451)
+ (stroke
+ (width 0.127)
+ (type default)
+ )
+ (layer "F.SilkS")
+ (uuid "b37081fe-f88e-478b-9330-c5cd2b8e4aa6")
+ )
+ (fp_arc
+ (start 6.985 -10.541)
+ (mid 8.332038 -9.983038)
+ (end 8.89 -8.636)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "d8430691-46f8-4e10-b64b-50ee101005c1")
+ )
+ (fp_arc
+ (start 8.89 8.509)
+ (mid 8.332038 9.856038)
+ (end 6.985 10.414)
+ (stroke
+ (width 0.127)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "4c320d84-204a-4793-8f9d-18c35299621a")
+ )
+ (fp_circle
+ (center -8.95 -10.3)
+ (end -8.95 -10.554)
+ (stroke
+ (width 0.5)
+ (type solid)
+ )
+ (fill solid)
+ (layer "F.SilkS")
+ (uuid "49376817-f454-4316-a36c-8cd4d7d19fb0")
+ )
+ (fp_circle
+ (center -7.807 -9.42)
+ (end -7.807 -9.674)
+ (stroke
+ (width 0.5)
+ (type solid)
+ )
+ (fill solid)
+ (layer "F.SilkS")
+ (uuid "bedccba5-e5b0-48f1-bdd1-87e997153417")
+ )
+ (fp_rect
+ (start -8.9 -10.55)
+ (end 8.9 10.425)
+ (stroke
+ (width 0.05)
+ (type default)
+ )
+ (fill none)
+ (layer "F.CrtYd")
+ (uuid "4468ecb7-906a-4ccc-a617-350cc5cc42c1")
+ )
+ (fp_rect
+ (start -8.9 -10.55)
+ (end 8.9 10.425)
+ (stroke
+ (width 0.1)
+ (type default)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "1c3ad90e-9ebc-4b79-930f-22843cc64b2e")
+ )
+ (fp_circle
+ (center -7.804 -9.426)
+ (end -7.804 -9.68)
+ (stroke
+ (width 0.5)
+ (type solid)
+ )
+ (fill solid)
+ (layer "F.Fab")
+ (uuid "cfed35be-ab2d-4ca9-a8d0-e24cbf03154e")
+ )
+ (pad "1" smd roundrect
+ (at -8.455 -7.62 180)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 18 "col4")
+ (pinfunction "GPIO26/ADC0/A0")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "4aae30f9-e9bf-4813-90bc-9f1709f9ec56")
+ )
+ (pad "1" thru_hole circle
+ (at -7.62 -7.62 180)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 18 "col4")
+ (pinfunction "GPIO26/ADC0/A0")
+ (pintype "passive")
+ (uuid "943a55d1-fae5-405c-a9a9-ec0ac576b845")
+ )
+ (pad "2" smd roundrect
+ (at -8.455 -5.08 180)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 14 "col3")
+ (pinfunction "GPIO27/ADC1/A1")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "57dcc893-8a49-4f6b-a44e-a49a331d0814")
+ )
+ (pad "2" thru_hole circle
+ (at -7.62 -5.08 180)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 14 "col3")
+ (pinfunction "GPIO27/ADC1/A1")
+ (pintype "passive")
+ (uuid "88e648e6-229e-409a-a345-723b4946beec")
+ )
+ (pad "3" smd roundrect
+ (at -8.455 -2.54 180)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 11 "col2")
+ (pinfunction "GPIO28/ADC2/A2")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "5f2b2e28-8e28-4e4e-9765-ee5af67fba6b")
+ )
+ (pad "3" thru_hole circle
+ (at -7.62 -2.54 180)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 11 "col2")
+ (pinfunction "GPIO28/ADC2/A2")
+ (pintype "passive")
+ (uuid "b7b214de-7e1b-4e08-a217-6495fddb923c")
+ )
+ (pad "4" smd roundrect
+ (at -8.455 0 180)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 24 "RINPUT")
+ (pinfunction "GPIO29/ADC3/A3")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "d616a121-f39e-4dde-8f67-ab55d7a1773a")
+ )
+ (pad "4" thru_hole circle
+ (at -7.62 0 180)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 24 "RINPUT")
+ (pinfunction "GPIO29/ADC3/A3")
+ (pintype "passive")
+ (uuid "5ad2f4bc-48db-4b1d-95bc-bd19e405c91a")
+ )
+ (pad "5" smd roundrect
+ (at -8.455 2.54 180)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 7 "SDA")
+ (pinfunction "GPIO6/SDA")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "113d7b97-bcfe-4ed5-ab76-5b1714714cc0")
+ )
+ (pad "5" thru_hole circle
+ (at -7.62 2.54 180)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 7 "SDA")
+ (pinfunction "GPIO6/SDA")
+ (pintype "passive")
+ (uuid "d96c399f-86fe-4a54-a775-0758f3ab98d1")
+ )
+ (pad "6" smd roundrect
+ (at -8.455 5.08 180)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 8 "SCL")
+ (pinfunction "GPIO7/SCL")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "7bd956bf-b3d7-4bff-8e42-38be29addd24")
+ )
+ (pad "6" thru_hole circle
+ (at -7.62 5.08 180)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 8 "SCL")
+ (pinfunction "GPIO7/SCL")
+ (pintype "passive")
+ (uuid "19aac008-b49b-48b0-b821-5fb50d800e47")
+ )
+ (pad "7" smd roundrect
+ (at -8.455 7.62 180)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 21 "row2")
+ (pinfunction "GPIO0/TX")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "1d95f920-ed7f-477d-9e64-bc71e5a2e474")
+ )
+ (pad "7" thru_hole circle
+ (at -7.62 7.62 180)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 21 "row2")
+ (pinfunction "GPIO0/TX")
+ (pintype "passive")
+ (uuid "ba22484d-3689-45f8-8804-500f0548d15b")
+ )
+ (pad "8" thru_hole circle
+ (at 7.62 7.62)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 26 "EC11B")
+ (pinfunction "GPIO1/RX")
+ (pintype "passive")
+ (uuid "2168fc10-9828-4174-bfcc-a74c19695618")
+ )
+ (pad "8" smd roundrect
+ (at 8.455 7.62)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 26 "EC11B")
+ (pinfunction "GPIO1/RX")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "e600158e-9af4-4c3f-984e-4d89b853a1ce")
+ )
+ (pad "9" thru_hole circle
+ (at 7.62 5.08)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 25 "EC11A")
+ (pinfunction "GPIO2/SCK")
+ (pintype "passive")
+ (uuid "6a3c37c1-e6b4-49a5-998c-aa6254b3b5bb")
+ )
+ (pad "9" smd roundrect
+ (at 8.455 5.08)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 25 "EC11A")
+ (pinfunction "GPIO2/SCK")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "3a1240d9-d607-413a-acac-007ea9b45652")
+ )
+ (pad "10" thru_hole circle
+ (at 7.62 2.54)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 22 "row1")
+ (pinfunction "GPIO4/MISO")
+ (pintype "passive")
+ (uuid "0d572ebe-cd7c-4601-98e9-e923fefcf210")
+ )
+ (pad "10" smd roundrect
+ (at 8.455 2.54)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 22 "row1")
+ (pinfunction "GPIO4/MISO")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "d774ef5d-a71a-4c4f-a8b3-5bb0f62d5cef")
+ )
+ (pad "11" thru_hole circle
+ (at 7.62 0)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 2 "NEOPIXEL")
+ (pinfunction "GPIO3/MOSI")
+ (pintype "passive")
+ (uuid "5dd39d58-8764-4d0c-9294-64ec896b7cbe")
+ )
+ (pad "11" smd roundrect
+ (at 8.455 0)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 2 "NEOPIXEL")
+ (pinfunction "GPIO3/MOSI")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "1133efc5-7060-4309-a890-04cd6ffe8f70")
+ )
+ (pad "12" thru_hole circle
+ (at 7.62 -2.54)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 9 "3V3")
+ (pinfunction "3V3")
+ (pintype "passive")
+ (uuid "5b3e6e35-8ab3-4e67-b227-5ae1cd02543a")
+ )
+ (pad "12" smd roundrect
+ (at 8.455 -2.54)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 9 "3V3")
+ (pinfunction "3V3")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "a4f6c349-c649-44c0-b361-3c80db9d9eb4")
+ )
+ (pad "13" thru_hole circle
+ (at 7.62 -5.08)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 4 "GND")
+ (pinfunction "GND")
+ (pintype "passive")
+ (uuid "9116ea51-4e7b-474f-bf75-06c390e46089")
+ )
+ (pad "13" smd roundrect
+ (at 8.455 -5.08)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 4 "GND")
+ (pinfunction "GND")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "7f310c9f-0472-4b43-85fe-9028b8ed6fac")
+ )
+ (pad "14" thru_hole circle
+ (at 7.62 -7.62)
+ (size 1.524 1.524)
+ (drill 0.889)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 1 "+5V")
+ (pinfunction "VBUS")
+ (pintype "passive")
+ (uuid "1bbe5454-2bb9-4d2b-b86b-3e708bd01d7a")
+ )
+ (pad "14" smd roundrect
+ (at 8.455 -7.62)
+ (size 2.432 1.524)
+ (layers "F.Cu" "F.Mask")
+ (roundrect_rratio 0.1)
+ (net 1 "+5V")
+ (pinfunction "VBUS")
+ (pintype "passive")
+ (thermal_bridge_angle 45)
+ (uuid "f5a639cf-860f-420f-8b13-dd2797379b73")
+ )
+ (model "${AMZPATH}/3dmodels/AMz3D.3dshapes/XIAO-nRF52840 v15.step"
+ (hide yes)
+ (offset
+ (xyz -1.778 -6.096 0.381)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz -90 0 0)
+ )
+ )
+ (model "${AMZPATH}/3dmodels/AMz3D.3dshapes/Seeeduino XIAO SAMD21 v4.step"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ (model "${AMZPATH}/3dmodels/AMz3D.3dshapes/Seeed Studio XIAO RP2040 v26.step"
+ (hide yes)
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 90)
+ )
+ )
+ (model "${AMZPATH}/3dmodels/AMz3D.3dshapes/Seeed Studio XIAO-ESP32-C3.step"
+ (hide yes)
+ (offset
+ (xyz -1.7018 -6.096 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz -90 0 0)
+ )
+ )
+ (model "${AMZPATH}/3dmodels/AMz3D.3dshapes/XIAO-ESP32S3 v2.step"
+ (hide yes)
+ (offset
+ (xyz -1.778 -6.1722 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz -90 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "bd1ff2b4-5a98-40b9-8ae9-86cf352dd3f8")
+ (at 106.7675 116.84)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D14"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "3c625ec1-55c7-4be2-9091-b613264b09bf")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "a2300933-1d6a-439e-967d-e257ab9af1e7")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "6de200d2-d27e-488c-abd2-b281014641ed")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "c36aa5a9-bc52-4cb2-8a38-a6c8bb22f81f")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "62e0f88d-eaf1-4f7b-91ee-fdc9c996625b")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/d4dad580-cf91-4aa0-9cca-6e9db2b71eab")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "6caf45c6-5010-4f85-a1ca-5fec55e06118")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b0836549-3757-4fc0-8c86-9ba8c6948c0d")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "d4d7497d-246d-4f51-b420-1a785e0dd6f8")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "90d1b589-e662-45f7-bea1-4c89996b7460")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "6dfccb0f-e56b-42b4-91cb-287afc7e9e48")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "21c8c6b0-6812-44c0-9b0b-79c389ab5298")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "228dae09-c387-4947-a659-debf4d77a073")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "342df1a6-73fe-481b-8e45-a96e85acfda5")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "686c340a-a78a-475d-9619-8a6bafb1026b")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "06472461-0716-477d-9d77-d75b1ccc8083")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "de3de138-10ff-4641-8d77-040bee9175c4")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "359e6e8c-0e25-47ef-a531-fffe2dd2e535")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "1c98cb9d-0145-483c-9319-cc287d773fd3")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "18e9a659-b27a-4dd4-919c-da3c52229a0b")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "ea8284f3-7172-4766-827b-5d3fb642b7ef")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 27 "Net-(D14-DOUT)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "718fb65f-41c5-442f-8fe0-5a5a5448e88f")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "e7d1aacb-a7ad-4e4d-990e-97f83835a225")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 31 "Net-(D13-DOUT)")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "893a3a82-144a-4674-aaf8-ff62198192e9")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "085451bc-28fd-47cc-811f-558da07c19b0")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (layer "F.Cu")
+ (uuid "e73cacef-550c-49e5-92c8-7d957733f060")
+ (at 59.23 97.79)
+ (descr "3.5mm x 3.5mm PLCC4 Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf")
+ (tags "LED RGB NeoPixel Mini PLCC-4 3535")
+ (property "Reference" "D2"
+ (at 0 -2.75 0)
+ (layer "F.SilkS")
+ (uuid "f7be8e45-02f7-47cb-982e-587295b87c10")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 0 3.25 0)
+ (layer "F.Fab")
+ (uuid "a41ecc9f-9228-43a0-857f-5adce95410e7")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "5b97a0b5-d13a-458d-ad33-b87601a7ee6a")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "c39b4e28-8027-4cd0-b604-23cb635eb61d")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "f8b79a82-9a1b-4eea-8dae-5ed704e5bc70")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*")
+ (path "/496010bf-b03a-4ebc-b0fa-a1866f535ae8")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr smd)
+ (fp_line
+ (start -2.95 -1.95)
+ (end 2.95 -1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "80313d67-23ec-45ac-b03f-852d553b843d")
+ )
+ (fp_line
+ (start -2.95 1.95)
+ (end 2.95 1.95)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "9ef7819e-72e4-444f-b023-1610b0b43558")
+ )
+ (fp_line
+ (start 2.95 1.95)
+ (end 2.95 0.875)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "317e6b3f-7217-4e62-90a7-7c3524e3b589")
+ )
+ (fp_line
+ (start -2.8 -2)
+ (end -2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "090db7b8-8bc6-4102-9b37-42807b8eba13")
+ )
+ (fp_line
+ (start -2.8 2)
+ (end 2.8 2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "870d2fed-3303-45a7-b382-d0caaf6da70b")
+ )
+ (fp_line
+ (start 2.8 -2)
+ (end -2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "0c625fb8-7c45-4b5e-970a-37726f9f6a75")
+ )
+ (fp_line
+ (start 2.8 2)
+ (end 2.8 -2)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "51f69623-fc7c-4f76-8078-678544429bf1")
+ )
+ (fp_line
+ (start -1.75 -1.75)
+ (end -1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f8072307-9efb-4fc2-b753-89011d4c1ba8")
+ )
+ (fp_line
+ (start -1.75 1.75)
+ (end 1.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "cbfac0a2-00af-4f45-9bb5-27d4b737dcae")
+ )
+ (fp_line
+ (start 1.75 -1.75)
+ (end -1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "1128bed8-3451-4e57-a083-a5876aba50cf")
+ )
+ (fp_line
+ (start 1.75 0.75)
+ (end 0.75 1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c8f723f5-7824-4d73-ac24-40ed28067b59")
+ )
+ (fp_line
+ (start 1.75 1.75)
+ (end 1.75 -1.75)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "9e054f6a-d239-4ab7-be55-7c51dba15c32")
+ )
+ (fp_circle
+ (center 0 0)
+ (end 0 -1.5)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (fill none)
+ (layer "F.Fab")
+ (uuid "71ab03f7-26c7-415b-b6ce-9db5b96abba6")
+ )
+ (fp_text user "1"
+ (at -3.5 -0.875 0)
+ (layer "F.SilkS")
+ (uuid "feb1c4d5-19cb-4c7f-b13d-3f01d177a26c")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 0 0 0)
+ (layer "F.Fab")
+ (uuid "75e4751b-8a2d-49cc-9aa3-ec35c8f3a085")
+ (effects
+ (font
+ (size 0.5 0.5)
+ (thickness 0.1)
+ )
+ )
+ )
+ (pad "1" smd rect
+ (at -1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 5 "Net-(D11-DIN)")
+ (pinfunction "DOUT")
+ (pintype "output")
+ (uuid "c6db48b1-1ab7-483f-9116-3f2c0f85986d")
+ )
+ (pad "2" smd rect
+ (at -1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 4 "GND")
+ (pinfunction "VSS")
+ (pintype "power_in")
+ (uuid "cb390840-0ee8-48f9-9804-142a71222136")
+ )
+ (pad "3" smd rect
+ (at 1.75 0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 3 "Net-(D1-DOUT)")
+ (pinfunction "DIN")
+ (pintype "input")
+ (uuid "62a2c179-a39a-4cb3-97b8-18d076155008")
+ )
+ (pad "4" smd rect
+ (at 1.75 -0.875)
+ (size 1.6 0.85)
+ (layers "F.Cu" "F.Paste" "F.Mask")
+ (net 1 "+5V")
+ (pinfunction "VDD")
+ (pintype "power_in")
+ (uuid "5a7e51a2-7e84-4623-9b9a-d810ae1abf0a")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/LED_SMD.3dshapes/LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (footprint "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (layer "F.Cu")
+ (uuid "ec74c34a-e51a-4c28-9d1a-f2c1fd37d6ed")
+ (at 68.705 92.275 90)
+ (descr "Diode, DO-35_SOD27 series, Axial, Horizontal, pin pitch=7.62mm, , length*diameter=4*2mm^2, , http://www.diodes.com/_files/packages/DO-35.pdf")
+ (tags "Diode DO-35_SOD27 series Axial Horizontal pin pitch 7.62mm length 4mm diameter 2mm")
+ (property "Reference" "D7"
+ (at 3.81 -2.12 90)
+ (layer "F.SilkS")
+ (uuid "520e982e-5820-46a3-9536-ecadcc0827fe")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 3.81 2.12 90)
+ (layer "F.Fab")
+ (uuid "f3124c54-7929-445d-ac9b-aa940cd4dc93")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "55ef0880-f2d1-4b2c-804e-5ec103c70295")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "4f959e3e-5b57-4651-85ff-7b8421e71cce")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "85e917c2-4b2f-42ce-8ffe-1182d9ea03e0")
+ (effects
+ (font
+ (size 1.27 1.27)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "09653017-6e21-4f1f-ae6c-c743bfee448d")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 90)
+ (unlocked yes)
+ (layer "F.Fab")
+ (hide yes)
+ (uuid "15ac0c1f-f61c-4993-984e-5275e7d4d314")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (property ki_fp_filters "D*DO?35*")
+ (path "/ff19517d-941e-403e-91a1-6d1f376aed1a")
+ (sheetname "Root")
+ (sheetfile "hackpad.kicad_sch")
+ (attr through_hole)
+ (fp_line
+ (start 5.93 -1.12)
+ (end 1.69 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "38c042c0-4948-4e53-b7bb-25a0f03d9ca3")
+ )
+ (fp_line
+ (start 2.53 -1.12)
+ (end 2.53 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "f24a1fd1-fb39-4442-9e95-f8f11459311e")
+ )
+ (fp_line
+ (start 2.41 -1.12)
+ (end 2.41 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "ff0d261d-26b5-413c-99a5-5efb0d91adbe")
+ )
+ (fp_line
+ (start 2.29 -1.12)
+ (end 2.29 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "f7a2e2cb-51a4-4539-8bb0-2e58c6dbe409")
+ )
+ (fp_line
+ (start 1.69 -1.12)
+ (end 1.69 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "cd9d9acf-832d-48d7-91d7-9ec55292730d")
+ )
+ (fp_line
+ (start 6.58 0)
+ (end 5.93 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "4a7a3cad-177a-445b-99b2-27bb8d34d71c")
+ )
+ (fp_line
+ (start 1.04 0)
+ (end 1.69 0)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "b4f1c57d-49e7-4cda-9175-f3e02c8227b6")
+ )
+ (fp_line
+ (start 5.93 1.12)
+ (end 5.93 -1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "cad2a197-fd17-472d-9047-39608fd674f4")
+ )
+ (fp_line
+ (start 1.69 1.12)
+ (end 5.93 1.12)
+ (stroke
+ (width 0.12)
+ (type solid)
+ )
+ (layer "F.SilkS")
+ (uuid "30b01b46-da5b-44b8-a227-d2c61dd3f35e")
+ )
+ (fp_line
+ (start 8.67 -1.25)
+ (end -1.05 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "bbc0d621-ff4c-41ff-8376-b5533d187b08")
+ )
+ (fp_line
+ (start -1.05 -1.25)
+ (end -1.05 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "f6405d2c-3927-4541-9400-d0f2ef168dd8")
+ )
+ (fp_line
+ (start 8.67 1.25)
+ (end 8.67 -1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "f8956552-5f7a-40be-b4c9-08c334980fb5")
+ )
+ (fp_line
+ (start -1.05 1.25)
+ (end 8.67 1.25)
+ (stroke
+ (width 0.05)
+ (type solid)
+ )
+ (layer "F.CrtYd")
+ (uuid "ee8bce21-dcea-4444-93c8-4af19223f833")
+ )
+ (fp_line
+ (start 5.81 -1)
+ (end 1.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "c7957cd1-8399-49a3-90a4-f21bacd07247")
+ )
+ (fp_line
+ (start 2.51 -1)
+ (end 2.51 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "79f6cff1-5b2d-4151-aa88-e8f02206739f")
+ )
+ (fp_line
+ (start 2.41 -1)
+ (end 2.41 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "19425f79-6826-4e1c-85c6-4aeacb7b2f11")
+ )
+ (fp_line
+ (start 2.31 -1)
+ (end 2.31 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "8367fd57-8ce4-488a-b12e-adb76f4a9695")
+ )
+ (fp_line
+ (start 1.81 -1)
+ (end 1.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "71c71e77-7c06-4364-9ded-a30366fa6ab8")
+ )
+ (fp_line
+ (start 7.62 0)
+ (end 5.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f3413446-4554-45ac-bb7f-dec4086bc09c")
+ )
+ (fp_line
+ (start 0 0)
+ (end 1.81 0)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "41d561ab-33a1-4a42-ab78-b6516cc8bce9")
+ )
+ (fp_line
+ (start 5.81 1)
+ (end 5.81 -1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "6de31880-dc7a-4f5d-a7b4-5dcb8a6271a8")
+ )
+ (fp_line
+ (start 1.81 1)
+ (end 5.81 1)
+ (stroke
+ (width 0.1)
+ (type solid)
+ )
+ (layer "F.Fab")
+ (uuid "f142cc1c-83b7-403e-ab79-1c3c738e0cbf")
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.SilkS")
+ (uuid "3b2038bc-908d-4a6c-bde7-2a2548065ad1")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (fp_text user "${REFERENCE}"
+ (at 4.11 0 90)
+ (layer "F.Fab")
+ (uuid "c75811a3-b822-42e8-b8dd-ab7264fd314d")
+ (effects
+ (font
+ (size 0.8 0.8)
+ (thickness 0.12)
+ )
+ )
+ )
+ (fp_text user "K"
+ (at 0 -1.8 90)
+ (layer "F.Fab")
+ (uuid "f6d3f2b4-6e7d-4b81-8c00-dce94db1dbf4")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.15)
+ )
+ )
+ )
+ (pad "1" thru_hole rect
+ (at 0 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 22 "row1")
+ (pinfunction "K")
+ (pintype "passive")
+ (uuid "4823e432-560f-4f66-98f6-adf7a0e73207")
+ )
+ (pad "2" thru_hole oval
+ (at 7.62 0 90)
+ (size 1.6 1.6)
+ (drill 0.8)
+ (layers "*.Cu" "*.Mask")
+ (remove_unused_layers no)
+ (net 16 "Net-(D7-A)")
+ (pinfunction "A")
+ (pintype "passive")
+ (uuid "a4ac56c6-7d7d-4dd6-b103-98b4a4fdddc9")
+ )
+ (model "${KICAD8_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl"
+ (offset
+ (xyz 0 0 0)
+ )
+ (scale
+ (xyz 1 1 1)
+ )
+ (rotate
+ (xyz 0 0 0)
+ )
+ )
+ )
+ (gr_rect
+ (start 26.5425 52.395)
+ (end 120.8625 121.255)
+ (stroke
+ (width 0.05)
+ (type default)
+ )
+ (fill none)
+ (layer "Edge.Cuts")
+ (uuid "12432d92-3880-4a43-b0b3-d5fbd9b9bf0c")
+ )
+ (dimension
+ (type aligned)
+ (layer "F.Cu")
+ (uuid "4a63cd72-c687-4d66-986b-5d76a4c7c5e4")
+ (pts
+ (xy 120.545 52.395) (xy 26.225 52.395)
+ )
+ (height 11.14)
+ (gr_text "94.3200 mm"
+ (at 73.385 39.455 0)
+ (layer "F.Cu")
+ (uuid "4a63cd72-c687-4d66-986b-5d76a4c7c5e4")
+ (effects
+ (font
+ (size 1.5 1.5)
+ (thickness 0.3)
+ )
+ )
+ )
+ (format
+ (prefix "")
+ (suffix "")
+ (units 3)
+ (units_format 1)
+ (precision 4)
+ )
+ (style
+ (thickness 0.2)
+ (arrow_length 1.27)
+ (text_position_mode 0)
+ (extension_height 0.58642)
+ (extension_offset 0.5) keep_text_aligned)
+ )
+ (dimension
+ (type aligned)
+ (layer "F.SilkS")
+ (uuid "67793f50-ab0a-4b05-992b-6a6410d8dc82")
+ (pts
+ (xy 120.8625 121.255) (xy 120.545 52.395)
+ )
+ (height 10.19288)
+ (gr_text "68.8607 mm"
+ (at 131.99651 86.772931 -89.73582223)
+ (layer "F.SilkS")
+ (uuid "67793f50-ab0a-4b05-992b-6a6410d8dc82")
+ (effects
+ (font
+ (size 1 1)
+ (thickness 0.1)
+ )
+ )
+ )
+ (format
+ (prefix "")
+ (suffix "")
+ (units 3)
+ (units_format 1)
+ (precision 4)
+ )
+ (style
+ (thickness 0.1)
+ (arrow_length 1.27)
+ (text_position_mode 0)
+ (extension_height 0.58642)
+ (extension_offset 0.5) keep_text_aligned)
+ )
+ (segment
+ (start 80.755 115.24)
+ (end 107.7925 115.24)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "0a014e8e-6993-4a5f-95e4-6565db0ea12d")
+ )
+ (segment
+ (start 63.719999 95.79)
+ (end 63.469999 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "0a9002ab-1f43-46f3-872a-dcb20c109679")
+ )
+ (segment
+ (start 41.93 96.85)
+ (end 41.93 90.96)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "151b3121-5cee-4f46-8e4a-442a84249dec")
+ )
+ (segment
+ (start 44.3425 97.79)
+ (end 43.4025 96.85)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "19cf8406-ea06-45c4-885c-e338fe6f8368")
+ )
+ (segment
+ (start 63.525 115.24)
+ (end 79.305 115.24)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "1d07030e-a890-4ee6-80d1-508f7caf6fd5")
+ )
+ (segment
+ (start 60.255 115.24)
+ (end 60.98 115.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "26b6ac09-e44c-41b6-a8f0-1a39ebdcdf4b")
+ )
+ (segment
+ (start 62.2625 95.79)
+ (end 62.105 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "31e56e81-7445-423d-a9fb-fc3dd6d117dd")
+ )
+ (segment
+ (start 79.305 115.24)
+ (end 80.03 115.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "3a31bb2c-b99f-4398-be1d-05d1ff081850")
+ )
+ (segment
+ (start 108.605 96.915)
+ (end 107.48 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "5785d62e-77ab-42ad-8b43-93348829cbe8")
+ )
+ (segment
+ (start 62.8 115.965)
+ (end 63.525 115.24)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "5aa86cd3-b634-4775-b30c-7c4b80e8f410")
+ )
+ (segment
+ (start 42.1425 113.955)
+ (end 42.1425 115.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "5e8162bb-882d-4d72-a575-e0ddf9ad6d94")
+ )
+ (segment
+ (start 46.7625 95.79)
+ (end 45.5425 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "5faa9de8-0dce-4793-a557-61b45ba95833")
+ )
+ (segment
+ (start 59.855 95.79)
+ (end 46.7625 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "6753fe75-61ed-4afd-bb2e-6f7de3e428e2")
+ )
+ (segment
+ (start 60.98 96.915)
+ (end 59.855 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "6784d8e9-82fc-41f2-9c35-708c18a6a9d4")
+ )
+ (segment
+ (start 42.1425 113.66)
+ (end 43.9675 111.835)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "6c9375a4-7aa5-46b4-a956-bf3976503414")
+ )
+ (segment
+ (start 80.03 115.965)
+ (end 80.755 115.24)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "6dd97f2b-eca2-4d71-975b-8dfea0bf5a78")
+ )
+ (segment
+ (start 43.4025 96.85)
+ (end 41.93 96.85)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "72a63643-4c33-4603-bf01-aa5bb627ef4c")
+ )
+ (segment
+ (start 42.8675 115.24)
+ (end 60.255 115.24)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "7dd43eeb-ce61-48ed-a95b-9ac52e356a7e")
+ )
+ (segment
+ (start 107.48 95.79)
+ (end 83.0425 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "7ea6117f-7428-4c5e-b2bd-3e443d4ac70f")
+ )
+ (segment
+ (start 62.105 95.79)
+ (end 60.98 96.915)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "82ee608f-2029-44d8-9a2f-cc28120d12fd")
+ )
+ (segment
+ (start 81.155 95.79)
+ (end 80.03 96.915)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "9a253946-18bb-4b56-92fb-e694629f7199")
+ )
+ (segment
+ (start 41.93 90.96)
+ (end 43.669707 89.220293)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "9b34bfef-cab4-4e47-bab2-dc6f9b148163")
+ )
+ (segment
+ (start 42.1425 115.965)
+ (end 42.8675 115.24)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "9ccd9193-10af-4331-a871-a2e79c7758ac")
+ )
+ (segment
+ (start 42.1425 113.955)
+ (end 42.1425 113.66)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "b1c7cbc0-3fe7-46d7-989b-655a3d415ccc")
+ )
+ (segment
+ (start 80.03 96.915)
+ (end 78.905 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "c0890c40-b641-430c-9485-6d54699ec8f2")
+ )
+ (segment
+ (start 44.3425 95.79)
+ (end 43.2825 96.85)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "d0fcb22f-490b-421c-8225-58ee262a5efa")
+ )
+ (segment
+ (start 60.98 115.965)
+ (end 62.8 115.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "d1affde8-57e3-4bdc-8304-9af7b77c45ab")
+ )
+ (segment
+ (start 43.2825 96.85)
+ (end 41.93 96.85)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "d653f8e9-d073-480f-83fa-a565f69bb09e")
+ )
+ (segment
+ (start 81.525 95.79)
+ (end 81.155 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "da20143f-1873-4fdd-8e0b-7d0c592a2080")
+ )
+ (segment
+ (start 78.905 95.79)
+ (end 63.719999 95.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "dc76ee6b-f2ec-4b4a-8e87-c9fb51dc9c20")
+ )
+ (segment
+ (start 43.9675 111.835)
+ (end 44.0125 111.835)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "e051a006-60d0-4fb2-b3fb-03c1b52d3cf9")
+ )
+ (segment
+ (start 107.7925 115.24)
+ (end 108.5175 115.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 1)
+ (uuid "fc66aed4-747b-42ff-8a64-e4e30722e7a9")
+ )
+ (via
+ (at 44.0125 111.835)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "1aa44adc-9203-48e3-9d8f-54d7873c3a18")
+ )
+ (via
+ (at 81.525 95.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "1be82906-555e-42bb-953e-91f2592683f8")
+ )
+ (via
+ (at 44.3425 95.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "23655249-c8cb-4499-9c0e-99c00d1fbfea")
+ )
+ (via
+ (at 45.5425 95.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "52ebfb7f-2254-4c14-9e09-20d1460562c1")
+ )
+ (via
+ (at 63.469999 95.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "93bf7f1e-a77a-41da-bf75-9d7c6a2f9261")
+ )
+ (via
+ (at 82.725 95.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "ae5dea61-053a-4c32-b838-c370546f65f5")
+ )
+ (via
+ (at 62.2625 95.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "b12d7578-a553-4549-95a1-3d86a7c45289")
+ )
+ (via
+ (at 43.669707 89.220293)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "edb58c86-8f13-4a80-8725-56e7055550b1")
+ )
+ (via
+ (at 44.3425 97.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 1)
+ (uuid "f572d4d6-9c2b-4847-945f-d906a9536413")
+ )
+ (segment
+ (start 44.0125 111.835)
+ (end 44.0125 102.922399)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "1b8bbf55-d010-4e07-ab18-e98c28ce8fdc")
+ )
+ (segment
+ (start 44.625 87.202944)
+ (end 44.625 63.785)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "34fc1cd5-e254-4c30-9b59-16bbe54f95ef")
+ )
+ (segment
+ (start 45.5425 95.79)
+ (end 44.3425 95.79)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "4250c822-5ea1-4f7e-b909-c9a38a91ac5a")
+ )
+ (segment
+ (start 44.625 63.785)
+ (end 47.825 60.585)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "648d53ec-dd44-4dc1-a5f7-e0f7b21bde1f")
+ )
+ (segment
+ (start 43.669707 89.220293)
+ (end 43.669707 88.158237)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "69584d53-d7d5-4fd3-8c5a-806ab75fc56f")
+ )
+ (segment
+ (start 82.725 95.79)
+ (end 81.525 95.79)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "996f6f97-9d21-4ca8-9cba-a7451fe93f7d")
+ )
+ (segment
+ (start 63.469999 95.79)
+ (end 62.2625 95.79)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "a63bd1c1-7f06-4e62-8852-f70079f14814")
+ )
+ (segment
+ (start 44.3425 102.592399)
+ (end 44.3425 97.79)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "ac8f3d13-cc8d-4b53-b1e7-2140180a956d")
+ )
+ (segment
+ (start 43.669707 88.158237)
+ (end 44.625 87.202944)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "e70cfa87-ee2c-4b55-b050-ecc917ee02e9")
+ )
+ (segment
+ (start 44.0125 102.922399)
+ (end 44.3425 102.592399)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 1)
+ (uuid "f7c0866b-69df-4556-95ec-b441d82d9659")
+ )
+ (segment
+ (start 40.83 97.5)
+ (end 40.83 93.5275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 2)
+ (uuid "0d5ebdc7-07b9-45df-997b-bfa85cd904e5")
+ )
+ (segment
+ (start 51.185 68.205)
+ (end 51.325 68.345)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 2)
+ (uuid "1f5c439c-90ed-4dc3-9e37-68e1f80707ac")
+ )
+ (segment
+ (start 40.83 93.5275)
+ (end 41.33 93.0275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 2)
+ (uuid "43d96146-646d-407b-83aa-092b8eae9dcd")
+ )
+ (segment
+ (start 47.825 68.205)
+ (end 51.185 68.205)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 2)
+ (uuid "b4a599cf-1687-454f-a267-880891b55567")
+ )
+ (segment
+ (start 41.93 98.6)
+ (end 40.83 97.5)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 2)
+ (uuid "f8dd1fec-0978-4f76-b534-67fcb8da7322")
+ )
+ (via
+ (at 41.33 93.0275)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 2)
+ (uuid "45cf245d-e0f5-44aa-90d0-d56584f05274")
+ )
+ (via
+ (at 51.325 68.345)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 2)
+ (uuid "71618f1b-2cfd-49fd-a627-6ed0ec094444")
+ )
+ (segment
+ (start 44.625 93.0275)
+ (end 47.81 89.8425)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 2)
+ (uuid "3022487e-9b0c-4a20-b2e9-289b989c4a9c")
+ )
+ (segment
+ (start 51.435372 68.455372)
+ (end 51.325 68.345)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 2)
+ (uuid "4e494af8-44f6-4179-a30b-c87696e11b7d")
+ )
+ (segment
+ (start 47.735 81.115)
+ (end 47.81 81.115)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 2)
+ (uuid "602ed6fb-c305-4fdc-b803-0808673bbfab")
+ )
+ (segment
+ (start 51.435372 77.489628)
+ (end 51.435372 68.455372)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 2)
+ (uuid "67658bf3-aa1c-41bb-b0fe-3d79db52cdd8")
+ )
+ (segment
+ (start 41.33 93.0275)
+ (end 44.625 93.0275)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 2)
+ (uuid "71b0557e-5975-4078-b075-5e2bafba4bd6")
+ )
+ (segment
+ (start 47.81 89.8425)
+ (end 47.81 81.115)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 2)
+ (uuid "beb17da7-5ee3-4010-9a41-dc4b75d4f327")
+ )
+ (segment
+ (start 47.81 81.115)
+ (end 51.435372 77.489628)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 2)
+ (uuid "ca571b24-cd73-43a1-a4c0-bc67ec82b1c9")
+ )
+ (segment
+ (start 58.505 96.19)
+ (end 60.98 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 3)
+ (uuid "086857c2-81a1-4955-acb6-246d422005da")
+ )
+ (segment
+ (start 45.5425 97.79)
+ (end 47.1425 96.19)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 3)
+ (uuid "0db3a36a-63ea-44d1-b3a0-17057e303ebc")
+ )
+ (segment
+ (start 47.1425 96.19)
+ (end 58.505 96.19)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 3)
+ (uuid "5eded7d0-acbd-4732-80ac-6328b1f688ab")
+ )
+ (via
+ (at 45.5425 97.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 3)
+ (uuid "46b15b3b-ce24-47d7-a8fd-074f9e114eff")
+ )
+ (via
+ (at 38.43 96.85)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 3)
+ (uuid "8ddab013-60c7-45c1-9227-289c8dfe2a71")
+ )
+ (segment
+ (start 38.77 97.19)
+ (end 38.43 96.85)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 3)
+ (uuid "acf87ba3-e128-4d49-8736-de2f6f95693b")
+ )
+ (segment
+ (start 45.5425 97.79)
+ (end 44.9425 97.19)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 3)
+ (uuid "da1bc38c-7f19-45a8-8efd-773d06965d5e")
+ )
+ (segment
+ (start 44.9425 97.19)
+ (end 38.77 97.19)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 3)
+ (uuid "f0ebd0ec-f4a3-4315-832d-383ac1959b75")
+ )
+ (segment
+ (start 54.895 71.905)
+ (end 58.845 67.955)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "06f7d5a8-cf1a-47d3-8938-6685d738508b")
+ )
+ (segment
+ (start 58.7625 118.44)
+ (end 76.3625 118.44)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "0de5146e-7c4e-4902-b858-71b88f3bd976")
+ )
+ (segment
+ (start 105.0175 117.715)
+ (end 104.2925 118.44)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "15a164b9-eaee-448a-937b-bb968e893300")
+ )
+ (segment
+ (start 56.445 64.208654)
+ (end 55.361346 63.125)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "15e4e0c3-4436-4c0b-9794-966aa072a23a")
+ )
+ (segment
+ (start 105.105 98.665)
+ (end 104.505 99.265)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "1b7d3211-b1ff-4e31-b550-7d518a4ffc7e")
+ )
+ (segment
+ (start 76.53 99.924899)
+ (end 80.240101 103.635)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "1fab33f0-24bf-4d51-89b0-61e80ffaffad")
+ )
+ (segment
+ (start 81.6425 103.635)
+ (end 86.6125 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "21310126-fe6e-4c3a-bbe4-9ce24e27e839")
+ )
+ (segment
+ (start 77.255 118.44)
+ (end 76.53 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "281e213c-e36d-4795-a183-b849e6d2e2de")
+ )
+ (segment
+ (start 42.140101 103.635)
+ (end 43.5425 103.635)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "2b822dc1-54f5-46c2-969c-8f918bfd7bde")
+ )
+ (segment
+ (start 67.5625 98.665)
+ (end 76.53 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "3ac63472-a05b-40a1-98c7-7272a8831701")
+ )
+ (segment
+ (start 56.755 118.44)
+ (end 57.48 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "3f2a94ac-a916-4348-b830-0e2102f56e28")
+ )
+ (segment
+ (start 54.895 71.905)
+ (end 56.445 70.355)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "4915949e-3e69-4786-aba2-744d749122e8")
+ )
+ (segment
+ (start 38.43 98.6)
+ (end 39.8625 97.1675)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "4cf505db-38be-49a0-aaa8-ed050efcab36")
+ )
+ (segment
+ (start 62.5925 103.635)
+ (end 67.5625 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "4cfd815a-7a79-49b2-a2d5-d4d45018e84f")
+ )
+ (segment
+ (start 104.2925 118.44)
+ (end 77.255 118.44)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "5833c9e5-7c09-431e-9368-c0f5c26fa0f8")
+ )
+ (segment
+ (start 38.6425 117.715)
+ (end 39.3675 118.44)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "61cdf301-42e4-411e-a0f4-4227dbe58989")
+ )
+ (segment
+ (start 38.43 99.924899)
+ (end 42.140101 103.635)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "6556e73f-21db-4c1c-b219-07c3034f55d2")
+ )
+ (segment
+ (start 76.3625 118.44)
+ (end 77.0875 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "6607eb1a-df9b-4be0-a52a-d06b48429dd2")
+ )
+ (segment
+ (start 39.3675 118.44)
+ (end 56.755 118.44)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "668ef1d1-d0d8-4516-a7fa-077a5c426cd7")
+ )
+ (segment
+ (start 39.8625 92.461814)
+ (end 43.069707 89.254607)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "68b936dc-981c-47ea-b2aa-4bbf373409c8")
+ )
+ (segment
+ (start 76.53 98.665)
+ (end 76.53 99.924899)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "6af620f4-9faf-4d49-956f-4956e08c1405")
+ )
+ (segment
+ (start 55.361346 63.125)
+ (end 47.825 63.125)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "71771a3d-0718-417e-85a0-d9df5a307506")
+ )
+ (segment
+ (start 57.48 117.715)
+ (end 58.0375 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "759fd11b-f26f-4f75-9737-4708893f8dad")
+ )
+ (segment
+ (start 61.190101 103.635)
+ (end 62.5925 103.635)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "81494715-9984-4443-956c-bc5d4754c6da")
+ )
+ (segment
+ (start 43.069707 89.254607)
+ (end 43.069707 88.654606)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "85c8684e-de3b-455c-8e05-b7ae52239397")
+ )
+ (segment
+ (start 58.845 67.955)
+ (end 99.385 67.955)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "8667b0e3-bb48-421d-ad6b-b86ef549c9db")
+ )
+ (segment
+ (start 106.855 116.84)
+ (end 105.98 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "88f88bf1-07c1-4a9c-95fc-727ee3ab3a7e")
+ )
+ (segment
+ (start 57.48 98.665)
+ (end 57.48 99.924899)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "8cd3f4ed-32fc-4884-9310-fe7d9ebf0ea1")
+ )
+ (segment
+ (start 48.5125 98.665)
+ (end 57.48 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "9e83e699-fab1-407f-97f3-fd49ffca549d")
+ )
+ (segment
+ (start 80.240101 103.635)
+ (end 81.6425 103.635)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "a2dcd11a-daf3-4f41-99b7-23a80e0dbbac")
+ )
+ (segment
+ (start 43.5425 103.635)
+ (end 48.5125 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "b65b78bd-c95b-48bb-8e81-993cdadce12d")
+ )
+ (segment
+ (start 38.43 98.6)
+ (end 38.43 99.924899)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "b7c281b5-a44d-42f9-a828-a0558afd18a1")
+ )
+ (segment
+ (start 56.445 70.355)
+ (end 56.445 64.208654)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "b815305e-62ce-4f2e-bf19-93841fbc9aaa")
+ )
+ (segment
+ (start 104.505 99.265)
+ (end 104.505 114.29)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "bb4c4c67-c2d3-4427-9988-6475d58ebaee")
+ )
+ (segment
+ (start 57.48 99.924899)
+ (end 61.190101 103.635)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "bf3a4723-7af9-4f7e-8684-5728ff7e0f04")
+ )
+ (segment
+ (start 86.6125 98.665)
+ (end 105.105 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "c279ee03-72ce-4ed2-b080-a5f8de2cdee4")
+ )
+ (segment
+ (start 39.8625 97.1675)
+ (end 39.8625 92.461814)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "c415eb81-00bb-4e25-b0a1-8eda9449edaf")
+ )
+ (segment
+ (start 99.385 67.955)
+ (end 99.535 68.105)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "c9038340-6241-46fc-a71d-6423bbf5ca0b")
+ )
+ (segment
+ (start 44.391985 63.169485)
+ (end 44.43647 63.125)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "db5b46b3-f957-4c4c-84d9-c135a3fb9c32")
+ )
+ (segment
+ (start 105.98 117.715)
+ (end 105.0175 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "e540a223-010e-42c9-a700-7aacf559b901")
+ )
+ (segment
+ (start 44.43647 63.125)
+ (end 47.825 63.125)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "f344238e-34f7-4403-9671-a0badc3c416f")
+ )
+ (segment
+ (start 104.505 114.29)
+ (end 104.855 114.64)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "f4278d1f-afe3-4a1e-bd3d-6bb485658035")
+ )
+ (segment
+ (start 58.0375 117.715)
+ (end 58.7625 118.44)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 4)
+ (uuid "fad937a8-fcdd-4e24-94c5-5ee3809f5138")
+ )
+ (via
+ (at 43.069707 88.654606)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 4)
+ (uuid "216e34d7-16b2-41aa-aab2-be2aa6e8319a")
+ )
+ (via
+ (at 104.855 114.64)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 4)
+ (uuid "91603a68-61c0-4eee-b004-13ae2fad5c1b")
+ )
+ (via
+ (at 44.391985 63.169485)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 4)
+ (uuid "cff35ff1-dee5-4fc5-9bb7-8afedb6e1972")
+ )
+ (via
+ (at 106.855 116.84)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 4)
+ (uuid "ded85262-80fa-42ea-87ec-f3301fda62d4")
+ )
+ (segment
+ (start 43.069707 88.192551)
+ (end 43.069707 88.654606)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 4)
+ (uuid "6cecd3ab-5a68-4c8b-9910-1bfe527f9076")
+ )
+ (segment
+ (start 104.855 114.84)
+ (end 106.855 116.84)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 4)
+ (uuid "777c2d32-e2d1-4d40-b543-5cf91f551935")
+ )
+ (segment
+ (start 44.391985 63.169485)
+ (end 44.225 63.33647)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 4)
+ (uuid "7c77c448-28ae-4e06-857c-203b6df0525b")
+ )
+ (segment
+ (start 44.225 87.037258)
+ (end 43.069707 88.192551)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 4)
+ (uuid "7f6dedb1-576d-4b92-96c2-6a8a627f5508")
+ )
+ (segment
+ (start 104.855 114.64)
+ (end 104.855 114.84)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 4)
+ (uuid "bdb614d6-3753-48cb-aef6-fef4bfcc5084")
+ )
+ (segment
+ (start 44.225 63.33647)
+ (end 44.225 87.037258)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 4)
+ (uuid "dcb8e892-42ed-400c-919e-a2410941b448")
+ )
+ (segment
+ (start 63.719999 97.79)
+ (end 63.469999 97.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 5)
+ (uuid "13a93905-e8de-437c-b70a-4dc718587873")
+ )
+ (segment
+ (start 77.555 96.19)
+ (end 65.319999 96.19)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 5)
+ (uuid "327ea98e-1284-4e3b-a224-61d361900fd8")
+ )
+ (segment
+ (start 57.48 96.915)
+ (end 58.0375 96.915)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 5)
+ (uuid "6941cbe1-00ee-414e-8dc9-89254378b733")
+ )
+ (segment
+ (start 65.319999 96.19)
+ (end 63.719999 97.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 5)
+ (uuid "7e53b6a6-c8f1-4255-8297-f0d8ef9e835a")
+ )
+ (segment
+ (start 80.03 98.665)
+ (end 77.555 96.19)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 5)
+ (uuid "ba0349fb-e806-487d-9134-4c3cd1f43cf2")
+ )
+ (segment
+ (start 58.0375 96.915)
+ (end 58.9125 97.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 5)
+ (uuid "ca6be708-3828-454b-84b7-34d6ded85a80")
+ )
+ (via
+ (at 58.9125 97.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 5)
+ (uuid "14fa4856-4fd5-4f21-bf6c-f53b3be796c0")
+ )
+ (via
+ (at 63.469999 97.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 5)
+ (uuid "3d08ed13-f208-4300-9557-1e2c715a6d10")
+ )
+ (segment
+ (start 63.469999 97.79)
+ (end 58.9125 97.79)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 5)
+ (uuid "d493b7ac-bca1-4513-9d5b-92625113f549")
+ )
+ (segment
+ (start 106.13 96.19)
+ (end 108.605 98.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 6)
+ (uuid "297ffd81-32a3-4c9e-8cc1-add4c1f643f3")
+ )
+ (segment
+ (start 77.405 97.79)
+ (end 76.53 96.915)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 6)
+ (uuid "66163522-3278-4c9f-8852-286315b7e06d")
+ )
+ (segment
+ (start 77.9625 97.79)
+ (end 77.405 97.79)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 6)
+ (uuid "78bbd6aa-8d4c-4038-814a-ba789e3bf48c")
+ )
+ (segment
+ (start 84.325 96.19)
+ (end 106.13 96.19)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 6)
+ (uuid "8c322367-fb9f-4ab2-afae-def1566c8de7")
+ )
+ (segment
+ (start 82.725 97.79)
+ (end 84.325 96.19)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 6)
+ (uuid "971ab111-ab53-4f18-8e6d-d8be75397c52")
+ )
+ (via
+ (at 82.725 97.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 6)
+ (uuid "08f6f525-7088-480e-b484-053203392508")
+ )
+ (via
+ (at 77.9625 97.79)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 6)
+ (uuid "2c00b561-20be-48b1-ab11-94fe2cd2cd9b")
+ )
+ (segment
+ (start 82.725 97.79)
+ (end 77.9625 97.79)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 6)
+ (uuid "5b96aa51-1ab0-40d3-9045-0a305b8448ed")
+ )
+ (segment
+ (start 39.045 64.285)
+ (end 32.585 70.745)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 7)
+ (uuid "a7092661-c3aa-4fa0-b19c-4cabcc8d06d2")
+ )
+ (segment
+ (start 54.895 64.285)
+ (end 39.045 64.285)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 7)
+ (uuid "f54513fe-4acb-4a33-80e4-5cd6cada2d12")
+ )
+ (segment
+ (start 49.499214 72.223)
+ (end 33.647 72.223)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 8)
+ (uuid "128d8188-10ef-4bc3-9391-a41c7e8eb5d8")
+ )
+ (segment
+ (start 54.895 66.827214)
+ (end 49.499214 72.223)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 8)
+ (uuid "59c2db0a-48e6-4ef9-87b7-8ff721eb7771")
+ )
+ (segment
+ (start 33.647 72.223)
+ (end 32.585 73.285)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 8)
+ (uuid "a6ee2625-38c0-47ea-ad4d-69cb2d6d99c7")
+ )
+ (segment
+ (start 54.895 66.825)
+ (end 54.895 66.827214)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 8)
+ (uuid "fc00832b-1e83-4a74-83fc-023b7c98139c")
+ )
+ (segment
+ (start 56.045 66.348654)
+ (end 55.361346 65.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 9)
+ (uuid "26b8fb07-8415-4f1c-b559-7826c72c2e0f")
+ )
+ (segment
+ (start 54.895 69.365)
+ (end 56.045 68.215)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 9)
+ (uuid "2ce5dde8-fc26-472c-b796-772ed029b4d5")
+ )
+ (segment
+ (start 55.361346 65.665)
+ (end 47.825 65.665)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 9)
+ (uuid "baabf829-b2dc-47c5-88c6-dca24792bd31")
+ )
+ (segment
+ (start 56.045 68.215)
+ (end 56.045 66.348654)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 9)
+ (uuid "cecc71b7-4a17-4f75-ba99-31cb7b5ae229")
+ )
+ (segment
+ (start 36.37 104.775)
+ (end 48.565 104.775)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 10)
+ (uuid "1d7022b0-1cae-4b03-80a9-aa7b9dd2c8c7")
+ )
+ (segment
+ (start 48.565 104.775)
+ (end 49.725 103.615)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 10)
+ (uuid "d79ff055-b6b1-4cb3-849f-9c0c253f07ed")
+ )
+ (segment
+ (start 61.77 86.42)
+ (end 61.675 86.325)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "1d906c21-12fd-4e58-a9e9-de8d70e46939")
+ )
+ (segment
+ (start 37.335 84.585)
+ (end 34.165 81.415)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "2cc6b446-144b-4a2d-a31b-ca9e56d4698e")
+ )
+ (segment
+ (start 62.869999 101.135001)
+ (end 62.869999 93.433528)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "31264445-3bc1-45cc-9884-76edacdf5c15")
+ )
+ (segment
+ (start 62.869999 93.433528)
+ (end 61.675 92.238529)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "50398bdd-104e-419f-8183-0dccf19f782f")
+ )
+ (segment
+ (start 61.675 92.238529)
+ (end 61.675 86.325)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "5aa89109-ebe8-41f8-a5a8-ae54d8db2922")
+ )
+ (segment
+ (start 43.299899 84.585)
+ (end 37.335 84.585)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "64d3bad8-f180-408b-b9c1-e32eeb28e60d")
+ )
+ (segment
+ (start 61.77 83.185)
+ (end 44.699899 83.185)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "863faace-6a61-46d3-b88d-b64d22e0561a")
+ )
+ (segment
+ (start 34.165 81.415)
+ (end 33.185 81.415)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "9085e836-9271-4ef7-88e5-e2d6a8daf25a")
+ )
+ (segment
+ (start 44.699899 83.185)
+ (end 43.299899 84.585)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "cd2a1547-989f-4eb1-9f69-44ad9844a341")
+ )
+ (segment
+ (start 61.77 102.235)
+ (end 62.869999 101.135001)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 11)
+ (uuid "e73dda5b-895a-4c5d-923a-ef352807dae5")
+ )
+ (via
+ (at 33.185 81.415)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 11)
+ (uuid "28df3ae0-aa78-45dc-be82-5866149b7cf3")
+ )
+ (via
+ (at 61.675 86.325)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 11)
+ (uuid "2b590312-e8d6-460c-81a7-30bd3e34c355")
+ )
+ (segment
+ (start 61.675 86.325)
+ (end 61.675 85.885)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 11)
+ (uuid "4161f437-660f-4f08-ac52-e4e57088b1ef")
+ )
+ (segment
+ (start 61.675 85.885)
+ (end 61.77 85.79)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 11)
+ (uuid "6c8ce530-21b9-4106-a663-bed4f224e0ea")
+ )
+ (segment
+ (start 31.523 66.727)
+ (end 32.585 65.665)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 11)
+ (uuid "acc1bd09-bf0c-44cf-b42b-dda15488ccc3")
+ )
+ (segment
+ (start 33.185 81.415)
+ (end 31.523 79.753)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 11)
+ (uuid "bdcaf52d-bf78-4ecb-ad95-9835b1633a5c")
+ )
+ (segment
+ (start 61.77 85.79)
+ (end 61.77 83.185)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 11)
+ (uuid "d98c272e-ee36-4833-909f-938dc839a9fa")
+ )
+ (segment
+ (start 31.523 79.753)
+ (end 31.523 66.727)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 11)
+ (uuid "e8a786eb-7a05-408f-a3b0-6baf94fcd26f")
+ )
+ (segment
+ (start 67.675 104.775)
+ (end 68.705 103.745)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 12)
+ (uuid "0ab3465f-a9f7-4b0d-bc80-8ef0f115dff1")
+ )
+ (segment
+ (start 55.42 104.775)
+ (end 67.675 104.775)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 12)
+ (uuid "188317ec-3f0d-40b4-b69c-4bbe0bf9bd69")
+ )
+ (segment
+ (start 74.47 104.775)
+ (end 86.745 104.775)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 13)
+ (uuid "e2bfc640-0493-4375-a99c-6b5459a11fd7")
+ )
+ (segment
+ (start 86.745 104.775)
+ (end 87.865 103.655)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 13)
+ (uuid "e6c8ea55-6505-4d29-b7b2-7b7912093202")
+ )
+ (segment
+ (start 61.609899 85.325)
+ (end 60.609899 84.325)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "09c72520-9e0f-4aed-961d-5eaab02b29f7")
+ )
+ (segment
+ (start 80.82 102.235)
+ (end 82.125 100.93)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "0d742387-4c7e-486e-bf70-3f20ce54b162")
+ )
+ (segment
+ (start 54.840101 84.325)
+ (end 52.778743 86.386358)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "13816258-2795-40eb-951c-bd70ed81cd2a")
+ )
+ (segment
+ (start 82.125 100.93)
+ (end 82.125 93.938529)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "30e572fa-2972-4557-a3ce-5019fc256fd4")
+ )
+ (segment
+ (start 80.82 92.633529)
+ (end 80.82 86.37)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "38187100-e8e0-4139-95d9-1ace296e884a")
+ )
+ (segment
+ (start 60.609899 84.325)
+ (end 54.840101 84.325)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "6504a3ed-d18b-48a8-be70-1c8af900516e")
+ )
+ (segment
+ (start 80.82 83.185)
+ (end 79.42 81.785)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "7af45386-61f2-4072-8c3b-c2489528be04")
+ )
+ (segment
+ (start 80.82 86.37)
+ (end 80.865 86.325)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "a3fe9462-ddb3-4b18-9f6b-ac9124f48e2a")
+ )
+ (segment
+ (start 79.42 81.785)
+ (end 65.149899 81.785)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "c3a1e0b3-e9a7-4f4d-bae7-e16f48af10cf")
+ )
+ (segment
+ (start 52.778743 86.386358)
+ (end 43.522646 86.386358)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "d4af6591-5db5-4f45-8ff4-45872e6afec5")
+ )
+ (segment
+ (start 65.149899 81.785)
+ (end 61.609899 85.325)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "dabf0011-609c-49f2-bef9-443e5b156abb")
+ )
+ (segment
+ (start 82.125 93.938529)
+ (end 80.82 92.633529)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 14)
+ (uuid "e14fb725-6daf-4b20-9ab1-23c0a2472c2b")
+ )
+ (via
+ (at 43.522646 86.386358)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 14)
+ (uuid "52a216a5-72a7-4c71-a156-d16dd73203e2")
+ )
+ (via
+ (at 80.865 86.325)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 14)
+ (uuid "c9d5b3ca-84f0-4c62-8e7f-ee5c21ec2981")
+ )
+ (segment
+ (start 33.647 64.187)
+ (end 32.585 63.125)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "0c32bcd0-7ce3-4b98-a7fc-976687272c50")
+ )
+ (segment
+ (start 42.984004 86.925)
+ (end 42.476471 86.925)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "1e77e8c5-75fd-4d4c-90a5-8d2c9a6a9d92")
+ )
+ (segment
+ (start 43.522646 86.386358)
+ (end 42.984004 86.925)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "273fc8e3-3b06-4c07-bc7c-2bb0e3bf0fb2")
+ )
+ (segment
+ (start 42.476471 86.925)
+ (end 33.647 78.095529)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "28035783-6cb1-4400-a335-7ea45c8cffa1")
+ )
+ (segment
+ (start 80.82 85.84)
+ (end 80.82 83.185)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "32f5d65b-f3f2-44e3-872c-3257b7b0c84e")
+ )
+ (segment
+ (start 80.865 85.885)
+ (end 80.82 85.84)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "4bd37b9c-a1de-4629-a389-a261b1d14be6")
+ )
+ (segment
+ (start 80.865 86.325)
+ (end 80.865 85.885)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "6547c18c-25b3-4bd8-bbd2-ad1b5e39c4ce")
+ )
+ (segment
+ (start 33.647 78.095529)
+ (end 33.647 64.187)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 14)
+ (uuid "7bfebd80-cda3-44a2-adb6-e88a6f0724a9")
+ )
+ (segment
+ (start 48.565 85.725)
+ (end 49.725 84.565)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 15)
+ (uuid "707df198-e2f5-4d35-a2ea-0940f5d06f38")
+ )
+ (segment
+ (start 36.37 85.725)
+ (end 48.565 85.725)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 15)
+ (uuid "c4473e35-960d-4017-970d-f94e64cd6d82")
+ )
+ (segment
+ (start 67.635 85.725)
+ (end 68.705 84.655)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 16)
+ (uuid "bf4b93e7-7227-495d-ab53-a31ba0d2f6f6")
+ )
+ (segment
+ (start 55.42 85.725)
+ (end 67.635 85.725)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 16)
+ (uuid "c19ee607-4ea6-450c-90e5-8ddcad669712")
+ )
+ (segment
+ (start 74.47 85.725)
+ (end 86.785 85.725)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 17)
+ (uuid "1cb4361c-9281-4acc-8734-c58dcec8ab61")
+ )
+ (segment
+ (start 86.785 85.725)
+ (end 87.855 84.655)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 17)
+ (uuid "ca3a95fe-dc8e-4565-a2c3-a2d1539c5142")
+ )
+ (segment
+ (start 111.6175 100.0125)
+ (end 109.395 102.235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 18)
+ (uuid "1509f082-2f53-42ed-a03a-e328acbd1cf6")
+ )
+ (segment
+ (start 109.395 83.185)
+ (end 107.398235 81.188235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 18)
+ (uuid "1e21471e-cb16-4f4e-9c4c-5b8090b12228")
+ )
+ (segment
+ (start 111.6175 89.644556)
+ (end 111.6175 100.0125)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 18)
+ (uuid "7db47ceb-5a37-41c3-8970-9aecfef3ee9f")
+ )
+ (segment
+ (start 107.398235 81.188235)
+ (end 41.571765 81.188235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 18)
+ (uuid "b4019566-98f3-4159-858d-e0802b27a261")
+ )
+ (segment
+ (start 111.6175 89.644556)
+ (end 109.395 87.422056)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 18)
+ (uuid "c3a8aae1-9536-443a-a805-56ed3a81eb89")
+ )
+ (segment
+ (start 109.395 87.422056)
+ (end 109.395 83.185)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 18)
+ (uuid "d038f82d-554c-4597-8162-7003082f1255")
+ )
+ (via
+ (at 41.571765 81.188235)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 18)
+ (uuid "ae314458-f0da-40d4-8e98-3c37fe0444cc")
+ )
+ (segment
+ (start 34.155 77.965)
+ (end 37.378235 81.188235)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 18)
+ (uuid "17872b74-d48a-4ec6-924f-645f87a9be28")
+ )
+ (segment
+ (start 34.155 62.155)
+ (end 34.155 77.965)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 18)
+ (uuid "62d30922-5fa7-4999-a497-7aaee7eb228a")
+ )
+ (segment
+ (start 32.585 60.585)
+ (end 34.155 62.155)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 18)
+ (uuid "c4924d2d-bc45-4ee7-82f5-7d268b67b634")
+ )
+ (segment
+ (start 37.378235 81.188235)
+ (end 41.571765 81.188235)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 18)
+ (uuid "ecb88937-f103-4b1d-ae71-41c65ea71371")
+ )
+ (segment
+ (start 98.135 85.725)
+ (end 97.025 84.615)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 19)
+ (uuid "40521558-ce8e-4f20-89c8-81a7a32effd9")
+ )
+ (segment
+ (start 103.045 85.725)
+ (end 98.135 85.725)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 19)
+ (uuid "9535fee2-95e0-4b0c-9f61-20957c3fc18e")
+ )
+ (segment
+ (start 98.105 104.775)
+ (end 97.055 103.725)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 20)
+ (uuid "35ada209-889a-477b-bf67-d10713bb1da5")
+ )
+ (segment
+ (start 103.045 104.775)
+ (end 98.105 104.775)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 20)
+ (uuid "67f30628-88eb-4290-b37d-737e425f11d0")
+ )
+ (segment
+ (start 49.725 111.235)
+ (end 37.322944 111.235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "13c50bc4-fb09-400f-a4bd-69ce626ad2ab")
+ )
+ (segment
+ (start 32.585 106.497056)
+ (end 32.585 75.825)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "3fc02fc1-5623-4cbf-853d-af93a8ced068")
+ )
+ (segment
+ (start 97.055 111.345)
+ (end 96.985 111.275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "51970218-6ddf-4917-bc36-460c18d43585")
+ )
+ (segment
+ (start 87.775 111.365)
+ (end 87.865 111.275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "727441c7-e1a2-4180-bb20-ef9644df935c")
+ )
+ (segment
+ (start 68.705 111.365)
+ (end 87.775 111.365)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "77513a1b-d20d-4502-afeb-b9f0c5f716f7")
+ )
+ (segment
+ (start 37.322944 111.235)
+ (end 32.585 106.497056)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "a8fb392c-85b5-4084-819e-f7c3fb3d9eb2")
+ )
+ (segment
+ (start 68.575 111.235)
+ (end 68.705 111.365)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "b4f14c0d-f18f-4fe2-97a8-5ee22fa3c439")
+ )
+ (segment
+ (start 49.725 111.235)
+ (end 68.575 111.235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "bdbb8cfd-6338-4ea4-821c-6362854135be")
+ )
+ (segment
+ (start 87.865 111.275)
+ (end 96.985 111.275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "db5cf461-cbfc-427a-9873-019c2a37ab78")
+ )
+ (segment
+ (start 97.33 111.345)
+ (end 97.055 111.345)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 21)
+ (uuid "ef48fa04-bfaf-45b4-a731-4ee3cb456a39")
+ )
+ (segment
+ (start 49.499214 74.347)
+ (end 50.577214 75.425)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "0f0e78f9-0446-4862-9903-a652dd3fc8dc")
+ )
+ (segment
+ (start 97.025 92.235)
+ (end 87.895 92.235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "2bcbbdbc-27b2-40b7-9f9f-ad6431b9ca4f")
+ )
+ (segment
+ (start 93.858235 81.89147)
+ (end 93.755 81.788235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "350c656c-0bdd-42fc-a668-8387cce84ab3")
+ )
+ (segment
+ (start 81.53 92.275)
+ (end 81.42 92.385)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "365b83af-af87-4a4b-9649-9948e91d4d87")
+ )
+ (segment
+ (start 46.515 72.823)
+ (end 46.515 73.485)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "3e9d3e70-e1c5-4684-bdfd-a5ec474aa8ef")
+ )
+ (segment
+ (start 87.855 92.275)
+ (end 81.53 92.275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "4bac80b6-0fba-4c2b-be88-5b25f8d0faed")
+ )
+ (segment
+ (start 47.377 74.347)
+ (end 49.499214 74.347)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "4d74a632-8507-4460-b0da-6c35c58a658d")
+ )
+ (segment
+ (start 68.705 92.275)
+ (end 62.56 92.275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "5b573ff3-dbd1-4af6-b989-34a353f25083")
+ )
+ (segment
+ (start 93.858235 89.068235)
+ (end 93.858235 81.89147)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "64240a74-21e5-49e8-91fd-53a50a8bd9a2")
+ )
+ (segment
+ (start 62.56 92.275)
+ (end 62.37 92.085)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "6a427787-8393-4d55-8ea3-5fd1ee5abbed")
+ )
+ (segment
+ (start 97.025 92.235)
+ (end 93.858235 89.068235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "76e09803-ccaf-44a2-8207-5a5f0c6283d8")
+ )
+ (segment
+ (start 50.577214 75.425)
+ (end 91.735 75.425)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "8d786696-4738-409f-8164-f0e02388c600")
+ )
+ (segment
+ (start 91.735 75.425)
+ (end 94.415 72.745)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "94515c59-1ea3-495e-ba45-c8644006e5e9")
+ )
+ (segment
+ (start 46.515 73.485)
+ (end 47.377 74.347)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "b792a4b2-cb63-46c3-a7ec-31d44b6f2d77")
+ )
+ (segment
+ (start 97.33 92.235)
+ (end 97.025 92.235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "c33d46a3-3e34-4af3-8fca-b84982912121")
+ )
+ (segment
+ (start 87.895 92.235)
+ (end 87.855 92.275)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 22)
+ (uuid "df9eeed0-6cb9-47ce-8711-c91f2a23bf0f")
+ )
+ (via
+ (at 81.42 92.385)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 22)
+ (uuid "0029fd8f-dc3b-46d7-9e19-f58cb38b0700")
+ )
+ (via
+ (at 46.515 72.823)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 22)
+ (uuid "8ae4d707-5076-49c3-9775-045e4a631cad")
+ )
+ (via
+ (at 93.755 81.788235)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 22)
+ (uuid "bd9c20ef-878e-4c33-8bef-6f0bfd3bb352")
+ )
+ (via
+ (at 62.37 92.085)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 22)
+ (uuid "d58518ca-2bd2-4a1b-b29e-390514e40e06")
+ )
+ (segment
+ (start 93.755 73.405)
+ (end 94.415 72.745)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "03c0ba24-44b9-4db0-a1a6-95158a6d2e8f")
+ )
+ (segment
+ (start 46.515 72.055)
+ (end 47.825 70.745)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "106be2f3-2cec-41bd-b1b5-a472b95dbb39")
+ )
+ (segment
+ (start 62.37 92.085)
+ (end 62.27 92.185)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "3e19d21a-64fe-4563-bf1e-8654c05a8897")
+ )
+ (segment
+ (start 62.27 92.185)
+ (end 49.725 92.185)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "4b1f3e80-791e-4b64-8372-36c0be95ed4b")
+ )
+ (segment
+ (start 81.065 92.385)
+ (end 80.955 92.275)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "507018db-96f9-459b-8e64-0b53a9b1241b")
+ )
+ (segment
+ (start 46.515 72.823)
+ (end 46.515 72.055)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "58dc06f5-3190-4458-a734-3c1cec24d0dc")
+ )
+ (segment
+ (start 93.755 81.588235)
+ (end 93.755 73.405)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "b0ed12b0-9635-4672-b0ab-73bddb12040d")
+ )
+ (segment
+ (start 80.955 92.275)
+ (end 68.705 92.275)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "ec7f76b5-25f6-4f33-b62f-eb2dc649cf7c")
+ )
+ (segment
+ (start 81.42 92.385)
+ (end 81.065 92.385)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 22)
+ (uuid "ff1a2faa-4002-4536-b467-7b20cc94adb7")
+ )
+ (segment
+ (start 112.585 64.155)
+ (end 114.035 65.605)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 23)
+ (uuid "6b69d90e-a460-4b1a-a5c7-2485e63306cf")
+ )
+ (segment
+ (start 94.415 65.125)
+ (end 95.385 64.155)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 23)
+ (uuid "e2c222aa-18a0-4fa0-9c96-9880c1ff40c7")
+ )
+ (segment
+ (start 95.385 64.155)
+ (end 112.585 64.155)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 23)
+ (uuid "f614ecaa-ca3b-4949-b819-d83e2b5b8550")
+ )
+ (segment
+ (start 30.910786 74.763)
+ (end 30.045 73.897214)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "0cf95e46-16d4-4481-8351-e6a01b2cedcb")
+ )
+ (segment
+ (start 44.9425 100.0125)
+ (end 42.72 102.235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "18b1f658-43cc-40ab-8c86-8c68cfa9d321")
+ )
+ (segment
+ (start 30.045 73.897214)
+ (end 30.045 69.91)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "1d210f1c-38e0-468d-8b32-80dfaa0ec34f")
+ )
+ (segment
+ (start 104.051765 80.588235)
+ (end 114.035 70.605)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "3a0383f5-093c-4e3b-939e-38b4e0322f33")
+ )
+ (segment
+ (start 42.72 83.185)
+ (end 34.298 74.763)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "3e1a53a6-ae6a-4648-b3ff-b8b7c14edac9")
+ )
+ (segment
+ (start 42.72 86.33)
+ (end 42.725 86.325)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "795a6ebb-2da0-4757-8d1f-37d36e41237e")
+ )
+ (segment
+ (start 44.9425 89.644556)
+ (end 44.9425 100.0125)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "79da4718-267b-4a68-8b2e-f37f11a66c8b")
+ )
+ (segment
+ (start 30.045 69.91)
+ (end 31.75 68.205)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "80338ca8-ca74-41e4-ae67-295fa48ff2d2")
+ )
+ (segment
+ (start 40.971765 81.436765)
+ (end 40.971765 80.939706)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "831e5099-f5c5-49de-9ede-2e10001b7354")
+ )
+ (segment
+ (start 34.298 74.763)
+ (end 30.910786 74.763)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "8b5b762a-3dc4-4544-9487-e0795ccb9a4b")
+ )
+ (segment
+ (start 42.72 83.185)
+ (end 40.971765 81.436765)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "8f9d4787-eb34-4570-b3a1-173f5c236451")
+ )
+ (segment
+ (start 31.75 68.205)
+ (end 32.585 68.205)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "a65c579d-174a-44dc-ad1e-ea6b162eab43")
+ )
+ (segment
+ (start 42.725 86.325)
+ (end 42.725 87.427056)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "b6035d2c-701a-4d8f-8539-7722ceb152fb")
+ )
+ (segment
+ (start 41.323236 80.588235)
+ (end 104.051765 80.588235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "c6aa9071-4f85-43af-a6af-4781bc1db73e")
+ )
+ (segment
+ (start 42.725 87.427056)
+ (end 44.9425 89.644556)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "d54ee5ca-c75e-438c-a49d-1cca99e0ad73")
+ )
+ (segment
+ (start 40.971765 80.939706)
+ (end 41.323236 80.588235)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 24)
+ (uuid "fdabdcc6-b802-4e56-b94b-38d690b48d6f")
+ )
+ (via
+ (at 42.725 86.325)
+ (size 0.6)
+ (drill 0.3)
+ (layers "F.Cu" "B.Cu")
+ (net 24)
+ (uuid "3cfe2570-da5d-4208-8476-fbdfe744bc21")
+ )
+ (segment
+ (start 42.725 85.965)
+ (end 42.72 85.96)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 24)
+ (uuid "0e72b7bf-dd36-494f-aa64-82cb5550cf79")
+ )
+ (segment
+ (start 42.72 85.96)
+ (end 42.72 83.185)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 24)
+ (uuid "2c199dbb-edda-498a-ae9f-75def93ef45e")
+ )
+ (segment
+ (start 42.725 86.325)
+ (end 42.725 85.965)
+ (width 0.2)
+ (layer "B.Cu")
+ (net 24)
+ (uuid "855e063f-8099-4155-8d3c-a31218fdbe12")
+ )
+ (segment
+ (start 48.66 73.285)
+ (end 49.039315 73.285)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 25)
+ (uuid "03d0fc64-44ef-4475-b412-e3b59565e51b")
+ )
+ (segment
+ (start 49.0029 73.285)
+ (end 47.825 73.285)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 25)
+ (uuid "3285d67a-8911-4f3d-b90e-a07415775d98")
+ )
+ (segment
+ (start 94.355 70.605)
+ (end 99.535 70.605)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 25)
+ (uuid "80589739-b613-4452-b919-713580469006")
+ )
+ (segment
+ (start 49.039315 73.285)
+ (end 50.649315 74.895)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 25)
+ (uuid "c782cadb-0325-4bd5-8be9-65ae7b20cb73")
+ )
+ (segment
+ (start 50.649315 74.895)
+ (end 90.065 74.895)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 25)
+ (uuid "c7bce07a-65e1-4322-a76e-478ee6d67ff6")
+ )
+ (segment
+ (start 90.065 74.895)
+ (end 94.355 70.605)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 25)
+ (uuid "e4827eb1-f60a-408e-b547-a2238046b3b2")
+ )
+ (segment
+ (start 100.835 71.143478)
+ (end 100.835 66.905)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 26)
+ (uuid "477068da-233a-4b81-9411-5a930851230a")
+ )
+ (segment
+ (start 47.825 75.825)
+ (end 96.153478 75.825)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 26)
+ (uuid "88dd5a81-e64f-45af-b261-6b7664fda4e8")
+ )
+ (segment
+ (start 100.835 66.905)
+ (end 99.535 65.605)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 26)
+ (uuid "890c69de-fafe-48c4-a42b-5165758880c6")
+ )
+ (segment
+ (start 96.153478 75.825)
+ (end 100.835 71.143478)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 26)
+ (uuid "bba9fe71-5912-460c-bc07-14d72dc69f3c")
+ )
+ (segment
+ (start 105.0175 115.965)
+ (end 103.2675 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 27)
+ (uuid "6c184477-4648-4654-aa68-53b57340865c")
+ )
+ (segment
+ (start 103.2675 117.715)
+ (end 80.03 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 27)
+ (uuid "ea725115-3078-43ea-ab32-6c2af576aaad")
+ )
+ (segment
+ (start 74.78 117.715)
+ (end 76.53 115.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 28)
+ (uuid "59bdeb2d-4014-4af8-b1cb-d16637025f32")
+ )
+ (segment
+ (start 60.98 117.715)
+ (end 74.78 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 28)
+ (uuid "783ae8b2-073d-4f5b-b24e-9e0dc5ea4b1d")
+ )
+ (segment
+ (start 55.73 117.715)
+ (end 57.48 115.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 29)
+ (uuid "4bf95508-7584-46a6-9aa6-aed5edc463bd")
+ )
+ (segment
+ (start 42.1425 117.715)
+ (end 55.73 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 29)
+ (uuid "67d9dfa4-44bc-4a29-8b88-974b3f8f1289")
+ )
+ (segment
+ (start 109.6175 116.69)
+ (end 108.5925 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 31)
+ (uuid "0ac9531f-316d-483c-bb13-b728cbd99bd4")
+ )
+ (segment
+ (start 105.105 96.915)
+ (end 107.828402 99.638402)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 31)
+ (uuid "56270ec4-53b3-4ea1-93dc-856a8413a684")
+ )
+ (segment
+ (start 108.5925 117.715)
+ (end 108.5175 117.715)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 31)
+ (uuid "66c25608-916f-491c-980a-8e96baaa3178")
+ )
+ (segment
+ (start 107.828402 99.638402)
+ (end 107.828402 104.965)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 31)
+ (uuid "98f27cc3-9a8e-4ca0-a039-7bf3d34b12e2")
+ )
+ (segment
+ (start 107.828402 104.965)
+ (end 109.6175 106.754098)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 31)
+ (uuid "ac1bfca9-1267-4462-a6f7-8a7b5d13337b")
+ )
+ (segment
+ (start 109.6175 106.754098)
+ (end 109.6175 116.69)
+ (width 0.2)
+ (layer "F.Cu")
+ (net 31)
+ (uuid "ea26ed17-3cd7-486c-8fa3-813ebdee0cbd")
+ )
+)
diff --git a/hackpads/blipyboard/pcb/hackpad copy.kicad_pro b/hackpads/blipyboard/pcb/hackpad copy.kicad_pro
new file mode 100644
index 0000000000..1ad86f6aa2
--- /dev/null
+++ b/hackpads/blipyboard/pcb/hackpad copy.kicad_pro
@@ -0,0 +1,584 @@
+{
+ "board": {
+ "3dviewports": [],
+ "design_settings": {
+ "defaults": {
+ "apply_defaults_to_fp_fields": false,
+ "apply_defaults_to_fp_shapes": false,
+ "apply_defaults_to_fp_text": false,
+ "board_outline_line_width": 0.05,
+ "copper_line_width": 0.2,
+ "copper_text_italic": false,
+ "copper_text_size_h": 1.5,
+ "copper_text_size_v": 1.5,
+ "copper_text_thickness": 0.3,
+ "copper_text_upright": false,
+ "courtyard_line_width": 0.05,
+ "dimension_precision": 4,
+ "dimension_units": 3,
+ "dimensions": {
+ "arrow_length": 1270000,
+ "extension_offset": 500000,
+ "keep_text_aligned": true,
+ "suppress_zeroes": false,
+ "text_position": 0,
+ "units_format": 1
+ },
+ "fab_line_width": 0.1,
+ "fab_text_italic": false,
+ "fab_text_size_h": 1.0,
+ "fab_text_size_v": 1.0,
+ "fab_text_thickness": 0.15,
+ "fab_text_upright": false,
+ "other_line_width": 0.1,
+ "other_text_italic": false,
+ "other_text_size_h": 1.0,
+ "other_text_size_v": 1.0,
+ "other_text_thickness": 0.15,
+ "other_text_upright": false,
+ "pads": {
+ "drill": 0.762,
+ "height": 1.524,
+ "width": 1.524
+ },
+ "silk_line_width": 0.1,
+ "silk_text_italic": false,
+ "silk_text_size_h": 1.0,
+ "silk_text_size_v": 1.0,
+ "silk_text_thickness": 0.1,
+ "silk_text_upright": false,
+ "zones": {
+ "min_clearance": 0.5
+ }
+ },
+ "diff_pair_dimensions": [],
+ "drc_exclusions": [],
+ "meta": {
+ "version": 2
+ },
+ "rule_severities": {
+ "annular_width": "error",
+ "clearance": "error",
+ "connection_width": "warning",
+ "copper_edge_clearance": "error",
+ "copper_sliver": "warning",
+ "courtyards_overlap": "error",
+ "diff_pair_gap_out_of_range": "error",
+ "diff_pair_uncoupled_length_too_long": "error",
+ "drill_out_of_range": "error",
+ "duplicate_footprints": "warning",
+ "extra_footprint": "warning",
+ "footprint": "error",
+ "footprint_symbol_mismatch": "warning",
+ "footprint_type_mismatch": "ignore",
+ "hole_clearance": "error",
+ "hole_near_hole": "error",
+ "holes_co_located": "warning",
+ "invalid_outline": "error",
+ "isolated_copper": "warning",
+ "item_on_disabled_layer": "error",
+ "items_not_allowed": "error",
+ "length_out_of_range": "error",
+ "lib_footprint_issues": "warning",
+ "lib_footprint_mismatch": "warning",
+ "malformed_courtyard": "error",
+ "microvia_drill_out_of_range": "error",
+ "missing_courtyard": "ignore",
+ "missing_footprint": "warning",
+ "net_conflict": "warning",
+ "npth_inside_courtyard": "ignore",
+ "padstack": "warning",
+ "pth_inside_courtyard": "ignore",
+ "shorting_items": "error",
+ "silk_edge_clearance": "warning",
+ "silk_over_copper": "warning",
+ "silk_overlap": "warning",
+ "skew_out_of_range": "error",
+ "solder_mask_bridge": "error",
+ "starved_thermal": "error",
+ "text_height": "warning",
+ "text_thickness": "warning",
+ "through_hole_pad_without_hole": "error",
+ "too_many_vias": "error",
+ "track_dangling": "warning",
+ "track_width": "error",
+ "tracks_crossing": "error",
+ "unconnected_items": "error",
+ "unresolved_variable": "error",
+ "via_dangling": "warning",
+ "zones_intersect": "error"
+ },
+ "rules": {
+ "max_error": 0.005,
+ "min_clearance": 0.0,
+ "min_connection": 0.0,
+ "min_copper_edge_clearance": 0.5,
+ "min_hole_clearance": 0.25,
+ "min_hole_to_hole": 0.25,
+ "min_microvia_diameter": 0.2,
+ "min_microvia_drill": 0.1,
+ "min_resolved_spokes": 2,
+ "min_silk_clearance": 0.0,
+ "min_text_height": 0.8,
+ "min_text_thickness": 0.08,
+ "min_through_hole_diameter": 0.3,
+ "min_track_width": 0.0,
+ "min_via_annular_width": 0.1,
+ "min_via_diameter": 0.5,
+ "solder_mask_to_copper_clearance": 0.0,
+ "use_height_for_length_calcs": true
+ },
+ "teardrop_options": [
+ {
+ "td_onpadsmd": true,
+ "td_onroundshapesonly": false,
+ "td_ontrackend": false,
+ "td_onviapad": true
+ }
+ ],
+ "teardrop_parameters": [
+ {
+ "td_allow_use_two_tracks": true,
+ "td_curve_segcount": 0,
+ "td_height_ratio": 1.0,
+ "td_length_ratio": 0.5,
+ "td_maxheight": 2.0,
+ "td_maxlen": 1.0,
+ "td_on_pad_in_zone": false,
+ "td_target_name": "td_round_shape",
+ "td_width_to_size_filter_ratio": 0.9
+ },
+ {
+ "td_allow_use_two_tracks": true,
+ "td_curve_segcount": 0,
+ "td_height_ratio": 1.0,
+ "td_length_ratio": 0.5,
+ "td_maxheight": 2.0,
+ "td_maxlen": 1.0,
+ "td_on_pad_in_zone": false,
+ "td_target_name": "td_rect_shape",
+ "td_width_to_size_filter_ratio": 0.9
+ },
+ {
+ "td_allow_use_two_tracks": true,
+ "td_curve_segcount": 0,
+ "td_height_ratio": 1.0,
+ "td_length_ratio": 0.5,
+ "td_maxheight": 2.0,
+ "td_maxlen": 1.0,
+ "td_on_pad_in_zone": false,
+ "td_target_name": "td_track_end",
+ "td_width_to_size_filter_ratio": 0.9
+ }
+ ],
+ "track_widths": [],
+ "tuning_pattern_settings": {
+ "diff_pair_defaults": {
+ "corner_radius_percentage": 80,
+ "corner_style": 1,
+ "max_amplitude": 1.0,
+ "min_amplitude": 0.2,
+ "single_sided": false,
+ "spacing": 1.0
+ },
+ "diff_pair_skew_defaults": {
+ "corner_radius_percentage": 80,
+ "corner_style": 1,
+ "max_amplitude": 1.0,
+ "min_amplitude": 0.2,
+ "single_sided": false,
+ "spacing": 0.6
+ },
+ "single_track_defaults": {
+ "corner_radius_percentage": 80,
+ "corner_style": 1,
+ "max_amplitude": 1.0,
+ "min_amplitude": 0.2,
+ "single_sided": false,
+ "spacing": 0.6
+ }
+ },
+ "via_dimensions": [],
+ "zones_allow_external_fillets": false
+ },
+ "ipc2581": {
+ "dist": "",
+ "distpn": "",
+ "internal_id": "",
+ "mfg": "",
+ "mpn": ""
+ },
+ "layer_presets": [],
+ "viewports": []
+ },
+ "boards": [],
+ "cvpcb": {
+ "equivalence_files": []
+ },
+ "erc": {
+ "erc_exclusions": [],
+ "meta": {
+ "version": 0
+ },
+ "pin_map": [
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 2,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 2,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2
+ ]
+ ],
+ "rule_severities": {
+ "bus_definition_conflict": "error",
+ "bus_entry_needed": "error",
+ "bus_to_bus_conflict": "error",
+ "bus_to_net_conflict": "error",
+ "conflicting_netclasses": "error",
+ "different_unit_footprint": "error",
+ "different_unit_net": "error",
+ "duplicate_reference": "error",
+ "duplicate_sheet_names": "error",
+ "endpoint_off_grid": "warning",
+ "extra_units": "error",
+ "global_label_dangling": "warning",
+ "hier_label_mismatch": "error",
+ "label_dangling": "error",
+ "lib_symbol_issues": "warning",
+ "missing_bidi_pin": "warning",
+ "missing_input_pin": "warning",
+ "missing_power_pin": "error",
+ "missing_unit": "warning",
+ "multiple_net_names": "warning",
+ "net_not_bus_member": "warning",
+ "no_connect_connected": "warning",
+ "no_connect_dangling": "warning",
+ "pin_not_connected": "error",
+ "pin_not_driven": "error",
+ "pin_to_pin": "warning",
+ "power_pin_not_driven": "error",
+ "similar_labels": "warning",
+ "simulation_model_issue": "ignore",
+ "unannotated": "error",
+ "unit_value_mismatch": "error",
+ "unresolved_variable": "error",
+ "wire_dangling": "error"
+ }
+ },
+ "libraries": {
+ "pinned_footprint_libs": [],
+ "pinned_symbol_libs": []
+ },
+ "meta": {
+ "filename": "hackpad.kicad_pro",
+ "version": 1
+ },
+ "net_settings": {
+ "classes": [
+ {
+ "bus_width": 12,
+ "clearance": 0.2,
+ "diff_pair_gap": 0.25,
+ "diff_pair_via_gap": 0.25,
+ "diff_pair_width": 0.2,
+ "line_style": 0,
+ "microvia_diameter": 0.3,
+ "microvia_drill": 0.1,
+ "name": "Default",
+ "pcb_color": "rgba(0, 0, 0, 0.000)",
+ "schematic_color": "rgba(0, 0, 0, 0.000)",
+ "track_width": 0.2,
+ "via_diameter": 0.6,
+ "via_drill": 0.3,
+ "wire_width": 6
+ }
+ ],
+ "meta": {
+ "version": 3
+ },
+ "net_colors": null,
+ "netclass_assignments": null,
+ "netclass_patterns": []
+ },
+ "pcbnew": {
+ "last_paths": {
+ "gencad": "",
+ "idf": "",
+ "netlist": "",
+ "plot": "",
+ "pos_files": "",
+ "specctra_dsn": "",
+ "step": "hackpad.step",
+ "svg": "",
+ "vrml": "hackpad.wrl"
+ },
+ "page_layout_descr_file": ""
+ },
+ "schematic": {
+ "annotate_start_num": 0,
+ "bom_export_filename": "",
+ "bom_fmt_presets": [],
+ "bom_fmt_settings": {
+ "field_delimiter": ",",
+ "keep_line_breaks": false,
+ "keep_tabs": false,
+ "name": "CSV",
+ "ref_delimiter": ",",
+ "ref_range_delimiter": "",
+ "string_delimiter": "\""
+ },
+ "bom_presets": [],
+ "bom_settings": {
+ "exclude_dnp": false,
+ "fields_ordered": [
+ {
+ "group_by": false,
+ "label": "Reference",
+ "name": "Reference",
+ "show": true
+ },
+ {
+ "group_by": true,
+ "label": "Value",
+ "name": "Value",
+ "show": true
+ },
+ {
+ "group_by": false,
+ "label": "Datasheet",
+ "name": "Datasheet",
+ "show": true
+ },
+ {
+ "group_by": false,
+ "label": "Footprint",
+ "name": "Footprint",
+ "show": true
+ },
+ {
+ "group_by": false,
+ "label": "Qty",
+ "name": "${QUANTITY}",
+ "show": true
+ },
+ {
+ "group_by": true,
+ "label": "DNP",
+ "name": "${DNP}",
+ "show": true
+ }
+ ],
+ "filter_string": "",
+ "group_symbols": true,
+ "name": "Grouped By Value",
+ "sort_asc": true,
+ "sort_field": "Reference"
+ },
+ "connection_grid_size": 50.0,
+ "drawing": {
+ "dashed_lines_dash_length_ratio": 12.0,
+ "dashed_lines_gap_length_ratio": 3.0,
+ "default_line_thickness": 6.0,
+ "default_text_size": 50.0,
+ "field_names": [],
+ "intersheets_ref_own_page": false,
+ "intersheets_ref_prefix": "",
+ "intersheets_ref_short": false,
+ "intersheets_ref_show": false,
+ "intersheets_ref_suffix": "",
+ "junction_size_choice": 3,
+ "label_size_ratio": 0.375,
+ "operating_point_overlay_i_precision": 3,
+ "operating_point_overlay_i_range": "~A",
+ "operating_point_overlay_v_precision": 3,
+ "operating_point_overlay_v_range": "~V",
+ "overbar_offset_ratio": 1.23,
+ "pin_symbol_size": 25.0,
+ "text_offset_ratio": 0.15
+ },
+ "legacy_lib_dir": "",
+ "legacy_lib_list": [],
+ "meta": {
+ "version": 1
+ },
+ "net_format_name": "",
+ "page_layout_descr_file": "",
+ "plot_directory": "",
+ "spice_current_sheet_as_root": false,
+ "spice_external_command": "spice \"%I\"",
+ "spice_model_current_sheet_as_root": true,
+ "spice_save_all_currents": false,
+ "spice_save_all_dissipations": false,
+ "spice_save_all_voltages": false,
+ "subpart_first_id": 65,
+ "subpart_id_separator": 0
+ },
+ "sheets": [
+ [
+ "82dbe48b-4e91-4863-9dbe-ebee03307ff6",
+ "Root"
+ ]
+ ],
+ "text_variables": {}
+}
diff --git a/hackpads/blipyboard/pcb/hackpad copy.kicad_sch b/hackpads/blipyboard/pcb/hackpad copy.kicad_sch
new file mode 100644
index 0000000000..03e1ff75c2
--- /dev/null
+++ b/hackpads/blipyboard/pcb/hackpad copy.kicad_sch
@@ -0,0 +1,5701 @@
+(kicad_sch
+ (version 20231120)
+ (generator "eeschema")
+ (generator_version "8.0")
+ (uuid "82dbe48b-4e91-4863-9dbe-ebee03307ff6")
+ (paper "A4")
+ (lib_symbols
+ (symbol "Device:RotaryEncoder_Switch"
+ (pin_names
+ (offset 0.254) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "SW"
+ (at 0 6.604 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "RotaryEncoder_Switch"
+ (at 0 -6.604 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at -3.81 4.064 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 6.604 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Rotary encoder, dual channel, incremental quadrate outputs, with switch"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "rotary switch encoder switch push button"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "RotaryEncoder*Switch*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "RotaryEncoder_Switch_0_1"
+ (rectangle
+ (start -5.08 5.08)
+ (end 5.08 -5.08)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type background)
+ )
+ )
+ (circle
+ (center -3.81 0)
+ (radius 0.254)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type outline)
+ )
+ )
+ (circle
+ (center -0.381 0)
+ (radius 1.905)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (arc
+ (start -0.381 2.667)
+ (mid -3.0988 -0.0635)
+ (end -0.381 -2.794)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -0.635 -1.778) (xy -0.635 1.778)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -0.381 -1.778) (xy -0.381 1.778)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -0.127 1.778) (xy -0.127 -1.778)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 3.81 0) (xy 3.429 0)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 3.81 1.016) (xy 3.81 -1.016)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -5.08 -2.54) (xy -3.81 -2.54) (xy -3.81 -2.032)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -5.08 2.54) (xy -3.81 2.54) (xy -3.81 2.032)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.254 -3.048) (xy -0.508 -2.794) (xy 0.127 -2.413)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0.254 2.921) (xy -0.508 2.667) (xy 0.127 2.286)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 5.08 -2.54) (xy 4.318 -2.54) (xy 4.318 -1.016)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 5.08 2.54) (xy 4.318 2.54) (xy 4.318 1.016)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -5.08 0) (xy -3.81 0) (xy -3.81 -1.016) (xy -3.302 -2.032)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -4.318 0) (xy -3.81 0) (xy -3.81 1.016) (xy -3.302 2.032)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (circle
+ (center 4.318 -1.016)
+ (radius 0.127)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (circle
+ (center 4.318 1.016)
+ (radius 0.127)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "RotaryEncoder_Switch_1_1"
+ (pin passive line
+ (at -7.62 2.54 0)
+ (length 2.54)
+ (name "A"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "A"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -7.62 -2.54 0)
+ (length 2.54)
+ (name "B"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "B"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -7.62 0 0)
+ (length 2.54)
+ (name "C"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "C"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 7.62 2.54 180)
+ (length 2.54)
+ (name "S1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "S1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 7.62 -2.54 180)
+ (length 2.54)
+ (name "S2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "S2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "LED:SK6812MINI"
+ (pin_names
+ (offset 0.254)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "D"
+ (at 5.08 5.715 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right bottom)
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 1.27 -5.715 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 1.27 -7.62 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 2.54 -9.525 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "RGB LED NeoPixel Mini addressable"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "LED*SK6812MINI*PLCC*3.5x3.5mm*P1.75mm*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "SK6812MINI_0_0"
+ (text "RGB"
+ (at 2.286 -4.191 0)
+ (effects
+ (font
+ (size 0.762 0.762)
+ )
+ )
+ )
+ )
+ (symbol "SK6812MINI_0_1"
+ (polyline
+ (pts
+ (xy 1.27 -3.556) (xy 1.778 -3.556)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 1.27 -2.54) (xy 1.778 -2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 4.699 -3.556) (xy 2.667 -3.556)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 2.286 -2.54) (xy 1.27 -3.556) (xy 1.27 -3.048)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 2.286 -1.524) (xy 1.27 -2.54) (xy 1.27 -2.032)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 3.683 -1.016) (xy 3.683 -3.556) (xy 3.683 -4.064)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 4.699 -1.524) (xy 2.667 -1.524) (xy 3.683 -3.556) (xy 4.699 -1.524)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (rectangle
+ (start 5.08 5.08)
+ (end -5.08 -5.08)
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type background)
+ )
+ )
+ )
+ (symbol "SK6812MINI_1_1"
+ (pin output line
+ (at 7.62 0 180)
+ (length 2.54)
+ (name "DOUT"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at 0 -7.62 90)
+ (length 2.54)
+ (name "VSS"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input line
+ (at -7.62 0 0)
+ (length 2.54)
+ (name "DIN"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at 0 7.62 270)
+ (length 2.54)
+ (name "VDD"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "ScottoKeebs:OLED_128x32"
+ (pin_names
+ (offset 1.016)
+ )
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "J"
+ (at 0 -6.35 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "OLED_128x32"
+ (at 0 6.35 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "ScottoKeebs_Components:OLED_128x32"
+ (at 0 8.89 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 1.27 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "OLED_128x32_0_1"
+ (rectangle
+ (start 0 5.08)
+ (end 15.24 -5.08)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type background)
+ )
+ )
+ )
+ (symbol "OLED_128x32_1_1"
+ (pin power_in line
+ (at -2.54 -3.81 0)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin power_in line
+ (at -2.54 -1.27 0)
+ (length 2.54)
+ (name "VCC"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin input clock
+ (at -2.54 1.27 0)
+ (length 2.54)
+ (name "SCL"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin bidirectional line
+ (at -2.54 3.81 0)
+ (length 2.54)
+ (name "SDA"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "ScottoKeebs:Placeholder_Diode"
+ (pin_numbers hide)
+ (pin_names hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "D"
+ (at 0 2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "Diode"
+ (at 0 -2.54 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "diode"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_fp_filters" "D*DO?35*"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "Placeholder_Diode_0_1"
+ (polyline
+ (pts
+ (xy -1.27 1.27) (xy -1.27 -1.27)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 1.27 0) (xy -1.27 0)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 1.27 1.27) (xy 1.27 -1.27) (xy -1.27 0) (xy 1.27 1.27)
+ )
+ (stroke
+ (width 0.254)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "Placeholder_Diode_1_1"
+ (pin passive line
+ (at -3.81 0 0)
+ (length 2.54)
+ (name "K"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 3.81 0 180)
+ (length 2.54)
+ (name "A"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Seeed_Studio_XIAO_Series:XIAO-RP2040-DIP"
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "U"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "XIAO-RP2040-DIP"
+ (at 5.334 -1.778 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Module:MOUDLE14P-XIAO-DIP-SMD"
+ (at 14.478 -32.258 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "XIAO-RP2040-DIP_1_0"
+ (polyline
+ (pts
+ (xy -1.27 -30.48) (xy -1.27 -16.51)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -27.94) (xy -2.54 -27.94)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -24.13) (xy -2.54 -24.13)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -20.32) (xy -2.54 -20.32)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -16.51) (xy -2.54 -16.51)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -16.51) (xy -1.27 -12.7)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -12.7) (xy -2.54 -12.7)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -12.7) (xy -1.27 -8.89)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -8.89) (xy -2.54 -8.89)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -8.89) (xy -1.27 -5.08)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -5.08) (xy -2.54 -5.08)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -5.08) (xy -1.27 -2.54)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -1.27 -2.54) (xy 29.21 -2.54)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 29.21 -30.48) (xy -1.27 -30.48)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 29.21 -12.7) (xy 29.21 -30.48)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 29.21 -8.89) (xy 29.21 -12.7)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 29.21 -5.08) (xy 29.21 -8.89)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 29.21 -2.54) (xy 29.21 -5.08)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 30.48 -27.94) (xy 29.21 -27.94)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 30.48 -24.13) (xy 29.21 -24.13)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 30.48 -20.32) (xy 29.21 -20.32)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 30.48 -16.51) (xy 29.21 -16.51)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 30.48 -12.7) (xy 29.21 -12.7)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 30.48 -8.89) (xy 29.21 -8.89)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 30.48 -5.08) (xy 29.21 -5.08)
+ )
+ (stroke
+ (width 0.1524)
+ (type solid)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (pin passive line
+ (at -3.81 -5.08 0)
+ (length 2.54)
+ (name "GPIO26/ADC0/A0"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 31.75 -20.32 180)
+ (length 2.54)
+ (name "GPIO4/MISO"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "10"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 31.75 -16.51 180)
+ (length 2.54)
+ (name "GPIO3/MOSI"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "11"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 31.75 -12.7 180)
+ (length 2.54)
+ (name "3V3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "12"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 31.75 -8.89 180)
+ (length 2.54)
+ (name "GND"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "13"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 31.75 -5.08 180)
+ (length 2.54)
+ (name "VBUS"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "14"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -3.81 -8.89 0)
+ (length 2.54)
+ (name "GPIO27/ADC1/A1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -3.81 -12.7 0)
+ (length 2.54)
+ (name "GPIO28/ADC2/A2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -3.81 -16.51 0)
+ (length 2.54)
+ (name "GPIO29/ADC3/A3"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "4"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -3.81 -20.32 0)
+ (length 2.54)
+ (name "GPIO6/SDA"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "5"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -3.81 -24.13 0)
+ (length 2.54)
+ (name "GPIO7/SCL"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "6"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at -3.81 -27.94 0)
+ (length 2.54)
+ (name "GPIO0/TX"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "7"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 31.75 -27.94 180)
+ (length 2.54)
+ (name "GPIO1/RX"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "8"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 31.75 -24.13 180)
+ (length 2.54)
+ (name "GPIO2/SCK"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "9"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "Switch:SW_Push_45deg"
+ (pin_numbers hide)
+ (pin_names
+ (offset 1.016) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "SW"
+ (at 3.048 1.016 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 0 -3.81 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "switch normally-open pushbutton push-button"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "SW_Push_45deg_0_1"
+ (circle
+ (center -1.1684 1.1684)
+ (radius 0.508)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -0.508 2.54) (xy 2.54 -0.508)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 1.016 1.016) (xy 2.032 2.032)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy -2.54 2.54) (xy -1.524 1.524) (xy -1.524 1.524)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 1.524 -1.524) (xy 2.54 -2.54) (xy 2.54 -2.54) (xy 2.54 -2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (circle
+ (center 1.143 -1.1938)
+ (radius 0.508)
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (pin passive line
+ (at -2.54 2.54 0)
+ (length 0)
+ (name "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ (pin passive line
+ (at 2.54 -2.54 180)
+ (length 0)
+ (name "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "2"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "power:+5V"
+ (power)
+ (pin_numbers hide)
+ (pin_names
+ (offset 0) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "#PWR"
+ (at 0 -3.81 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "+5V"
+ (at 0 3.556 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"+5V\""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "global power"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "+5V_0_1"
+ (polyline
+ (pts
+ (xy -0.762 1.27) (xy 0 2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0 0) (xy 0 2.54)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ (polyline
+ (pts
+ (xy 0 2.54) (xy 0.762 1.27)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "+5V_1_1"
+ (pin power_in line
+ (at 0 0 90)
+ (length 0)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ (symbol "power:GND"
+ (power)
+ (pin_numbers hide)
+ (pin_names
+ (offset 0) hide)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (property "Reference" "#PWR"
+ (at 0 -6.35 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "GND"
+ (at 0 -3.81 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"GND\" , ground"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "ki_keywords" "global power"
+ (at 0 0 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (symbol "GND_0_1"
+ (polyline
+ (pts
+ (xy 0 0) (xy 0 -1.27) (xy 1.27 -1.27) (xy 0 -2.54) (xy -1.27 -1.27) (xy 0 -1.27)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (fill
+ (type none)
+ )
+ )
+ )
+ (symbol "GND_1_1"
+ (pin power_in line
+ (at 0 0 270)
+ (length 0)
+ (name "~"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (number "1"
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (junction
+ (at 76.2 86.36)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "0cf2e436-2fa9-4223-bbd2-1ae3cd60cd39")
+ )
+ (junction
+ (at 119.38 124.46)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "0e886d46-1d97-405a-a959-21245a2a875a")
+ )
+ (junction
+ (at 119.38 139.7)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "0f2728f2-e840-4ffb-a70d-ea9ac2192e05")
+ )
+ (junction
+ (at 140.97 124.46)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "13a831b7-9a06-4cef-8548-58a70b2a4ac6")
+ )
+ (junction
+ (at 95.25 86.36)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "20991fd9-18e1-499b-8b43-71c4dec1dcbf")
+ )
+ (junction
+ (at 105.41 139.7)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "32faf1df-b449-4301-8068-547e6795d0df")
+ )
+ (junction
+ (at 59.69 63.5)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "5113df16-b250-4666-a00f-2e83e32d472e")
+ )
+ (junction
+ (at 62.23 124.46)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "6a8bae1c-5a2c-4947-a156-360f82a14764")
+ )
+ (junction
+ (at 48.26 124.46)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "90260c0b-0833-4e1a-85fa-09ff17e16460")
+ )
+ (junction
+ (at 95.25 63.5)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "9eb9e812-5067-40ce-9a5d-51e851f09e7a")
+ )
+ (junction
+ (at 36.83 50.8)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "a002188c-67d5-4348-ab72-ab1912aab8a0")
+ )
+ (junction
+ (at 83.82 124.46)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "a155e91a-24bf-4770-a08f-b66103444538")
+ )
+ (junction
+ (at 113.03 63.5)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "a2b994c6-1533-43f6-b91d-759be4ccec78")
+ )
+ (junction
+ (at 105.41 124.46)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "b0ce829c-a210-4139-8679-c50929a674cf")
+ )
+ (junction
+ (at 62.23 139.7)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "c76e513b-aee2-4357-ba8c-c48c82f5a0d7")
+ )
+ (junction
+ (at 162.56 124.46)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "cb64f199-d190-41c3-8dba-1f908041e74b")
+ )
+ (junction
+ (at 48.26 139.7)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "d01fe8b8-e1ce-4361-b734-799eea3b1786")
+ )
+ (junction
+ (at 76.2 63.5)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "d181ec1e-1d0b-4d0c-b416-d33e5b141800")
+ )
+ (junction
+ (at 162.56 139.7)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "e530f95a-1776-421e-947c-93942217e4a5")
+ )
+ (junction
+ (at 59.69 86.36)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "f1ebe3b6-e91b-4215-858c-e916ae3653f3")
+ )
+ (junction
+ (at 83.82 139.7)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "f674dcfd-1c3a-45b3-8260-e600e7aaf5b9")
+ )
+ (junction
+ (at 140.97 139.7)
+ (diameter 0)
+ (color 0 0 0 0)
+ (uuid "f790c8d5-5d8b-404b-80fb-67fe0c929ca0")
+ )
+ (wire
+ (pts
+ (xy 83.82 124.46) (xy 105.41 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "02c2369d-defd-4f12-876d-66713473762a")
+ )
+ (wire
+ (pts
+ (xy 59.69 86.36) (xy 76.2 86.36)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "10a142a5-e22e-4f4e-bc10-0ed75d75cd9b")
+ )
+ (wire
+ (pts
+ (xy 83.82 139.7) (xy 105.41 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "188128bb-3969-4713-9fce-3b1c38cab6d1")
+ )
+ (wire
+ (pts
+ (xy 90.17 50.8) (xy 90.17 73.66)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "19c5f215-d232-4e74-b702-5e574fa8bf7e")
+ )
+ (wire
+ (pts
+ (xy 121.92 86.36) (xy 95.25 86.36)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1a9a592b-eef0-4410-acff-e731eafa24c7")
+ )
+ (wire
+ (pts
+ (xy 119.38 139.7) (xy 140.97 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "1d4d4b2e-643b-4c92-9f4b-11dcd1d7b16d")
+ )
+ (wire
+ (pts
+ (xy 62.23 124.46) (xy 83.82 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "23514951-b14d-4b9e-bd6a-e14422ac17a4")
+ )
+ (wire
+ (pts
+ (xy 177.8 59.69) (xy 173.99 59.69)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "23e16aad-b07c-4344-8e35-f4f74c9ce533")
+ )
+ (wire
+ (pts
+ (xy 140.97 124.46) (xy 162.56 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "2a8261a8-85af-40f8-a305-f6c13b7f3ce6")
+ )
+ (wire
+ (pts
+ (xy 48.26 124.46) (xy 62.23 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3820dfbf-81a3-4b77-b11d-9cc5ba36988f")
+ )
+ (wire
+ (pts
+ (xy 91.44 132.08) (xy 97.79 132.08)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "384e4eae-ae8c-4b64-9291-6e3975e1af60")
+ )
+ (wire
+ (pts
+ (xy 162.56 139.7) (xy 187.96 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3876dc86-7c0b-46bb-bba8-cf05f2889548")
+ )
+ (wire
+ (pts
+ (xy 48.26 139.7) (xy 62.23 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "3b995569-86e8-42f9-a7a3-ccea37d1986e")
+ )
+ (wire
+ (pts
+ (xy 162.56 124.46) (xy 187.96 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "4ae477f0-3fff-406a-bef6-fafb8390cab2")
+ )
+ (wire
+ (pts
+ (xy 76.2 63.5) (xy 95.25 63.5)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "4b94cfcb-d9ec-475e-877c-47205a49f6db")
+ )
+ (wire
+ (pts
+ (xy 71.12 50.8) (xy 71.12 73.66)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "50517b8d-fa19-4320-a91f-cc4531aee91b")
+ )
+ (wire
+ (pts
+ (xy 148.59 132.08) (xy 154.94 132.08)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "522bd4cb-dfc9-4126-92ad-482d762e4a1f")
+ )
+ (wire
+ (pts
+ (xy 140.97 139.7) (xy 162.56 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "5f400f14-d754-43b1-ab06-443e77c7ff4d")
+ )
+ (wire
+ (pts
+ (xy 36.83 29.21) (xy 36.83 50.8)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "613accae-a036-4f1e-b769-f61c18fae4ce")
+ )
+ (wire
+ (pts
+ (xy 105.41 139.7) (xy 119.38 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "62db0933-ae8c-45a2-b599-0dfe36cb7b46")
+ )
+ (wire
+ (pts
+ (xy 119.38 124.46) (xy 140.97 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "6552ac37-f751-4098-b231-7ce7675d78a2")
+ )
+ (wire
+ (pts
+ (xy 113.03 63.5) (xy 95.25 63.5)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "733ae8dd-cbde-4e8d-841b-90f3fce09877")
+ )
+ (wire
+ (pts
+ (xy 36.83 50.8) (xy 36.83 73.66)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "74c0f3b3-4250-4f5f-a5f8-b3a461fbadc5")
+ )
+ (wire
+ (pts
+ (xy 41.91 86.36) (xy 59.69 86.36)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "768b2b19-bf0c-4e1e-ad2e-a9375c2c0142")
+ )
+ (wire
+ (pts
+ (xy 69.85 132.08) (xy 76.2 132.08)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "7860045d-ef8a-418e-8a51-29d4b23ac3c3")
+ )
+ (wire
+ (pts
+ (xy 62.23 139.7) (xy 83.82 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "7c7499c2-9be0-444d-978f-b80d99cc8eae")
+ )
+ (wire
+ (pts
+ (xy 76.2 86.36) (xy 95.25 86.36)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "88515cc8-2ec0-42a7-a9b5-99be2de0b3da")
+ )
+ (wire
+ (pts
+ (xy 208.28 86.36) (xy 193.04 86.36)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "a270fe44-4135-44e0-a5ae-0114835530d3")
+ )
+ (wire
+ (pts
+ (xy 34.29 124.46) (xy 48.26 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "bc114d7d-17da-41b6-8b35-18d08646571d")
+ )
+ (wire
+ (pts
+ (xy 208.28 90.17) (xy 193.04 90.17)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "bd28f5a1-f555-4a0e-b2f0-8e5793b6af59")
+ )
+ (wire
+ (pts
+ (xy 127 132.08) (xy 133.35 132.08)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "cc1e71ff-7c3a-49ba-b435-0688a21e2fba")
+ )
+ (wire
+ (pts
+ (xy 105.41 124.46) (xy 119.38 124.46)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "cdda8274-cf2e-4a26-85a3-1e6aef5d8c7d")
+ )
+ (wire
+ (pts
+ (xy 130.81 55.88) (xy 139.7 55.88)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ce57a172-de20-4474-b209-fa82f2449d82")
+ )
+ (wire
+ (pts
+ (xy 59.69 63.5) (xy 76.2 63.5)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d56a50ac-eb31-4544-b1c3-b9fd251fec74")
+ )
+ (wire
+ (pts
+ (xy 54.61 50.8) (xy 54.61 73.66)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "d8d7cec3-9976-4b04-beeb-6314fd4a5bbd")
+ )
+ (wire
+ (pts
+ (xy 173.99 59.69) (xy 173.99 60.96)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e48fb94e-7acf-4c8f-adcd-05d4cbb83bc1")
+ )
+ (wire
+ (pts
+ (xy 34.29 139.7) (xy 48.26 139.7)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e56d2116-7a31-42ec-944c-cfd4b2af87f7")
+ )
+ (wire
+ (pts
+ (xy 121.92 63.5) (xy 113.03 63.5)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "e58d005e-d60d-488b-aaa6-bc4ffd30bc64")
+ )
+ (wire
+ (pts
+ (xy 170.18 132.08) (xy 180.34 132.08)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "ed52cdfa-0b97-4b75-9fda-c7e212c8354c")
+ )
+ (wire
+ (pts
+ (xy 41.91 63.5) (xy 59.69 63.5)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "f12b974e-9e14-4ef2-9287-335ba808e98c")
+ )
+ (wire
+ (pts
+ (xy 41.91 132.08) (xy 54.61 132.08)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "f7213325-1e06-4dd7-a245-4e7713c01be6")
+ )
+ (wire
+ (pts
+ (xy 111.76 132.08) (xy 113.03 132.08)
+ )
+ (stroke
+ (width 0)
+ (type default)
+ )
+ (uuid "fee86481-0f02-4b7e-b77b-e7dff85c0c7d")
+ )
+ (global_label "NEOPIXEL"
+ (shape input)
+ (at 26.67 132.08 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "2d95a03a-4ae6-46bd-b2a4-ae1114249901")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 14.6134 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col1"
+ (shape input)
+ (at 36.83 29.21 90)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "2ef80886-9415-4443-9102-3451094520b3")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 36.83 22.1125 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "SDA"
+ (shape input)
+ (at 157.48 101.6 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "357ef89a-73c0-4188-b62c-3d28babbbe60")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 150.9267 101.6 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col2"
+ (shape input)
+ (at 54.61 50.8 90)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "3700ad9a-598b-4f22-89d6-e73284c37179")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 54.61 43.7025 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col2"
+ (shape input)
+ (at 157.48 93.98 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "414cf9f3-a16e-438d-9c57-cf45094051b7")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 150.3825 93.98 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "SCL"
+ (shape input)
+ (at 157.48 105.41 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "4e07f16f-8b31-49cf-b726-786031b2761b")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 150.9872 105.41 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col3"
+ (shape input)
+ (at 71.12 50.8 90)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "5805439f-e39b-4e01-b0b7-4463702469da")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 71.12 43.7025 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "ROUTPUT"
+ (shape input)
+ (at 113.03 55.88 90)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "5cad1b85-3056-4b7d-8d64-98354f728289")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 113.03 44.4281 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "row1"
+ (shape input)
+ (at 193.04 101.6 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "5f5fe941-cda2-4c81-8e23-75e7e526c3fa")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 200.5004 101.6 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "row2"
+ (shape input)
+ (at 121.92 86.36 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "6829e5a9-d65a-41fa-b866-76abd45e4a77")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 129.3804 86.36 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "NEOPIXEL"
+ (shape input)
+ (at 193.04 97.79 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "7d18881c-717d-4628-9ba3-2fb61f2ac9b9")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 205.0966 97.79 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "EC11B"
+ (shape input)
+ (at 139.7 53.34 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "8164b014-f8c0-47a2-af8e-4b4d18598d52")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 130.6068 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "EC11A"
+ (shape input)
+ (at 193.04 105.41 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "8feb5882-88a3-4423-88fd-1692601e62cf")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 201.9518 105.41 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col3"
+ (shape input)
+ (at 157.48 90.17 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "98b50935-5978-4590-b7ed-d1f7c004c2b2")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 150.3825 90.17 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "EC11A"
+ (shape input)
+ (at 139.7 58.42 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "a45ac9fc-72aa-449f-a5cd-51d11b56eaab")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 130.7882 58.42 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col4"
+ (shape input)
+ (at 157.48 86.36 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "ab9d5c1f-f812-42c7-89ad-755ea9c130db")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 150.3825 86.36 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "EC11B"
+ (shape input)
+ (at 193.04 109.22 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "ada89d72-47b8-41a0-9b81-f0987114be68")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 202.1332 109.22 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col4"
+ (shape input)
+ (at 90.17 50.8 90)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "ade4fd79-3b85-4dab-b528-763635f3cd8e")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 90.17 43.7025 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "3V3"
+ (shape input)
+ (at 177.8 57.15 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "ae4a16a3-a644-458f-b2ae-449bf0468da9")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 171.3072 57.15 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "col1"
+ (shape input)
+ (at 157.48 97.79 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "af8535b7-763b-48ad-98a1-ef626a8a2490")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 150.3825 97.79 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "row1"
+ (shape input)
+ (at 121.92 63.5 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "b06231a6-c386-4ddc-96aa-658fa994b64b")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 129.3804 63.5 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "row2"
+ (shape input)
+ (at 157.48 109.22 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "b257c538-af7c-4de7-83ca-301e7be70d19")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 150.0196 109.22 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "SCL"
+ (shape input)
+ (at 177.8 54.61 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "c7f4f4c5-7ed3-4682-890d-23e0ecd4a4d6")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 171.3072 54.61 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "RINPUT"
+ (shape input)
+ (at 36.83 36.83 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "ca306316-e19a-4578-9599-631a2b9cc911")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 27.0714 36.83 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "3V3"
+ (shape input)
+ (at 193.04 93.98 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "d76d643a-1d7a-4fbc-a381-12a7604f809d")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 199.5328 93.98 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "RINPUT"
+ (shape input)
+ (at 154.94 53.34 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "d7b348a6-fdd7-4cc4-b9bf-c92e3f0eedee")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 164.6986 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "ROUTPUT"
+ (shape input)
+ (at 154.94 58.42 0)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ (uuid "d97a99b2-1652-4e60-99f9-54458a796b04")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 166.3919 58.42 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ (hide yes)
+ )
+ )
+ )
+ (global_label "SDA"
+ (shape input)
+ (at 177.8 52.07 180)
+ (fields_autoplaced yes)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ (uuid "e2c04a09-e39b-4744-8e8b-63df532dcbe5")
+ (property "Intersheetrefs" "${INTERSHEET_REFS}"
+ (at 171.2467 52.07 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ (hide yes)
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 41.91 82.55 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "0182b48c-fe8b-47ef-8be4-7fa0b56081bd")
+ (property "Reference" "D3"
+ (at 44.45 81.2799 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 44.45 83.8199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 41.91 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 41.91 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 41.91 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 41.91 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 41.91 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "ec7ea631-6828-4bc6-bb1a-43120b34e603")
+ )
+ (pin "1"
+ (uuid "078994c5-f3df-4a7b-a998-d8765640c52a")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D3")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Device:RotaryEncoder_Switch")
+ (at 147.32 55.88 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "1f3b652e-8c8b-49f0-b2ef-8372bc3bab18")
+ (property "Reference" "SW9"
+ (at 147.32 45.72 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "RotaryEncoder_Switch"
+ (at 147.32 48.26 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Rotary_Encoder:RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm"
+ (at 143.51 51.816 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 147.32 49.276 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Rotary encoder, dual channel, incremental quadrate outputs, with switch"
+ (at 147.32 55.88 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "A"
+ (uuid "bb135034-1708-4b5a-ae03-582031b3b35b")
+ )
+ (pin "B"
+ (uuid "91e5a1b6-1640-407d-8077-2f9eb86c9af8")
+ )
+ (pin "S2"
+ (uuid "2e210253-a2b6-486f-82aa-d772d685bfbb")
+ )
+ (pin "S1"
+ (uuid "07e37b84-a6b0-408b-b2ad-e4d870ad31eb")
+ )
+ (pin "C"
+ (uuid "8bb539ed-2faf-4471-9f4a-709cdf917a46")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW9")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "power:+5V")
+ (at 208.28 86.36 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "235c46b6-f99b-460e-8859-bc8b006f0aa1")
+ (property "Reference" "#PWR03"
+ (at 208.28 90.17 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "+5V"
+ (at 208.28 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 208.28 86.36 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 208.28 86.36 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"+5V\""
+ (at 208.28 86.36 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "717881cd-cf03-4f53-babe-45161384a137")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "#PWR03")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "power:GND")
+ (at 48.26 139.7 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "25643743-ccf2-4fca-a91e-c886fdc0568e")
+ (property "Reference" "#PWR01"
+ (at 48.26 146.05 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "GND"
+ (at 48.26 144.78 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 48.26 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 48.26 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"GND\" , ground"
+ (at 48.26 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "886fbfca-6c00-4466-a6e8-9bfb10098f22")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "#PWR01")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 39.37 76.2 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "261f75ab-c061-46a1-9759-af1f257be337")
+ (property "Reference" "SW1"
+ (at 39.37 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 39.37 71.12 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 39.37 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 39.37 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 39.37 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "029d8268-75a7-429b-bce3-3f678009c3c5")
+ )
+ (pin "2"
+ (uuid "da6964a6-9dc2-4729-97a6-55f234bc7043")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Seeed_Studio_XIAO_Series:XIAO-RP2040-DIP")
+ (at 161.29 81.28 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "35a068e0-5f88-40dc-ba2a-cf656c23bdce")
+ (property "Reference" "U1"
+ (at 175.26 78.74 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "XIAO-RP2040-DIP"
+ (at 175.26 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Seeed Studio XIAO Series Library:XIAO-RP2040-DIP"
+ (at 175.768 113.538 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 161.29 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 161.29 81.28 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "6"
+ (uuid "600ec4d4-48ec-40a0-8d89-97dacd8e17be")
+ )
+ (pin "9"
+ (uuid "d5275c79-cd14-453c-80d1-8861b6470357")
+ )
+ (pin "13"
+ (uuid "aeff5494-b2d7-4717-b72e-b0b646607378")
+ )
+ (pin "11"
+ (uuid "7773e803-1a5d-4a2d-a68f-5729d0b5dc42")
+ )
+ (pin "8"
+ (uuid "9b4b334e-db81-4dcf-88da-54d71ccf8fb1")
+ )
+ (pin "2"
+ (uuid "5cd6ba0f-7247-4182-a962-74b5d236ef30")
+ )
+ (pin "14"
+ (uuid "0b2effcf-8e65-4170-a936-73c77e324386")
+ )
+ (pin "12"
+ (uuid "570c028a-43e2-47b0-90f2-d970eaafa31f")
+ )
+ (pin "10"
+ (uuid "4bb715f1-9888-4ca3-886e-13cd0bdb0982")
+ )
+ (pin "3"
+ (uuid "cbbd32b5-1f20-4e03-b7be-07b7995d87c1")
+ )
+ (pin "5"
+ (uuid "dc45325c-91ab-45ee-9bc7-700329898620")
+ )
+ (pin "1"
+ (uuid "2e28ed87-1d2c-4dbf-9e96-4e8d26301c8b")
+ )
+ (pin "4"
+ (uuid "eebfee26-1065-4ece-81ed-8739d81f879e")
+ )
+ (pin "7"
+ (uuid "3a8a98f7-73f4-4371-b8be-326b0ee85834")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "U1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 95.25 59.69 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "492b14a3-196e-491e-8781-0d6aedc31079")
+ (property "Reference" "D9"
+ (at 97.79 58.4199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 97.79 60.9599 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 95.25 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 95.25 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 95.25 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 95.25 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 95.25 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "536a53a0-419b-4dd0-9e5c-34bff06a6459")
+ )
+ (pin "1"
+ (uuid "50a186ad-5ce7-43b7-b2f2-e0f90065e9ac")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D9")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 62.23 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "496010bf-b03a-4ebc-b0fa-a1866f535ae8")
+ (property "Reference" "D2"
+ (at 74.93 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 74.93 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 63.5 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 64.77 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 62.23 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "33d4b93b-e45d-4f4a-a421-51018b509e83")
+ )
+ (pin "2"
+ (uuid "dd5a5e09-f3c7-4bf3-9de0-50c5d8a3e9bb")
+ )
+ (pin "1"
+ (uuid "abca9311-b368-4f1f-9337-61507e0e1c10")
+ )
+ (pin "3"
+ (uuid "99702eab-e447-4567-b771-65c8a4fa4931")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 92.71 53.34 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "4e64b0d4-0bf5-4a85-844f-860d31b1043a")
+ (property "Reference" "SW7"
+ (at 92.71 45.72 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 92.71 48.26 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 92.71 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 92.71 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 92.71 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "96f44453-99fc-4315-9f57-f865ea77698c")
+ )
+ (pin "2"
+ (uuid "8509b7ef-9d14-4c86-b31d-efcbb5d5870a")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW7")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 59.69 82.55 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "4e988283-ea88-4926-a401-acf7a0415ab1")
+ (property "Reference" "D4"
+ (at 62.23 81.2799 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 62.23 83.8199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 59.69 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 59.69 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 59.69 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 59.69 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 59.69 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "ae5ac38f-3bf5-4135-b5fc-016c67ebb31c")
+ )
+ (pin "1"
+ (uuid "7041285c-b187-445f-95b5-f517dc77ed90")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D4")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "power:GND")
+ (at 173.99 60.96 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "5209f54d-9721-4bfb-a47f-b798e7a18665")
+ (property "Reference" "#PWR05"
+ (at 173.99 67.31 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "GND"
+ (at 173.99 66.04 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 173.99 60.96 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 173.99 60.96 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"GND\" , ground"
+ (at 173.99 60.96 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "4d224cfa-6966-4873-aeb2-80ffdb6d1eaa")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "#PWR05")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 76.2 59.69 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "554ad5aa-fcfb-4528-b5bb-4feac667d765")
+ (property "Reference" "D8"
+ (at 78.74 58.4199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 78.74 60.9599 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 76.2 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 76.2 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 76.2 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 76.2 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 76.2 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "f3759646-4595-42ab-bd5a-d320a927fbf0")
+ )
+ (pin "1"
+ (uuid "7f631640-3fdf-43cc-8630-d827d5825048")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D8")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:OLED_128x32")
+ (at 180.34 55.88 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "55d70023-2f4f-4dd3-9cd5-34beea9f5bfe")
+ (property "Reference" "J2"
+ (at 196.85 54.6099 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Value" "OLED_128x32"
+ (at 196.85 57.1499 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left)
+ )
+ )
+ (property "Footprint" "ScottoKeebs_Components:OLED_128x32"
+ (at 180.34 46.99 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 180.34 54.61 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" ""
+ (at 180.34 55.88 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "f4004f06-9b6b-4447-88d7-cf13fa042ca8")
+ )
+ (pin "2"
+ (uuid "5c5f5777-720a-491a-9bfe-460a4a75dfee")
+ )
+ (pin "3"
+ (uuid "31dd2584-3b1e-45b3-b961-4fb0ef0fe367")
+ )
+ (pin "1"
+ (uuid "159ab1e0-1d62-4995-8c18-163c1cc9aeda")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "J2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "power:GND")
+ (at 130.81 55.88 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "5b6b466a-2f58-4300-82dc-174ed61dc905")
+ (property "Reference" "#PWR06"
+ (at 130.81 62.23 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "GND"
+ (at 130.81 60.96 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 130.81 55.88 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 130.81 55.88 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"GND\" , ground"
+ (at 130.81 55.88 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "90f06f00-f3e9-4333-a830-11697551cf33")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "#PWR06")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 39.37 53.34 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "5f4c010a-8b72-4d09-b514-c1bed217a028")
+ (property "Reference" "SW4"
+ (at 39.37 45.72 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 39.37 48.26 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 39.37 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 39.37 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 39.37 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "63ed5a01-fa0d-469a-8e5d-49cc92475c94")
+ )
+ (pin "2"
+ (uuid "6419f91c-d9a1-4449-8103-da6c10e3fcab")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW4")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 73.66 53.34 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "758505f7-d3d8-4901-9513-5d620fdca2ab")
+ (property "Reference" "SW6"
+ (at 73.66 45.72 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 73.66 48.26 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 73.66 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 73.66 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 73.66 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "359eb099-012e-49f9-b6e3-04493d714e8e")
+ )
+ (pin "2"
+ (uuid "db6f8717-de98-4c56-a5e8-0f2a1ba9192c")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW6")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "power:+5V")
+ (at 48.26 124.46 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "78862f0f-a4af-4590-b768-978b3a019aa8")
+ (property "Reference" "#PWR04"
+ (at 48.26 128.27 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "+5V"
+ (at 48.26 119.38 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 48.26 124.46 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 48.26 124.46 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"+5V\""
+ (at 48.26 124.46 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "d7ffad31-fc3b-49cc-b82a-d875d2121b35")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "#PWR04")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 76.2 82.55 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "8f9dee36-bcf8-4199-b179-81a96b947127")
+ (property "Reference" "D5"
+ (at 78.74 81.2799 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 78.74 83.8199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 76.2 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 76.2 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 76.2 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 76.2 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 76.2 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "6261f445-84e8-40ba-9f30-36e9e0a1bd92")
+ )
+ (pin "1"
+ (uuid "83c89c5b-0061-414e-8d3f-a59bd51d83ec")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D5")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 83.82 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "92960efb-0266-4005-bd5f-7ae1803b9af7")
+ (property "Reference" "D11"
+ (at 96.52 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 96.52 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 85.09 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 86.36 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 83.82 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "7c2eee88-d293-4f89-ac47-dca1f4f40188")
+ )
+ (pin "2"
+ (uuid "c89d942a-592a-4e28-8c1e-ca42ce61a7f1")
+ )
+ (pin "1"
+ (uuid "14a69ada-265b-43a6-9584-a2828f09ca3d")
+ )
+ (pin "3"
+ (uuid "ee7e79a3-bbfc-4a5c-8921-c01e8646380d")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D11")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "power:GND")
+ (at 208.28 90.17 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "9a0d354a-e5c0-4b21-9d96-afc39358fd06")
+ (property "Reference" "#PWR02"
+ (at 208.28 96.52 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Value" "GND"
+ (at 208.28 95.25 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" ""
+ (at 208.28 90.17 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 208.28 90.17 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Power symbol creates a global label with name \"GND\" , ground"
+ (at 208.28 90.17 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "49caf229-e323-40c6-864c-86ef49ffc54c")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "#PWR02")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 41.91 59.69 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "9beb8400-f418-49d3-8d9b-ca8a6e3d55a9")
+ (property "Reference" "D6"
+ (at 44.45 58.4199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 44.45 60.9599 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 41.91 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 41.91 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 41.91 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 41.91 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 41.91 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "08ffb663-9cb3-4659-a101-c2bca3609b21")
+ )
+ (pin "1"
+ (uuid "9d2c93ba-dce1-4cd1-87af-52b92bde6e94")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D6")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 95.25 82.55 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "ac02af9b-38a1-4956-b4e5-3c84756921e8")
+ (property "Reference" "D10"
+ (at 97.79 81.2799 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 97.79 83.8199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 95.25 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 95.25 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 95.25 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 95.25 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 95.25 82.55 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "89ec82c5-4ae2-4fff-a2bc-eb11ea49b69d")
+ )
+ (pin "1"
+ (uuid "0114a1e9-c41d-49d0-acb2-94de1f579b2e")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D10")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 57.15 76.2 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "c222d41d-1ea9-43a3-bed7-12de2759d5b3")
+ (property "Reference" "SW2"
+ (at 57.15 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 57.15 71.12 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 57.15 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 57.15 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 57.15 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "8adf2917-1174-4c94-b6df-3408ad595f6b")
+ )
+ (pin "2"
+ (uuid "df61288c-8ada-4d71-8aa1-52720cdb7587")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW2")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 73.66 76.2 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "c5f1d131-52fa-4aab-92d1-4f7d6a77768d")
+ (property "Reference" "SW3"
+ (at 73.66 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 73.66 71.12 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 73.66 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 73.66 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 73.66 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "a0cb71c7-7695-4706-b26e-c21000612fb7")
+ )
+ (pin "2"
+ (uuid "1d80deea-3a9a-4f77-991a-9b73535cd3d5")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW3")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 113.03 59.69 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "d2757a62-5fd6-436f-a272-edfa97e09620")
+ (property "Reference" "D12"
+ (at 115.57 58.4199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 115.57 60.9599 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 113.03 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 113.03 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 113.03 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 113.03 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 113.03 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "a84560c4-dd0c-44c9-8d1f-bee53053cad5")
+ )
+ (pin "1"
+ (uuid "45dea4ca-feee-426d-9987-e85d22e4619a")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D12")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 119.38 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "d4dad580-cf91-4aa0-9cca-6e9db2b71eab")
+ (property "Reference" "D14"
+ (at 132.08 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 132.08 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 120.65 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 121.92 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 119.38 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "7ae415d3-ac80-4896-9acd-f81c092c04ee")
+ )
+ (pin "2"
+ (uuid "1df5575b-6a89-4e36-a5e2-277b33c7580f")
+ )
+ (pin "1"
+ (uuid "4b0d04d7-b301-4570-b2a5-109e3f253602")
+ )
+ (pin "3"
+ (uuid "c25ec39d-6b2e-4a9a-913f-e01dba1b20e6")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D14")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 34.29 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "d54e5a7f-7f39-41b2-a0c7-e86fcb28a10b")
+ (property "Reference" "D1"
+ (at 46.99 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 46.99 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 35.56 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 36.83 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 34.29 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "e19bfe51-c0d9-4916-a190-178aa01149f1")
+ )
+ (pin "2"
+ (uuid "4d86aeb0-6472-4f37-bef5-fe216d12ea98")
+ )
+ (pin "1"
+ (uuid "d0ec2561-074f-43ef-92bd-540907c717f0")
+ )
+ (pin "3"
+ (uuid "7334b7cf-63ae-40f9-b4b6-a239fe865fa3")
+ )
+ (instances
+ (project ""
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D1")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 105.41 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "d7e2a864-424f-46fb-b7ff-7fca8ee5a421")
+ (property "Reference" "D13"
+ (at 118.11 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 118.11 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 106.68 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 107.95 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 105.41 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "28253de3-e25a-41d5-a26b-27af368503a1")
+ )
+ (pin "2"
+ (uuid "42c226c8-c0d6-44c2-aed9-d3009b7c9781")
+ )
+ (pin "1"
+ (uuid "76db3edc-04c2-4276-a56d-fc57e8c34308")
+ )
+ (pin "3"
+ (uuid "e9daa752-31b1-47a5-ac6b-9a9e8b3ae87d")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D13")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 140.97 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "ee596f9f-bf74-4da1-9666-bf7b9b49cced")
+ (property "Reference" "D15"
+ (at 153.67 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 153.67 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 142.24 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 143.51 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 140.97 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "13f5cc77-b3d7-443f-8886-586430e85dae")
+ )
+ (pin "2"
+ (uuid "a462710c-a20f-4370-b3bc-311c00965e8a")
+ )
+ (pin "1"
+ (uuid "e2dbcd32-0e33-48d8-8a56-5d62978aea9b")
+ )
+ (pin "3"
+ (uuid "3131e3d3-be6d-4343-bf35-0b3d14076e73")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D15")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 57.15 53.34 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "f09b3314-d915-403a-ab16-16fc4614b166")
+ (property "Reference" "SW5"
+ (at 57.15 45.72 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 57.15 48.26 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 57.15 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 57.15 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 57.15 53.34 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "705552f4-523c-4e62-99ff-2933136add2c")
+ )
+ (pin "2"
+ (uuid "a055072b-bba1-4c80-bc67-f4d39d9192c3")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW5")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 187.96 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "f4b5d257-d254-4ca9-8510-b7d538e00f6e")
+ (property "Reference" "D17"
+ (at 200.66 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 200.66 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 189.23 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 190.5 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 187.96 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "da6d0b60-b167-45a0-8637-95d8dc932f60")
+ )
+ (pin "2"
+ (uuid "e73f55a1-b793-41d0-83cb-9dcccab3a3ed")
+ )
+ (pin "1"
+ (uuid "1375a941-adf4-403b-b475-fe68679753f1")
+ )
+ (pin "3"
+ (uuid "ff6baded-b9f9-4827-a347-88a88cc080fd")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D17")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "LED:SK6812MINI")
+ (at 162.56 132.08 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "f5eb316a-048e-4ccd-b0dd-9ce11e5a2036")
+ (property "Reference" "D16"
+ (at 175.26 125.7614 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SK6812MINI"
+ (at 175.26 128.3014 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "LED_SMD:LED_SK6812MINI_PLCC4_3.5x3.5mm_P1.75mm"
+ (at 163.83 139.7 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "https://cdn-shop.adafruit.com/product-files/2686/SK6812MINI_REV.01-1-2.pdf"
+ (at 165.1 141.605 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify left top)
+ (hide yes)
+ )
+ )
+ (property "Description" "RGB LED with integrated controller"
+ (at 162.56 132.08 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "4"
+ (uuid "d7f9074b-bddf-4db5-bb7a-ee93cc8d4d41")
+ )
+ (pin "2"
+ (uuid "c37255bb-5ba5-4daf-8551-ed0dbaf937ee")
+ )
+ (pin "1"
+ (uuid "b09b6a47-169e-46f8-aab1-9b9c929bcf1e")
+ )
+ (pin "3"
+ (uuid "1d898747-3ca0-469a-a89d-b99abc6e8f9d")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D16")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "ScottoKeebs:Placeholder_Diode")
+ (at 59.69 59.69 90)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (fields_autoplaced yes)
+ (uuid "ff19517d-941e-403e-91a1-6d1f376aed1a")
+ (property "Reference" "D7"
+ (at 62.23 58.4199 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Value" "Diode"
+ (at 62.23 60.9599 90)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (justify right)
+ )
+ )
+ (property "Footprint" "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal"
+ (at 59.69 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" ""
+ (at 59.69 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "1N4148 (DO-35) or 1N4148W (SOD-123)"
+ (at 59.69 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Device" "D"
+ (at 59.69 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Sim.Pins" "1=K 2=A"
+ (at 59.69 59.69 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "2"
+ (uuid "dfb92c3b-7dbd-40c5-aa03-07cec662b4dd")
+ )
+ (pin "1"
+ (uuid "ca35717e-105e-4c15-8cfe-15f5e171b9a5")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "D7")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (symbol
+ (lib_id "Switch:SW_Push_45deg")
+ (at 92.71 76.2 0)
+ (unit 1)
+ (exclude_from_sim no)
+ (in_bom yes)
+ (on_board yes)
+ (dnp no)
+ (uuid "ff8dd6cf-a205-43c4-8cd2-4c561b3f0627")
+ (property "Reference" "SW8"
+ (at 92.71 68.58 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Value" "SW_Push_45deg"
+ (at 92.71 71.12 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ )
+ )
+ (property "Footprint" "Button_Switch_Keyboard:SW_Cherry_MX_1.00u_PCB"
+ (at 92.71 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Datasheet" "~"
+ (at 92.71 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (property "Description" "Push button switch, normally open, two pins, 45° tilted"
+ (at 92.71 76.2 0)
+ (effects
+ (font
+ (size 1.27 1.27)
+ )
+ (hide yes)
+ )
+ )
+ (pin "1"
+ (uuid "55d6b2ae-bfd4-41c2-af21-8024e01edf7e")
+ )
+ (pin "2"
+ (uuid "b2716831-2737-4191-b1f5-bf4d000853d5")
+ )
+ (instances
+ (project "hackpad"
+ (path "/82dbe48b-4e91-4863-9dbe-ebee03307ff6"
+ (reference "SW8")
+ (unit 1)
+ )
+ )
+ )
+ )
+ (sheet_instances
+ (path "/"
+ (page "1")
+ )
+ )
+)
diff --git a/hackpads/blipyboard/pcb/hackpad.kicad_prl copy b/hackpads/blipyboard/pcb/hackpad.kicad_prl copy
new file mode 100644
index 0000000000..8387f6b1ae
--- /dev/null
+++ b/hackpads/blipyboard/pcb/hackpad.kicad_prl copy
@@ -0,0 +1,83 @@
+{
+ "board": {
+ "active_layer": 0,
+ "active_layer_preset": "All Layers",
+ "auto_track_width": true,
+ "hidden_netclasses": [],
+ "hidden_nets": [],
+ "high_contrast_mode": 0,
+ "net_color_mode": 1,
+ "opacity": {
+ "images": 0.6,
+ "pads": 1.0,
+ "tracks": 1.0,
+ "vias": 1.0,
+ "zones": 0.6
+ },
+ "selection_filter": {
+ "dimensions": true,
+ "footprints": true,
+ "graphics": true,
+ "keepouts": true,
+ "lockedItems": false,
+ "otherItems": true,
+ "pads": true,
+ "text": true,
+ "tracks": true,
+ "vias": true,
+ "zones": true
+ },
+ "visible_items": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 39,
+ 40
+ ],
+ "visible_layers": "fffffff_ffffffff",
+ "zone_display_mode": 0
+ },
+ "git": {
+ "repo_password": "",
+ "repo_type": "",
+ "repo_username": "",
+ "ssh_key": ""
+ },
+ "meta": {
+ "filename": "hackpad.kicad_prl",
+ "version": 3
+ },
+ "project": {
+ "files": []
+ }
+}
diff --git a/hackpads/blipyboard/production/bottom.stl b/hackpads/blipyboard/production/bottom.stl
new file mode 100644
index 0000000000..2d1df82a82
Binary files /dev/null and b/hackpads/blipyboard/production/bottom.stl differ
diff --git a/hackpads/blipyboard/production/hackpad.zip b/hackpads/blipyboard/production/hackpad.zip
new file mode 100644
index 0000000000..8eeedd56c0
Binary files /dev/null and b/hackpads/blipyboard/production/hackpad.zip differ
diff --git a/hackpads/blipyboard/production/plate.stl b/hackpads/blipyboard/production/plate.stl
new file mode 100644
index 0000000000..cfda1e0487
Binary files /dev/null and b/hackpads/blipyboard/production/plate.stl differ
diff --git a/hackpads/blipyboard/production/top.stl b/hackpads/blipyboard/production/top.stl
new file mode 100644
index 0000000000..3932c621a7
Binary files /dev/null and b/hackpads/blipyboard/production/top.stl differ