├── README.md ├── public ├── WebEdit.swf ├── Preloader.swf ├── images │ └── favicon.ico ├── playerProductInstall.swf ├── crossdomain.xml ├── firmware │ ├── 0B254DDAF5F73894FB0CCD89CEF1E5B1.bin │ ├── 26CA02103A321B2EAF466BEE55AAB2F5.bin │ ├── 3C905AC6744CEF39F40460693C2D2B41.bin │ ├── 3FBAB957638B57B08DB6E985BCB4A659.bin │ ├── 4674639F055F43E594ACDE7063E5F0C2.bin │ ├── 6DF3C523AE9B4E604B8B44F05C60867F.bin │ ├── 74334E7D720C67C03A9E06A87C67A1B8.bin │ ├── 87F9BFB784BDD145A6BB8CC622367D0D.bin │ ├── D402EF6E5D86AAD4DCF0DF3777F58900.bin │ ├── DAEDF1034730C679E59641496DC79EBF.bin │ ├── DF9482E5F602508C283AEDA6058A64E1.bin │ ├── E77636A940AD0F15C9238849212ECDC5.bin │ └── FC88C6C26604001FC0056714582590FC.bin ├── stylesheets │ ├── style.css │ ├── history.css │ ├── sticky-footer.css │ └── blog.css ├── history │ ├── history.css │ ├── historyFrame.html │ └── history.js └── javascripts │ └── ie10-viewport-bug-workaround.js ├── views ├── error.ejs ├── index.ejs ├── keyboard.ejs ├── kb68.ejs ├── diyso72.ejs ├── index2.ejs └── epbt75.ejs ├── .gitignore ├── test ├── khash2.js ├── cls1.js ├── static.js ├── server_kc60.js ├── server_diyso60.js ├── server_epbt60.js ├── server_epbt60v2.js ├── initdb_diyso72.js ├── initdb_epbt68.js ├── epbt60 │ ├── keycodeToKey.json │ ├── fntype.json │ ├── create_keymap.js │ └── config.json ├── kc60 │ ├── keycodeToKey.json │ ├── fntype.json │ ├── create_keymap.js │ └── config.json ├── initdb_epbt75.js ├── epbt75.json ├── initdb.js └── initdb_kc60.js ├── package.json ├── routes └── index.js ├── app.js ├── bin └── www └── compiler ├── Makefile.kb68 ├── Makefile.kb72 ├── Makefile.kb84 ├── Makefile.kb60 └── Makefile.ble60 /README.md: -------------------------------------------------------------------------------- 1 | # online_compiler 2 | node js tmk compiler 3 | -------------------------------------------------------------------------------- /public/WebEdit.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jichuntao/online_compiler/HEAD/public/WebEdit.swf -------------------------------------------------------------------------------- /public/Preloader.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jichuntao/online_compiler/HEAD/public/Preloader.swf -------------------------------------------------------------------------------- /public/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jichuntao/online_compiler/HEAD/public/images/favicon.ico -------------------------------------------------------------------------------- /views/error.ejs: -------------------------------------------------------------------------------- 1 |
<%= error.stack %>4 | -------------------------------------------------------------------------------- /public/playerProductInstall.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jichuntao/online_compiler/HEAD/public/playerProductInstall.swf -------------------------------------------------------------------------------- /public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 |
Welcome to <%= title %>
10 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | static_file/*.hex 4 | ./log 5 | compiler/tmk_keyboard 6 | .dep/ 7 | *.log 8 | *_temp/ 9 | keymap.db 10 | server.js 11 | *.db 12 | bootstrap-4.0.0-alpha 13 | *.zip 14 | controller 15 | bin/.dep/ 16 | bin/compiler 17 | bin/keymap 18 | bin/obj_*_temp 19 | .idea 20 | public/firmware 21 | keymap -------------------------------------------------------------------------------- /test/khash2.js: -------------------------------------------------------------------------------- 1 | var sqlite3 = require('sqlite3'); 2 | var db = new sqlite3.Database('keymap.db',function() { 3 | db.serialize(function() { 4 | db.all("select * from keymaps where key = 'default'",function(err,res){ 5 | if(!err) 6 | console.log(res[0].keymap); 7 | else 8 | console.log(err); 9 | }); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/cls1.js: -------------------------------------------------------------------------------- 1 | 2 | function class1() 3 | { 4 | this.fun1=function (){ 5 | console.log('class1 fun1'); 6 | fun4(); 7 | } 8 | this.fun2=function(){ 9 | console.log('class1 fun2'); 10 | } 11 | var fun3 =function(){ 12 | console.log('class1 fun3'); 13 | }; 14 | function fun4() 15 | { 16 | console.log('class1 fun4'); 17 | } 18 | } 19 | var ss = new class1(); 20 | ss.fun1(); -------------------------------------------------------------------------------- /public/history/history.css: -------------------------------------------------------------------------------- 1 | /* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */ 2 | 3 | #ie_historyFrame { width: 0px; height: 0px; display:none } 4 | #firefox_anchorDiv { width: 0px; height: 0px; display:none } 5 | #safari_formDiv { width: 0px; height: 0px; display:none } 6 | #safari_rememberDiv { width: 0px; height: 0px; display:none } 7 | -------------------------------------------------------------------------------- /public/stylesheets/history.css: -------------------------------------------------------------------------------- 1 | /* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */ 2 | 3 | #ie_historyFrame { width: 0px; height: 0px; display:none } 4 | #firefox_anchorDiv { width: 0px; height: 0px; display:none } 5 | #safari_formDiv { width: 0px; height: 0px; display:none } 6 | #safari_rememberDiv { width: 0px; height: 0px; display:none } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "online_compiler", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.13.2", 10 | "cookie-parser": "~1.3.5", 11 | "debug": "~2.2.0", 12 | "ejs": "~2.3.3", 13 | "express": "~4.13.1", 14 | "morgan": "~1.6.1", 15 | "serve-favicon": "~2.3.0", 16 | "sqlite3" : "~3.1.1" 17 | } 18 | } -------------------------------------------------------------------------------- /public/javascripts/ie10-viewport-bug-workaround.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | // See the Getting Started docs for more information: 8 | // http://getbootstrap.com/getting-started/#support-ie10-width 9 | 10 | (function () { 11 | 'use strict'; 12 | 13 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 14 | var msViewportStyle = document.createElement('style') 15 | msViewportStyle.appendChild( 16 | document.createTextNode( 17 | '@-ms-viewport{width:auto!important}' 18 | ) 19 | ) 20 | document.querySelector('head').appendChild(msViewportStyle) 21 | } 22 | 23 | })(); 24 | -------------------------------------------------------------------------------- /public/stylesheets/sticky-footer.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer styles 2 | -------------------------------------------------- */ 3 | html { 4 | position: relative; 5 | min-height: 100%; 6 | } 7 | body { 8 | height: 100%; 9 | background-color: #eeeeee; 10 | overflow:auto; text-align:center; 11 | 12 | } 13 | .footer { 14 | position: absolute; 15 | bottom: 0; 16 | width: 100%; 17 | /* Set the fixed height of the footer here */ 18 | height: 60px; 19 | background-color: #f5f5f5; 20 | } 21 | 22 | 23 | /* Custom page CSS 24 | -------------------------------------------------- */ 25 | /* Not required for template or sticky footer method. */ 26 | 27 | .container { 28 | width: auto; 29 | max-width: 680px; 30 | padding: 0 15px; 31 | } 32 | .container .text-muted { 33 | margin: 20px 0; 34 | } 35 | -------------------------------------------------------------------------------- /public/history/historyFrame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 27 | Hidden frame for Browser History support. 28 | 29 | 30 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | /* ble60 */ 10 | router.get('/ble60', function(req, res, next) { 11 | res.render('keyboard', { kbtype: 'ble60' }); 12 | }); 13 | 14 | /* kc60 */ 15 | router.get('/kc60', function(req, res, next) { 16 | res.render('keyboard', { kbtype: 'kc60' }); 17 | }); 18 | 19 | /* epbt60 */ 20 | router.get('/epbt60', function(req, res, next) { 21 | res.render('keyboard', { kbtype: 'epbt60' }); 22 | }); 23 | 24 | /* epbt60v2 */ 25 | router.get('/epbt60v2', function(req, res, next) { 26 | res.render('keyboard', { kbtype: 'epbt60v2' }); 27 | }); 28 | 29 | /* diyso60 */ 30 | router.get('/diyso60', function(req, res, next) { 31 | res.render('keyboard', { kbtype: 'diyso60' }); 32 | }); 33 | 34 | /* epbt75 */ 35 | router.get('/epbt75', function(req, res, next) { 36 | res.render('keyboard', { kbtype: 'epbt75' }); 37 | }); 38 | 39 | /* test2 */ 40 | router.get('/index2', function(req, res, next) { 41 | res.render('epbt75', { kbtype: 'epbt75' }); 42 | }); 43 | 44 | /* diyer72 */ 45 | router.get('/diyer72', function(req, res, next) { 46 | res.render('diyso72', { kbtype: 'diyso72' }); 47 | }); 48 | 49 | /* kb68 */ 50 | router.get('/tada68', function(req, res, next) { 51 | res.render('kb68', { kbtype: 'kb68' }); 52 | }); 53 | module.exports = router; 54 | -------------------------------------------------------------------------------- /test/static.js: -------------------------------------------------------------------------------- 1 | 2 | var sys = require('sys'), 3 | http = require('http'), 4 | url = require('url'), 5 | path = require('path'), 6 | fs = require('fs'); 7 | 8 | function exe(req,res,rf,data) 9 | { 10 | var filename = rf.pathname; 11 | fs.exists(filename, function(exists) { 12 | if(!exists) { 13 | res.writeHead(404, { "Content-Type": "text/plain" }); 14 | res.write("404 Not Found\n"); 15 | res.end(); 16 | return; 17 | } 18 | fs.readFile(filename, "binary", function(err, file) { 19 | if(err) { 20 | res.writeHead(500, { "Content-Type": "text/plain" }); 21 | res.write(err + "\n"); 22 | res.end(); 23 | return; 24 | } 25 | var contentType='text/html'; 26 | if(Filetypes[rf.extname]){ 27 | contentType=Filetypes[rf.extname]; 28 | } 29 | res.writeHead(200, { 'Content-Type': contentType , 'Content-Length':file.length}); 30 | res.write(file, "binary"); 31 | res.end(); 32 | }); 33 | }); 34 | } 35 | var Filetypes = { 36 | ".css": "text/css", 37 | ".gif": "image/gif", 38 | ".html": "text/html", 39 | ".ico": "image/x-icon", 40 | ".jpeg": "image/jpeg", 41 | ".jpg": "image/jpeg", 42 | ".js": "text/javascript", 43 | ".json": "application/json", 44 | ".pdf": "application/pdf", 45 | ".png": "image/png", 46 | ".txt": "text/plain", 47 | ".xml": "text/xml", 48 | ".swf": "application/x-shockwave-flash", 49 | ".wav": "audio/x-wav", 50 | ".wma": "audio/x-ms-wma", 51 | ".wmv": "video/x-ms-wmv", 52 | ".svg": "image/svg+xml", 53 | ".hex": "application/octet-stream", 54 | ".bin": "application/octet-stream" 55 | }; 56 | exports.exe=exe; 57 | -------------------------------------------------------------------------------- /test/server_kc60.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var url = require('url'); 3 | var path = require('path'); 4 | var util = require('util'); 5 | 6 | var acc = 100; 7 | http.createServer(function (req, res) { 8 | acc++; 9 | if (req.method == 'POST') { 10 | var postData = ''; 11 | req.setEncoding('utf8'); 12 | req.on('data', function (postDataChunk) { 13 | postData += postDataChunk; 14 | }); 15 | req.on('end', function () { 16 | req.removeAllListeners(); 17 | handler(req, res, postData); 18 | postData = ''; 19 | }); 20 | } 21 | else if (req.method == 'GET') { 22 | handler(req, res, ''); 23 | } 24 | }).listen(9128); 25 | 26 | 27 | function handler(req, res, data) { 28 | var rf = restful(req.url); 29 | try { 30 | require('./' + rf.command).exe(req, res, rf, data); 31 | 32 | } catch (err) { 33 | console.log(err); 34 | res.writeHead(404); 35 | res.end(); 36 | } 37 | 38 | return 0; 39 | } 40 | function restful(urlstr) { 41 | 42 | var ret = {}; 43 | var urlObj = url.parse(urlstr, true); 44 | ret.pathname = urlObj.pathname; 45 | ret.query = urlObj.query; 46 | ret.pathname = path.normalize(ret.pathname); 47 | ret.pathname = (ret.pathname == '/') ? ret.pathname = '/index_kc60.html' : ret.pathname; 48 | if (path.extname(ret.pathname) == '') { 49 | ret.command = path.basename(ret.pathname); 50 | } else { 51 | ret.command = 'static'; 52 | ret.pathname = path.join('./static_file/', ret.pathname); 53 | ret.extname = path.extname(ret.pathname); 54 | } 55 | //console.log(ret); 56 | return ret; 57 | } 58 | console.log('Server running'); -------------------------------------------------------------------------------- /test/server_diyso60.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var url = require('url'); 3 | var path = require('path'); 4 | var util = require('util'); 5 | 6 | var acc = 100; 7 | http.createServer(function (req, res) { 8 | acc++; 9 | if (req.method == 'POST') { 10 | var postData = ''; 11 | req.setEncoding('utf8'); 12 | req.on('data', function (postDataChunk) { 13 | postData += postDataChunk; 14 | }); 15 | req.on('end', function () { 16 | req.removeAllListeners(); 17 | handler(req, res, postData); 18 | postData = ''; 19 | }); 20 | } 21 | else if (req.method == 'GET') { 22 | handler(req, res, ''); 23 | } 24 | }).listen(9188); 25 | 26 | 27 | function handler(req, res, data) { 28 | var rf = restful(req.url); 29 | try { 30 | require('./' + rf.command).exe(req, res, rf, data); 31 | 32 | } catch (err) { 33 | console.log(err); 34 | res.writeHead(404); 35 | res.end(); 36 | } 37 | 38 | return 0; 39 | } 40 | function restful(urlstr) { 41 | 42 | var ret = {}; 43 | var urlObj = url.parse(urlstr, true); 44 | ret.pathname = urlObj.pathname; 45 | ret.query = urlObj.query; 46 | ret.pathname = path.normalize(ret.pathname); 47 | ret.pathname = (ret.pathname == '/') ? ret.pathname = '/index_diyso60.html' : ret.pathname; 48 | if (path.extname(ret.pathname) == '') { 49 | ret.command = path.basename(ret.pathname); 50 | } else { 51 | ret.command = 'static'; 52 | ret.pathname = path.join('./static_file/', ret.pathname); 53 | ret.extname = path.extname(ret.pathname); 54 | } 55 | //console.log(ret); 56 | return ret; 57 | } 58 | console.log('Server running'); -------------------------------------------------------------------------------- /test/server_epbt60.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var url = require('url'); 3 | var path = require('path'); 4 | var util = require('util'); 5 | 6 | var acc = 100; 7 | http.createServer(function (req, res) { 8 | acc++; 9 | if (req.method == 'POST') { 10 | var postData = ''; 11 | req.setEncoding('utf8'); 12 | req.on('data', function (postDataChunk) { 13 | postData += postDataChunk; 14 | }); 15 | req.on('end', function () { 16 | req.removeAllListeners(); 17 | handler(req, res, postData); 18 | postData = ''; 19 | }); 20 | } 21 | else if (req.method == 'GET') { 22 | handler(req, res, ''); 23 | } 24 | }).listen(9127); 25 | 26 | 27 | function handler(req, res, data) { 28 | var rf = restful(req.url); 29 | try { 30 | require('./' + rf.command).exe(req, res, rf, data); 31 | 32 | } catch (err) { 33 | console.log(err); 34 | res.writeHead(404); 35 | res.end(); 36 | } 37 | 38 | return 0; 39 | } 40 | function restful(urlstr) { 41 | 42 | var ret = {}; 43 | var urlObj = url.parse(urlstr, true); 44 | ret.pathname = urlObj.pathname; 45 | ret.query = urlObj.query; 46 | ret.pathname = path.normalize(ret.pathname); 47 | ret.pathname = (ret.pathname == '/') ? ret.pathname = '/index_epbt.html' : ret.pathname; 48 | if (path.extname(ret.pathname) == '') { 49 | ret.command = path.basename(ret.pathname); 50 | } else { 51 | ret.command = 'static'; 52 | ret.pathname = path.join('./static_file/', ret.pathname); 53 | ret.extname = path.extname(ret.pathname); 54 | } 55 | //console.log(ret); 56 | return ret; 57 | } 58 | console.log('Server running'); -------------------------------------------------------------------------------- /test/server_epbt60v2.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var url = require('url'); 3 | var path = require('path'); 4 | var util = require('util'); 5 | 6 | var acc = 100; 7 | http.createServer(function (req, res) { 8 | acc++; 9 | if (req.method == 'POST') { 10 | var postData = ''; 11 | req.setEncoding('utf8'); 12 | req.on('data', function (postDataChunk) { 13 | postData += postDataChunk; 14 | }); 15 | req.on('end', function () { 16 | req.removeAllListeners(); 17 | handler(req, res, postData); 18 | postData = ''; 19 | }); 20 | } 21 | else if (req.method == 'GET') { 22 | handler(req, res, ''); 23 | } 24 | }).listen(9129); 25 | 26 | 27 | function handler(req, res, data) { 28 | var rf = restful(req.url); 29 | try { 30 | require('./' + rf.command).exe(req, res, rf, data); 31 | 32 | } catch (err) { 33 | console.log(err); 34 | res.writeHead(404); 35 | res.end(); 36 | } 37 | 38 | return 0; 39 | } 40 | function restful(urlstr) { 41 | 42 | var ret = {}; 43 | var urlObj = url.parse(urlstr, true); 44 | ret.pathname = urlObj.pathname; 45 | ret.query = urlObj.query; 46 | ret.pathname = path.normalize(ret.pathname); 47 | ret.pathname = (ret.pathname == '/') ? ret.pathname = '/index_epbt60v2.html' : ret.pathname; 48 | if (path.extname(ret.pathname) == '') { 49 | ret.command = path.basename(ret.pathname); 50 | } else { 51 | ret.command = 'static'; 52 | ret.pathname = path.join('./static_file/', ret.pathname); 53 | ret.extname = path.extname(ret.pathname); 54 | } 55 | //console.log(ret); 56 | return ret; 57 | } 58 | console.log('Server running'); -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | 8 | var routes = require('./routes/index'); 9 | var layout = require('./controller/layout'); 10 | var compile = require('./controller/compile'); 11 | 12 | var app = express(); 13 | 14 | // view engine setup 15 | app.set('views', path.join(__dirname, 'views')); 16 | app.set('view engine', 'ejs'); 17 | 18 | // uncomment after placing your favicon in /public 19 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 20 | app.use(logger('dev')); 21 | app.use(bodyParser.json()); 22 | app.use(bodyParser.urlencoded({ extended: false })); 23 | app.use(cookieParser()); 24 | app.use(express.static(path.join(__dirname, 'public'))); 25 | 26 | app.use('/', routes); 27 | app.use('/layout', layout); 28 | app.use('/compile', compile); 29 | 30 | // catch 404 and forward to error handler 31 | app.use(function(req, res, next) { 32 | var err = new Error('Not Found'); 33 | err.status = 404; 34 | next(err); 35 | }); 36 | 37 | // error handlers 38 | 39 | // development error handler 40 | // will print stacktrace 41 | if (app.get('env') === 'development') { 42 | app.use(function(err, req, res, next) { 43 | res.status(err.status || 500); 44 | res.render('error', { 45 | message: err.message, 46 | error: err 47 | }); 48 | }); 49 | } 50 | 51 | // production error handler 52 | // no stacktraces leaked to user 53 | app.use(function(err, req, res, next) { 54 | res.status(err.status || 500); 55 | res.render('error', { 56 | message: err.message, 57 | error: {} 58 | }); 59 | }); 60 | 61 | 62 | module.exports = app; 63 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('online_compiler:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /test/initdb_diyso72.js: -------------------------------------------------------------------------------- 1 | var sqlite3 = require('sqlite3').verbose(); 2 | var databaseFile='../keymap.db'; 3 | var db = new sqlite3.Database(databaseFile); 4 | var defaultKeymap=[[],[[[["KC_ESC"],["KC_F1"],["KC_F2"],["KC_F3"],["KC_F4"],["KC_F5"]],[["KC_GRV"],["KC_1"],["KC_2"],["KC_3"],["KC_4"],["KC_5"],["KC_6"],["KC_7"],["KC_8"],["KC_9"],["KC_0"],["KC_MINS"],["KC_EQL"],["KC_BSPC"],["KC_INS"]],[["KC_TAB"],["KC_Q"],["KC_W"],["KC_E"],["KC_R"],["KC_T"],["KC_Y"],["KC_U"],["KC_I"],["KC_O"],["KC_P"],["KC_LBRC"],["KC_RBRC"],["KC_BSLS"],["KC_DEL"]],[["KC_CAPS"],["KC_A"],["KC_S"],["KC_D"],["KC_F"],["KC_G"],["KC_H"],["KC_J"],["KC_K"],["KC_L"],["KC_SCLN"],["KC_QUOT"],["KC_ENT"]],[["KC_LSFT"],["KC_Z"],["KC_X"],["KC_C"],["KC_V"],["KC_B"],["KC_N"],["KC_M"],["KC_COMM"],["KC_DOT"],["KC_SLSH"],["KC_RSFT"],["KC_UP"]],[["KC_LCTRL"],["KC_LGUI"],["KC_LALT"],["KC_SPC"],["KC_RALT"],["KC_FN",[1,[1]]],["KC_RCTRL"],["KC_DOWN"],["KC_RGHT"],["KC_RGHT"]]],[[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]]]],"diyso72","1.2","bin"]; 5 | //console.log(JSON.stringify(defaultKeymap)); 6 | db.serialize(function() { 7 | db.run("delete from keymaps where key='diyso72'"); 8 | db.run("insert into keymaps values('diyso72','diyso72','"+JSON.stringify(defaultKeymap)+"')"); 9 | 10 | }); 11 | 12 | db.close(); -------------------------------------------------------------------------------- /test/initdb_epbt68.js: -------------------------------------------------------------------------------- 1 | var sqlite3 = require('sqlite3').verbose(); 2 | var databaseFile='../keymap.db'; 3 | var db = new sqlite3.Database(databaseFile); 4 | var defaultKeymap=[[0,0,0],[[[["KC_GRV"],["KC_1"],["KC_2"],["KC_3"],["KC_4"],["KC_5"],["KC_6"],["KC_7"],["KC_8"],["KC_9"],["KC_0"],["KC_MINS"],["KC_EQL"],["KC_BSPC"],["KC_DEL"]],[["KC_TAB"],["KC_Q"],["KC_W"],["KC_E"],["KC_R"],["KC_T"],["KC_Y"],["KC_U"],["KC_I"],["KC_O"],["KC_P"],["KC_LBRC"],["KC_RBRC"],["KC_BSLS"],["KC_PGUP"]],[["KC_CAPS"],["KC_A"],["KC_S"],["KC_D"],["KC_F"],["KC_G"],["KC_H"],["KC_J"],["KC_K"],["KC_L"],["KC_SCLN"],["KC_QUOT"],["KC_ENT"],["KC_PGDN"]],[["KC_LSFT"],["KC_Z"],["KC_X"],["KC_C"],["KC_V"],["KC_B"],["KC_N"],["KC_M"],["KC_COMM"],["KC_DOT"],["KC_SLSH"],["KC_RSFT"],["KC_UP"],["KC_FN",[1,[1]]]],[["KC_LCTRL"],["KC_LGUI"],["KC_LALT"],["KC_SPC"],["KC_RALT"],["KC_RCTRL"],["KC_LEFT"],["KC_DOWN"],["KC_RGHT"]]],[[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]],[["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"],["KC_TRNS"]]]],"kb68","1.2","bin"]; 5 | db.serialize(function() { 6 | db.run("delete from keymaps where key='kb68'"); 7 | db.run("insert into keymaps values('kb68','kb68','"+JSON.stringify(defaultKeymap)+"')"); 8 | }); 9 | 10 | db.close(); -------------------------------------------------------------------------------- /test/epbt60/keycodeToKey.json: -------------------------------------------------------------------------------- 1 | { 2 | "8": "BSPC", 3 | "9": "TAB", 4 | "12": "CLEAR", 5 | "13": "ENT", 6 | "16": "LSFT", 7 | "17": "LCTRL", 8 | "18": "LALT", 9 | "20": "CAPS", 10 | "27": "ESC", 11 | "32": "SPC", 12 | "33": "PGUP", 13 | "34": "PGDN", 14 | "35": "END", 15 | "36": "HOME", 16 | "37": "LEFT", 17 | "38": "UP", 18 | "39": "RGHT", 19 | "40": "DOWN", 20 | "45": "INS", 21 | "46": "DEL", 22 | "47": "HELP", 23 | "48": "0", 24 | "49": "1", 25 | "50": "2", 26 | "51": "3", 27 | "52": "4", 28 | "53": "5", 29 | "54": "6", 30 | "55": "7", 31 | "56": "8", 32 | "57": "9", 33 | "65": "A", 34 | "66": "B", 35 | "67": "C", 36 | "68": "D", 37 | "69": "E", 38 | "70": "F", 39 | "71": "G", 40 | "72": "H", 41 | "73": "I", 42 | "74": "J", 43 | "75": "K", 44 | "76": "L", 45 | "77": "M", 46 | "78": "N", 47 | "79": "O", 48 | "80": "P", 49 | "81": "Q", 50 | "82": "R", 51 | "83": "S", 52 | "84": "T", 53 | "85": "U", 54 | "86": "V", 55 | "87": "W", 56 | "88": "X", 57 | "89": "Y", 58 | "90": "Z", 59 | "96": "P0", 60 | "97": "P1", 61 | "98": "P2", 62 | "99": "P3", 63 | "100": "P4", 64 | "101": "P5", 65 | "102": "P6", 66 | "103": "P7", 67 | "104": "P8", 68 | "105": "P9", 69 | "106": "PAST", 70 | "107": "PPLS", 71 | "108": "PENT", 72 | "109": "PMNS", 73 | "110": "PDOT", 74 | "111": "PSLS", 75 | "112": "F1", 76 | "113": "F2", 77 | "114": "F3", 78 | "115": "F4", 79 | "116": "F5", 80 | "117": "F6", 81 | "118": "F7", 82 | "119": "F8", 83 | "120": "F9", 84 | "121": "F10", 85 | "122": "F11", 86 | "123": "F12", 87 | "124": "PSCR", 88 | "125": "F14", 89 | "126": "F15", 90 | "144": "NLCK", 91 | "186": "QUOT", 92 | "187": "EQL", 93 | "188": "COMM", 94 | "189": "MINS", 95 | "190": "DOT", 96 | "191": "SLSH", 97 | "219": "LBRC", 98 | "220": "BSLS", 99 | "221": "RBRC", 100 | "222": "SCLN" 101 | } -------------------------------------------------------------------------------- /test/kc60/keycodeToKey.json: -------------------------------------------------------------------------------- 1 | { 2 | "8": "BSPC", 3 | "9": "TAB", 4 | "12": "CLEAR", 5 | "13": "ENT", 6 | "16": "LSFT", 7 | "17": "LCTRL", 8 | "18": "LALT", 9 | "20": "CAPS", 10 | "27": "ESC", 11 | "32": "SPC", 12 | "33": "PGUP", 13 | "34": "PGDN", 14 | "35": "END", 15 | "36": "HOME", 16 | "37": "LEFT", 17 | "38": "UP", 18 | "39": "RGHT", 19 | "40": "DOWN", 20 | "45": "INS", 21 | "46": "DEL", 22 | "47": "HELP", 23 | "48": "0", 24 | "49": "1", 25 | "50": "2", 26 | "51": "3", 27 | "52": "4", 28 | "53": "5", 29 | "54": "6", 30 | "55": "7", 31 | "56": "8", 32 | "57": "9", 33 | "65": "A", 34 | "66": "B", 35 | "67": "C", 36 | "68": "D", 37 | "69": "E", 38 | "70": "F", 39 | "71": "G", 40 | "72": "H", 41 | "73": "I", 42 | "74": "J", 43 | "75": "K", 44 | "76": "L", 45 | "77": "M", 46 | "78": "N", 47 | "79": "O", 48 | "80": "P", 49 | "81": "Q", 50 | "82": "R", 51 | "83": "S", 52 | "84": "T", 53 | "85": "U", 54 | "86": "V", 55 | "87": "W", 56 | "88": "X", 57 | "89": "Y", 58 | "90": "Z", 59 | "96": "P0", 60 | "97": "P1", 61 | "98": "P2", 62 | "99": "P3", 63 | "100": "P4", 64 | "101": "P5", 65 | "102": "P6", 66 | "103": "P7", 67 | "104": "P8", 68 | "105": "P9", 69 | "106": "PAST", 70 | "107": "PPLS", 71 | "108": "PENT", 72 | "109": "PMNS", 73 | "110": "PDOT", 74 | "111": "PSLS", 75 | "112": "F1", 76 | "113": "F2", 77 | "114": "F3", 78 | "115": "F4", 79 | "116": "F5", 80 | "117": "F6", 81 | "118": "F7", 82 | "119": "F8", 83 | "120": "F9", 84 | "121": "F10", 85 | "122": "F11", 86 | "123": "F12", 87 | "124": "PSCR", 88 | "125": "F14", 89 | "126": "F15", 90 | "144": "NLCK", 91 | "186": "QUOT", 92 | "187": "EQL", 93 | "188": "COMM", 94 | "189": "MINS", 95 | "190": "DOT", 96 | "191": "SLSH", 97 | "219": "LBRC", 98 | "220": "BSLS", 99 | "221": "RBRC", 100 | "222": "SCLN" 101 | } -------------------------------------------------------------------------------- /test/epbt60/fntype.json: -------------------------------------------------------------------------------- 1 | { 2 | "fntype": [ 3 | { 4 | "args": [], 5 | "action": "ACTION_KEY", 6 | "type": 0 7 | }, 8 | { 9 | "args": [ 10 | 1 11 | ], 12 | "action": "ACTION_LAYER_MOMENTARY", 13 | "type": 1 14 | }, 15 | { 16 | "args": [ 17 | 1 18 | ], 19 | "action": "ACTION_LAYER_ON", 20 | "type": 2 21 | }, 22 | { 23 | "args": [ 24 | 1 25 | ], 26 | "action": "ACTION_LAYER_OFF", 27 | "type": 2 28 | }, 29 | { 30 | "args": [ 31 | 1 32 | ], 33 | "action": "ACTION_LAYER_TOGGLE", 34 | "type": 1 35 | }, 36 | { 37 | "args": [ 38 | 1, 39 | "KC_NO" 40 | ], 41 | "action": "ACTION_LAYER_TAP_KEY", 42 | "type": 3 43 | }, 44 | { 45 | "args": [ 46 | 0, 47 | 0, 48 | 0, 49 | 0 50 | ], 51 | "action": "ACTION_MODS", 52 | "type": 4 53 | }, 54 | { 55 | "args": [ 56 | 0, 57 | 0, 58 | 0, 59 | 0, 60 | "KC_NO" 61 | ], 62 | "action": "ACTION_MODS_KEY", 63 | "type": 5 64 | }, 65 | { 66 | "args": [ 67 | 0, 68 | 0, 69 | 0, 70 | 0 71 | ], 72 | "action": "ACTION_MODS_ONESHOT", 73 | "type": 4 74 | }, 75 | { 76 | "args": [ 77 | 0, 78 | 0, 79 | 0, 80 | 0 81 | ], 82 | "action": "ACTION_MODS_TAP_TOGGLE", 83 | "type": 4 84 | }, 85 | { 86 | "args": [ 87 | 1 88 | ], 89 | "action": "ACTION_LAYER_CLEAR", 90 | "type": 6 91 | }, 92 | { 93 | "args": [], 94 | "action": "ACTION_MACRO", 95 | "type": 7 96 | } 97 | ], 98 | "fntype_sp": { 99 | "KC_LED_IN": { 100 | "action": "ACTION_BACKLIGHT_INCREASE", 101 | "args": [] 102 | }, 103 | "KC_LED_DE": { 104 | "action": "ACTION_BACKLIGHT_DECREASE", 105 | "args": [] 106 | }, 107 | "KC_LED_TOGGLE": { 108 | "action": "ACTION_BACKLIGHT_TOGGLE", 109 | "args": [] 110 | }, 111 | "KC_SFT_ESC": { 112 | "action": "ACTION_FUNCTION", 113 | "args": [ 114 | "SHIFT_ESC" 115 | ] 116 | }, 117 | "KC_LOCK_WIN": { 118 | "action": "ACTION_NOGUI_TOGGLE", 119 | "args": [] 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /test/kc60/fntype.json: -------------------------------------------------------------------------------- 1 | { 2 | "fntype": [ 3 | { 4 | "args": [], 5 | "action": "ACTION_KEY", 6 | "type": 0 7 | }, 8 | { 9 | "args": [ 10 | 1 11 | ], 12 | "action": "ACTION_LAYER_MOMENTARY", 13 | "type": 1 14 | }, 15 | { 16 | "args": [ 17 | 1 18 | ], 19 | "action": "ACTION_LAYER_ON", 20 | "type": 2 21 | }, 22 | { 23 | "args": [ 24 | 1 25 | ], 26 | "action": "ACTION_LAYER_OFF", 27 | "type": 2 28 | }, 29 | { 30 | "args": [ 31 | 1 32 | ], 33 | "action": "ACTION_LAYER_TOGGLE", 34 | "type": 1 35 | }, 36 | { 37 | "args": [ 38 | 1, 39 | "KC_NO" 40 | ], 41 | "action": "ACTION_LAYER_TAP_KEY", 42 | "type": 3 43 | }, 44 | { 45 | "args": [ 46 | 0, 47 | 0, 48 | 0, 49 | 0 50 | ], 51 | "action": "ACTION_MODS", 52 | "type": 4 53 | }, 54 | { 55 | "args": [ 56 | 0, 57 | 0, 58 | 0, 59 | 0, 60 | "KC_NO" 61 | ], 62 | "action": "ACTION_MODS_KEY", 63 | "type": 5 64 | }, 65 | { 66 | "args": [ 67 | 0, 68 | 0, 69 | 0, 70 | 0 71 | ], 72 | "action": "ACTION_MODS_ONESHOT", 73 | "type": 4 74 | }, 75 | { 76 | "args": [ 77 | 0, 78 | 0, 79 | 0, 80 | 0 81 | ], 82 | "action": "ACTION_MODS_TAP_TOGGLE", 83 | "type": 4 84 | }, 85 | { 86 | "args": [ 87 | 1 88 | ], 89 | "action": "ACTION_LAYER_CLEAR", 90 | "type": 6 91 | }, 92 | { 93 | "args": [], 94 | "action": "ACTION_MACRO", 95 | "type": 7 96 | } 97 | ], 98 | "fntype_sp": { 99 | "KC_LED_IN": { 100 | "action": "ACTION_BACKLIGHT_INCREASE", 101 | "args": [] 102 | }, 103 | "KC_LED_DE": { 104 | "action": "ACTION_BACKLIGHT_DECREASE", 105 | "args": [] 106 | }, 107 | "KC_LED_TOGGLE": { 108 | "action": "ACTION_BACKLIGHT_TOGGLE", 109 | "args": [] 110 | }, 111 | "KC_SFT_ESC": { 112 | "action": "ACTION_FUNCTION", 113 | "args": [ 114 | "SHIFT_ESC" 115 | ] 116 | }, 117 | "KC_LOCK_WIN": { 118 | "action": "ACTION_NOGUI_TOGGLE", 119 | "args": [] 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /public/stylesheets/blog.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Globals 3 | */ 4 | 5 | @media (min-width: 48em) { 6 | html { 7 | font-size: 18px; 8 | } 9 | } 10 | 11 | body { 12 | color: #555; 13 | } 14 | 15 | h1, .h1, 16 | h2, .h2, 17 | h3, .h3, 18 | h4, .h4, 19 | h5, .h5, 20 | h6, .h6 { 21 | font-weight: normal; 22 | color: #333; 23 | } 24 | 25 | 26 | /* 27 | * Override Bootstrap's default container. 28 | */ 29 | 30 | .container { 31 | max-width: 60rem; 32 | } 33 | 34 | 35 | /* 36 | * Masthead for nav 37 | */ 38 | 39 | .blog-masthead { 40 | margin-bottom: 0rem; 41 | background-color: #428bca; 42 | -webkit-box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.1); 43 | box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.1); 44 | } 45 | 46 | /* Nav links */ 47 | .nav-link { 48 | position: relative; 49 | padding: 1rem; 50 | font-weight: 500; 51 | color: #cdddeb; 52 | } 53 | .nav-link:hover, 54 | .nav-link:focus { 55 | color: #fff; 56 | background-color: transparent; 57 | } 58 | 59 | /* Active state gets a caret at the bottom */ 60 | .nav-link.active { 61 | color: #fff; 62 | } 63 | .nav-link.active:after { 64 | position: absolute; 65 | bottom: 0; 66 | left: 50%; 67 | width: 0; 68 | height: 0; 69 | margin-left: -.3rem; 70 | vertical-align: middle; 71 | content: ""; 72 | border-right: .3rem solid transparent; 73 | border-bottom: .3rem solid; 74 | border-left: .3rem solid transparent; 75 | } 76 | 77 | 78 | /* 79 | * Blog name and description 80 | */ 81 | 82 | .blog-header { 83 | padding-bottom: 1.25rem; 84 | margin-bottom: 2rem; 85 | border-bottom: .05rem solid #eee; 86 | } 87 | .blog-title { 88 | margin-bottom: 0; 89 | font-size: 2rem; 90 | font-weight: normal; 91 | } 92 | .blog-description { 93 | font-size: 1.1rem; 94 | color: #999; 95 | } 96 | 97 | @media (min-width: 40em) { 98 | .blog-title { 99 | font-size: 3.5rem; 100 | } 101 | } 102 | 103 | 104 | /* 105 | * Main column and sidebar layout 106 | */ 107 | 108 | /* Sidebar modules for boxing content */ 109 | .sidebar-module { 110 | padding: 1rem; 111 | /*margin: 0 -1rem 1rem;*/ 112 | } 113 | .sidebar-module-inset { 114 | padding: 1rem; 115 | background-color: #f5f5f5; 116 | border-radius: .25rem; 117 | } 118 | .sidebar-module-inset p:last-child, 119 | .sidebar-module-inset ul:last-child, 120 | .sidebar-module-inset ol:last-child { 121 | margin-bottom: 0; 122 | } 123 | 124 | 125 | /* Pagination */ 126 | .pager { 127 | margin-bottom: 4rem; 128 | text-align: left; 129 | } 130 | .pager > li > a { 131 | width: 8rem; 132 | padding: .75rem 1.25rem; 133 | text-align: center; 134 | border-radius: 2rem; 135 | } 136 | 137 | 138 | /* 139 | * Blog posts 140 | */ 141 | 142 | .blog-post { 143 | margin-bottom: 4rem; 144 | } 145 | .blog-post-title { 146 | margin-bottom: .25rem; 147 | font-size: 2.5rem; 148 | } 149 | .blog-post-meta { 150 | margin-bottom: 1.25rem; 151 | color: #999; 152 | } 153 | 154 | 155 | /* 156 | * Footer 157 | */ 158 | 159 | .blog-footer { 160 | padding: 2.5rem 0; 161 | color: #999; 162 | text-align: center; 163 | background-color: #f9f9f9; 164 | border-top: .05rem solid #e5e5e5; 165 | } 166 | .blog-footer p:last-child { 167 | margin-bottom: 0; 168 | } 169 | -------------------------------------------------------------------------------- /views/keyboard.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 |78 | To view this page ensure that Adobe Flash Player version 79 | 11.1.0 or greater is installed. 80 |
81 |81 | To view this page ensure that Adobe Flash Player version 82 | 11.1.0 or greater is installed. 83 |
84 |刷机方式:按下键盘PCB背部的刷机按钮,此时键盘会识别为U盘,点击编译固件后,将bin覆盖U盘中的固件然后按Esc键重启键盘即可。
89 | 90 |81 | To view this page ensure that Adobe Flash Player version 82 | 11.1.0 or greater is installed. 83 |
84 |刷机方式:按下键盘PCB背部的刷机按钮,此时键盘会识别为U盘,点击编译固件后,将bin覆盖U盘中的固件然后按Esc键重启键盘即可。
89 | 90 | 91 |81 | To view this page ensure that Adobe Flash Player version 82 | 11.1.0 or greater is installed. 83 |
84 |Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS.
92 |Use the sticky footer with a fixed navbar if need be, too.
93 |81 | To view this page ensure that Adobe Flash Player version 82 | 11.1.0 or greater is installed. 83 |
84 |配列1: WKL(Winkeyless) , 配列2: WK(Winkey)
89 |刷机方式:按下键盘PCB背部的刷机按钮,此时键盘会识别为U盘,点击编译固件后,将bin覆盖U盘中的固件然后按Esc键重启键盘即可。
90 | 91 | 92 |