@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
var dimensions = { |
||||
|
||||
width:0, |
||||
|
||||
height:0, |
||||
|
||||
getWidth: function () { |
||||
if (window.innerWidth) { |
||||
return window.innerWidth; |
||||
} |
||||
if (document.documentElement && document.documentElement.clientHeight){ |
||||
return document.documentElement.clientWidth; |
||||
} |
||||
if (document.body) { |
||||
return document.body.clientWidth; |
||||
} |
||||
return 0; |
||||
}, |
||||
|
||||
getHeight: function () { |
||||
if (window.innerWidth) { |
||||
return window.innerHeight; |
||||
} |
||||
if (document.documentElement && document.documentElement.clientHeight){ |
||||
return document.documentElement.clientHeight; |
||||
} |
||||
if (document.body) { |
||||
return document.body.clientHeight; |
||||
} |
||||
return 0; |
||||
}, |
||||
|
||||
update: function () { |
||||
var curW = this.getWidth() |
||||
var curH = this.getHeight() |
||||
if (curW!=this.width||curH!=this.height){ |
||||
this.width=curW |
||||
this.height=curH |
||||
return true |
||||
} |
||||
else { |
||||
return false |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,189 @@
@@ -0,0 +1,189 @@
|
||||
// (function(){
|
||||
|
||||
// var color = "rgb(255,133,0)"
|
||||
// var color = "rgb(55,110,79)"
|
||||
var color="white" |
||||
|
||||
// var color = "rgb(255,221,21)"
|
||||
// var color = '#'+(16777216+Math.floor(Math.random()*16777215)).toString(16).slice(1)
|
||||
// document.styleSheets[0].insertRule("a {color: "+color+"}",0)
|
||||
|
||||
var lasttime, |
||||
canvas = document.getElementById('canvas'), |
||||
ctx = canvas.getContext('2d'); |
||||
|
||||
// canvas.style['background-color'] = color;
|
||||
|
||||
var logo = new Image(), logo_small = new Image() |
||||
logo.src = 'img/logo.png' |
||||
logo_small.src = 'img/logo.png' |
||||
|
||||
|
||||
// var pixelRatio = (function(context) {
|
||||
// var backingStore = context.backingStorePixelRatio ||
|
||||
// context.webkitBackingStorePixelRatio ||
|
||||
// context.mozBackingStorePixelRatio ||
|
||||
// context.msBackingStorePixelRatio ||
|
||||
// context.oBackingStorePixelRatio ||
|
||||
// context.backingStorePixelRatio || 1;
|
||||
|
||||
// return (window.devicePixelRatio || 1) / backingStore;
|
||||
// })(ctx);
|
||||
|
||||
function app1(p,a,c1,c2){ |
||||
var l = Math.cos(a)*p[c1]+Math.sin(a)*p[c2] |
||||
var k = -Math.sin(a)*p[c1]+Math.cos(a)*p[c2] |
||||
p[c1] = l |
||||
p[c2] = k |
||||
} |
||||
|
||||
function app2(p,a,c1,c2){ |
||||
var l = Math.cos(a)*p[c1]-Math.sin(a)*p[c2] |
||||
var k = Math.sin(a)*p[c1]+Math.cos(a)*p[c2] |
||||
p[c1] = l |
||||
p[c2] = k |
||||
} |
||||
|
||||
var _edges |
||||
function tesseractedges(){ |
||||
if(!_edges){ |
||||
var m = tesseractwithrotation(0,0,0,0,0,0) |
||||
var edges = [] |
||||
var indicies = ['x','y','z','w'] |
||||
for (var i = 0; i < m.length; i++) { |
||||
for (var j = i+1; j < m.length; j++) { |
||||
var count = 0 |
||||
for (var k = 0; k < 4; k++) { |
||||
if (m[i][indicies[k]] === m[j][indicies[k]]) count++ |
||||
}; |
||||
if (count === 3) edges.push([i,j]) |
||||
} |
||||
} |
||||
_edges = edges |
||||
} |
||||
return _edges |
||||
} |
||||
|
||||
function tesseractwithrotation(a,b,c,d,e,f) { |
||||
var verticies = [] |
||||
for (var i = 0; i < 16; i++) { |
||||
var p = { |
||||
x: (i&1)*2 - 1, |
||||
y: ((i>>1)&1)*2 - 1, |
||||
z: ((i>>2)&1)*2 - 1, |
||||
w: ((i>>3)&1)*2 - 1 |
||||
} |
||||
app1(p,a,'x','y') |
||||
app1(p,b,'y','z') |
||||
app1(p,c,'x','w') |
||||
app2(p,d,'x','z') |
||||
app2(p,e,'y','w') |
||||
app2(p,f,'z','w') |
||||
verticies.push(p) |
||||
} |
||||
return verticies |
||||
} |
||||
|
||||
function project(point, size){ |
||||
return { |
||||
x: (point.x+Math.SQRT2*point.z)*size, |
||||
y: (point.y+Math.SQRT2*point.w)*size |
||||
} |
||||
} |
||||
|
||||
|
||||
function init () { |
||||
fixdim() |
||||
lasttime = new Date().getTime() |
||||
requestAnimationFrame(main) |
||||
} |
||||
|
||||
function fixdim() { |
||||
if(dimensions.update()){ |
||||
var displaywidth = Math.sqrt(dimensions.width)*18//dimensions.width > 900 ? 900 : 450
|
||||
var displayheight = displaywidth * 4/15//dimensions.width > 900 ? 250 : 125
|
||||
canvas.width = displaywidth*window.devicePixelRatio |
||||
canvas.style.width = displaywidth |
||||
canvas.height = displayheight*window.devicePixelRatio |
||||
canvas.style.height = displayheight |
||||
} |
||||
} |
||||
|
||||
function drawtesseract(tesseract, opts){ |
||||
var edges = tesseractedges() |
||||
for (var i = 0; i < tesseract.length; i++) { |
||||
var proj = project(tesseract[i], opts.size) |
||||
ctx.beginPath() |
||||
ctx.arc(proj.x + opts.x, proj.y + opts.y, opts.corner_radius, 0, 2 * Math.PI) |
||||
ctx.fill() |
||||
}; |
||||
ctx.lineWidth = opts.line_width || 1 |
||||
ctx.beginPath() |
||||
for (var i = 0; i < edges.length; i++) { |
||||
var v1 = project(tesseract[edges[i][0]], opts.size), |
||||
v2 = project(tesseract[edges[i][1]], opts.size) |
||||
ctx.moveTo(v1.x+opts.x,v1.y+opts.y) |
||||
ctx.lineTo(v2.x+opts.x,v2.y+opts.y) |
||||
}; |
||||
ctx.stroke() |
||||
} |
||||
|
||||
var as = -.371, df = -.01, gh = .12; |
||||
|
||||
var asdf = 120 |
||||
var sdfg = .01 |
||||
|
||||
var x = 10, y=10,w = 10,h = 10 |
||||
|
||||
function main (time) { |
||||
fixdim() |
||||
ctx.clearRect(0,0,canvas.width,canvas.height) |
||||
|
||||
var t = time/10000 |
||||
|
||||
// "rgb(0,140,255)"
|
||||
// ctx.strokeStyle = '#444'
|
||||
// ctx.fillStyle = "rgb(0,140,255)"
|
||||
ctx.strokeStyle = ctx.fillStyle = color |
||||
var sm = 1 |
||||
|
||||
// var m = tesseractwithrotation( 0,0,0,mouse.x/100 ,mouse.y/100, 0)
|
||||
var m = tesseractwithrotation(t, t*2, t*3, mouse.x/100 , mouse.y/100, 0) |
||||
|
||||
drawtesseract(m, { |
||||
x: as*canvas.width + canvas.width/2, |
||||
y: df*canvas.height + canvas.height/2, |
||||
size: gh*canvas.height, |
||||
corner_radius: 0, |
||||
line_width: 2 |
||||
}) |
||||
|
||||
ctx.beginPath() |
||||
// ctx.fillStyle = 'red'
|
||||
// ctx.fillRect(
|
||||
// (as+.5 - .0058)*canvas.width,
|
||||
// (df+.002+.5-.164)*canvas.height,// + canvas.height/2 - asdf/2,
|
||||
// .0058*2*canvas.width,
|
||||
// .164*2*canvas.height
|
||||
// )
|
||||
// ctx.fillRect(
|
||||
// 0.0951*canvas.width,
|
||||
// 0.0871*canvas.width,
|
||||
// 0.0673*canvas.width,
|
||||
// 0.0109*canvas.width
|
||||
// )
|
||||
|
||||
// ctx.fill()
|
||||
|
||||
// var m = tesseractwithrotation(0,0,0, mouse.x/100 , mouse.y/100, 0)
|
||||
// var m = tesseractwithrotation(t, t*2, t*3, mouse.x/100 , mouse.y/100, 0)
|
||||
// var k = tesseractwithrotation(t, t*2, t*3, mouse.x/100+.08, mouse.y/100, 0)
|
||||
|
||||
|
||||
lasttime = time |
||||
requestAnimationFrame(main) |
||||
} |
||||
|
||||
init() |
||||
|
||||
// })()
|
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
var mouse = { |
||||
x: 0, |
||||
y: 0, |
||||
direction:0, |
||||
|
||||
start: { |
||||
x:0, |
||||
y:0 |
||||
}, |
||||
|
||||
dragging: false, |
||||
|
||||
set: function (x,y) { |
||||
mouse.x = x |
||||
mouse.y = y |
||||
mouse.direction = Math.atan2(y-mouse.start.y,x-mouse.start.x) |
||||
}, |
||||
|
||||
coords: function (e) { |
||||
// e.preventDefault();
|
||||
if(e.pageX){ |
||||
mouse.set(e.pageX,e.pageY) |
||||
} |
||||
else if(e.offsetX) { |
||||
mouse.set(e.offsetX,e.offsetY) |
||||
} |
||||
else if(e.layerX) { |
||||
mouse.set(e.layerX,e.layerY) |
||||
} |
||||
else if(e.targetTouches && e.targetTouches.length > 0){ |
||||
mouse.set(e.targetTouches[0].pageX,e.targetTouches[0].pageY) |
||||
} |
||||
}, |
||||
|
||||
down: function (e) { |
||||
mouse.coords(e) |
||||
mouse.start.x=mouse.x |
||||
mouse.start.y=mouse.y |
||||
mouse.dragging = true |
||||
// console.log(e)
|
||||
|
||||
}, |
||||
|
||||
up: function (e) { |
||||
mouse.coords(e) |
||||
mouse.dragging = false |
||||
} |
||||
} |
||||
|
||||
document.addEventListener("touchstart", mouse.down, true); |
||||
document.addEventListener("touchend", mouse.up, true); |
||||
document.addEventListener("touchmove", mouse.coords, true); |
||||
|
||||
document.addEventListener("mousedown", mouse.down, true); |
||||
document.addEventListener("mouseup", mouse.up, true); |
||||
document.addEventListener("mousemove", mouse.coords, true); |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
||||
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
|
||||
// MIT license
|
||||
|
||||
;(function() { |
||||
var lastTime = 0; |
||||
var vendors = ['ms', 'moz', 'webkit', 'o']; |
||||
if(typeof window != "undefined"){ |
||||
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { |
||||
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; |
||||
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] |
||||
|| window[vendors[x]+'CancelRequestAnimationFrame']; |
||||
} |
||||
if (!window.requestAnimationFrame) |
||||
window.requestAnimationFrame = function(callback, element) { |
||||
var currTime = new Date().getTime(); |
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime)); |
||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); }, |
||||
timeToCall); |
||||
lastTime = currTime + timeToCall; |
||||
return id; |
||||
}; |
||||
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; |
||||
} |
||||
}()); |
||||
|
@ -0,0 +1,327 @@
@@ -0,0 +1,327 @@
|
||||
/* BASICS */ |
||||
|
||||
.CodeMirror { |
||||
/* Set height, width, borders, and global font properties here */ |
||||
font-family: monospace; |
||||
height: auto; |
||||
color: black; |
||||
padding: 10px; |
||||
padding-top: 5px; |
||||
} |
||||
|
||||
/* PADDING */ |
||||
|
||||
.CodeMirror-lines { |
||||
padding: 4px 0; /* Vertical padding around content */ |
||||
} |
||||
.CodeMirror pre { |
||||
padding: 0 4px; /* Horizontal padding of content */ |
||||
} |
||||
|
||||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { |
||||
background-color: white; /* The little square between H and V scrollbars */ |
||||
} |
||||
|
||||
/* GUTTER */ |
||||
|
||||
.CodeMirror-gutters { |
||||
border-right: 1px solid #ddd; |
||||
background-color: #f7f7f7; |
||||
white-space: nowrap; |
||||
} |
||||
.CodeMirror-linenumbers {} |
||||
.CodeMirror-linenumber { |
||||
padding: 0 3px 0 5px; |
||||
min-width: 20px; |
||||
text-align: right; |
||||
color: #999; |
||||
white-space: nowrap; |
||||
} |
||||
|
||||
.CodeMirror-guttermarker { color: black; } |
||||
.CodeMirror-guttermarker-subtle { color: #999; } |
||||
|
||||
/* CURSOR */ |
||||
|
||||
.CodeMirror div.CodeMirror-cursor { |
||||
border-left: 1px solid black; |
||||
} |
||||
/* Shown when moving in bi-directional text */ |
||||
.CodeMirror div.CodeMirror-secondarycursor { |
||||
border-left: 1px solid silver; |
||||
} |
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursor { |
||||
width: auto; |
||||
border: 0; |
||||
background: #7e7; |
||||
} |
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursors { |
||||
z-index: 1; |
||||
} |
||||
|
||||
.cm-animate-fat-cursor { |
||||
width: auto; |
||||
border: 0; |
||||
-webkit-animation: blink 1.06s steps(1) infinite; |
||||
-moz-animation: blink 1.06s steps(1) infinite; |
||||
animation: blink 1.06s steps(1) infinite; |
||||
} |
||||
@-moz-keyframes blink { |
||||
0% { background: #7e7; } |
||||
50% { background: none; } |
||||
100% { background: #7e7; } |
||||
} |
||||
@-webkit-keyframes blink { |
||||
0% { background: #7e7; } |
||||
50% { background: none; } |
||||
100% { background: #7e7; } |
||||
} |
||||
@keyframes blink { |
||||
0% { background: #7e7; } |
||||
50% { background: none; } |
||||
100% { background: #7e7; } |
||||
} |
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */ |
||||
div.CodeMirror-overwrite div.CodeMirror-cursor {} |
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; } |
||||
|
||||
.CodeMirror-ruler { |
||||
border-left: 1px solid #ccc; |
||||
position: absolute; |
||||
} |
||||
|
||||
/* DEFAULT THEME */ |
||||
|
||||
.cm-s-default .cm-header {color: blue;} |
||||
.cm-s-default .cm-quote {color: #090;} |
||||
.cm-negative {color: #d44;} |
||||
.cm-positive {color: #292;} |
||||
.cm-header, .cm-strong {font-weight: bold;} |
||||
.cm-em {font-style: italic;} |
||||
.cm-link {text-decoration: underline;} |
||||
.cm-strikethrough {text-decoration: line-through;} |
||||
|
||||
.cm-s-default .cm-keyword {color: #f90;} |
||||
.cm-s-default .cm-atom {color: #219;} |
||||
.cm-s-default .cm-number {color: #164;} |
||||
.cm-s-default .cm-def {color: #00f;} |
||||
.cm-s-default .cm-variable, |
||||
.cm-s-default .cm-punctuation {} |
||||
.cm-s-default .cm-property {color: #4CA2F2;} |
||||
.cm-s-default .cm-operator {} |
||||
.cm-s-default .cm-variable-2 {color: #05a;} |
||||
.cm-s-default .cm-variable-3 {color: #085;} |
||||
.cm-s-default .cm-comment {color: #a50;} |
||||
.cm-s-default .cm-string {color: #a11;} |
||||
.cm-s-default .cm-string-2 {color: #f50;} |
||||
.cm-s-default .cm-meta {color: #555;} |
||||
.cm-s-default .cm-qualifier {color: #555;} |
||||
.cm-s-default .cm-builtin {color: #30a;} |
||||
.cm-s-default .cm-bracket {color: #997;} |
||||
.cm-s-default .cm-tag {color: #170;} |
||||
.cm-s-default .cm-attribute {color: #00c;} |
||||
.cm-s-default .cm-hr {color: #999;} |
||||
.cm-s-default .cm-link {color: #00c;} |
||||
|
||||
.cm-s-default .cm-error {color: #f00;} |
||||
.cm-invalidchar {color: #f00;} |
||||
|
||||
.CodeMirror-composing { border-bottom: 2px solid; } |
||||
|
||||
/* Default styles for common addons */ |
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} |
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} |
||||
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } |
||||
.CodeMirror-activeline-background {background: #e8f2ff;} |
||||
|
||||
/* STOP */ |
||||
|
||||
/* The rest of this file contains styles related to the mechanics of |
||||
the editor. You probably shouldn't touch them. */ |
||||
|
||||
.CodeMirror { |
||||
position: relative; |
||||
overflow: hidden; |
||||
background: white; |
||||
} |
||||
|
||||
.CodeMirror-scroll { |
||||
overflow: scroll !important; /* Things will break if this is overridden */ |
||||
/* 30px is the magic margin used to hide the element's real scrollbars */ |
||||
/* See overflow: hidden in .CodeMirror */ |
||||
margin-bottom: -30px; margin-right: -30px; |
||||
padding-bottom: 30px; |
||||
/*height: 100%;*/ |
||||
outline: none; /* Prevent dragging from highlighting the element */ |
||||
position: relative; |
||||
} |
||||
.CodeMirror-sizer { |
||||
position: relative; |
||||
border-right: 30px solid transparent; |
||||
} |
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling |
||||
before actuall scrolling happens, thus preventing shaking and |
||||
flickering artifacts. */ |
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { |
||||
position: absolute; |
||||
z-index: 6; |
||||
display: none; |
||||
} |
||||
.CodeMirror-vscrollbar { |
||||
right: 0; top: 0; |
||||
overflow-x: hidden; |
||||
overflow-y: scroll; |
||||
} |
||||
.CodeMirror-hscrollbar { |
||||
bottom: 0; left: 0; |
||||
overflow-y: hidden; |
||||
overflow-x: scroll; |
||||
} |
||||
.CodeMirror-scrollbar-filler { |
||||
right: 0; bottom: 0; |
||||
} |
||||
.CodeMirror-gutter-filler { |
||||
left: 0; bottom: 0; |
||||
} |
||||
|
||||
.CodeMirror-gutters { |
||||
position: absolute; left: 0; top: 0; |
||||
z-index: 3; |
||||
} |
||||
.CodeMirror-gutter { |
||||
white-space: normal; |
||||
height: 100%; |
||||
display: inline-block; |
||||
margin-bottom: -30px; |
||||
/* Hack to make IE7 behave */ |
||||
*zoom:1; |
||||
*display:inline; |
||||
} |
||||
.CodeMirror-gutter-wrapper { |
||||
position: absolute; |
||||
z-index: 4; |
||||
height: 100%; |
||||
} |
||||
.CodeMirror-gutter-elt { |
||||
position: absolute; |
||||
cursor: default; |
||||
z-index: 4; |
||||
} |
||||
.CodeMirror-gutter-wrapper { |
||||
-webkit-user-select: none; |
||||
-moz-user-select: none; |
||||
user-select: none; |
||||
} |
||||
|
||||
.CodeMirror-lines { |
||||
cursor: text; |
||||
min-height: 1px; /* prevents collapsing before first draw */ |
||||
} |
||||
.CodeMirror pre { |
||||
/* Reset some styles that the rest of the page might have set */ |
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; |
||||
border-width: 0; |
||||
background: transparent; |
||||
font-family: inherit; |
||||
font-size: inherit; |
||||
margin: 0; |
||||
white-space: pre; |
||||
word-wrap: normal; |
||||
line-height: inherit; |
||||
color: inherit; |
||||
z-index: 2; |
||||
position: relative; |
||||
overflow: visible; |
||||
-webkit-tap-highlight-color: transparent; |
||||
} |
||||
.CodeMirror-wrap pre { |
||||
word-wrap: break-word; |
||||
white-space: pre-wrap; |
||||
word-break: normal; |
||||
} |
||||
|
||||
.CodeMirror-linebackground { |
||||
position: absolute; |
||||
left: 0; right: 0; top: 0; bottom: 0; |
||||
z-index: 0; |
||||
} |
||||
|
||||
.CodeMirror-linewidget { |
||||
position: relative; |
||||
z-index: 2; |
||||
overflow: auto; |
||||
} |
||||
|
||||
.CodeMirror-widget {} |
||||
|
||||
.CodeMirror-code { |
||||
outline: none; |
||||
} |
||||
|
||||
/* Force content-box sizing for the elements where we expect it */ |
||||
.CodeMirror-scroll, |
||||
.CodeMirror-sizer, |
||||
.CodeMirror-gutter, |
||||
.CodeMirror-gutters, |
||||
.CodeMirror-linenumber { |
||||
-moz-box-sizing: content-box; |
||||
box-sizing: content-box; |
||||
} |
||||
|
||||
.CodeMirror-measure { |
||||
position: absolute; |
||||
width: 100%; |
||||
height: 0; |
||||
overflow: hidden; |
||||
visibility: hidden; |
||||
} |
||||
.CodeMirror-measure pre { position: static; } |
||||
|
||||
.CodeMirror div.CodeMirror-cursor { |
||||
position: absolute; |
||||
border-right: none; |
||||
width: 0; |
||||
} |
||||
|
||||
div.CodeMirror-cursors { |
||||
visibility: hidden; |
||||
position: relative; |
||||
z-index: 3; |
||||
} |
||||
.CodeMirror-focused div.CodeMirror-cursors { |
||||
visibility: visible; |
||||
} |
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; } |
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } |
||||
.CodeMirror-crosshair { cursor: crosshair; } |
||||
.CodeMirror ::selection { background: #d7d4f0; } |
||||
.CodeMirror ::-moz-selection { background: #d7d4f0; } |
||||
|
||||
.cm-searching { |
||||
background: #ffa; |
||||
background: rgba(255, 255, 0, .4); |
||||
} |
||||
|
||||
/* IE7 hack to prevent it from returning funny offsetTops on the spans */ |
||||
.CodeMirror span { *vertical-align: text-bottom; } |
||||
|
||||
/* Used to force a border model for a node */ |
||||
.cm-force-border { padding-right: .1px; } |
||||
|
||||
@media print { |
||||
/* Hide the cursor when printing */ |
||||
.CodeMirror div.CodeMirror-cursors { |
||||
visibility: hidden; |
||||
} |
||||
} |
||||
|
||||
/* See issue #2901 */ |
||||
.cm-tab-wrap-hack:after { content: ''; } |
||||
|
||||
/* Help users use markselection to safely style text background */ |
||||
span.CodeMirror-selectedtext { background: none; } |
@ -0,0 +1,704 @@
@@ -0,0 +1,704 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// TODO actually recognize syntax of TypeScript constructs
|
||||
|
||||
(function(mod) { |
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror")); |
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod); |
||||
else // Plain browser env
|
||||
mod(CodeMirror); |
||||
})(function(CodeMirror) { |
||||
"use strict"; |
||||
|
||||
CodeMirror.defineMode("javascript", function(config, parserConfig) { |
||||
var indentUnit = config.indentUnit; |
||||
var statementIndent = parserConfig.statementIndent; |
||||
var jsonldMode = parserConfig.jsonld; |
||||
var jsonMode = parserConfig.json || jsonldMode; |
||||
var isTS = parserConfig.typescript; |
||||
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; |
||||
|
||||
// Tokenizer
|
||||
|
||||
var keywords = function(){ |
||||
function kw(type) {return {type: type, style: "keyword"};} |
||||
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); |
||||
var operator = kw("operator"), atom = {type: "atom", style: "atom"}; |
||||
|
||||
var jsKeywords = { |
||||
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, |
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C, |
||||
"var": kw("var"), "const": kw("var"), "let": kw("var"), |
||||
"function": kw("function"), "catch": kw("catch"), |
||||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), |
||||
"in": operator, "typeof": operator, "instanceof": operator, |
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, |
||||
"this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), |
||||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C |
||||
}; |
||||
|
||||
// Extend the 'normal' keywords with the TypeScript language extensions
|
||||
if (isTS) { |
||||
var type = {type: "variable", style: "variable-3"}; |
||||
var tsKeywords = { |
||||
// object-like things
|
||||
"interface": kw("interface"), |
||||
"extends": kw("extends"), |
||||
"constructor": kw("constructor"), |
||||
|
||||
// scope modifiers
|
||||
"public": kw("public"), |
||||
"private": kw("private"), |
||||
"protected": kw("protected"), |
||||
"static": kw("static"), |
||||
|
||||
// types
|
||||
"string": type, "number": type, "bool": type, "any": type |
||||
}; |
||||
|
||||
for (var attr in tsKeywords) { |
||||
jsKeywords[attr] = tsKeywords[attr]; |
||||
} |
||||
} |
||||
|
||||
return jsKeywords; |
||||
}(); |
||||
|
||||
var isOperatorChar = /[+\-*&%=<>!?|~^]/; |
||||
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; |
||||
|
||||
function readRegexp(stream) { |
||||
var escaped = false, next, inSet = false; |
||||
while ((next = stream.next()) != null) { |
||||
if (!escaped) { |
||||
if (next == "/" && !inSet) return; |
||||
if (next == "[") inSet = true; |
||||
else if (inSet && next == "]") inSet = false; |
||||
} |
||||
escaped = !escaped && next == "\\"; |
||||
} |
||||
} |
||||
|
||||
// Used as scratch variables to communicate multiple values without
|
||||
// consing up tons of objects.
|
||||
var type, content; |
||||
function ret(tp, style, cont) { |
||||
type = tp; content = cont; |
||||
return style; |
||||
} |
||||
function tokenBase(stream, state) { |
||||
var ch = stream.next(); |
||||
if (ch == '"' || ch == "'") { |
||||
state.tokenize = tokenString(ch); |
||||
return state.tokenize(stream, state); |
||||
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { |
||||
return ret("number", "number"); |
||||
} else if (ch == "." && stream.match("..")) { |
||||
return ret("spread", "meta"); |
||||
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { |
||||
return ret(ch); |
||||
} else if (ch == "=" && stream.eat(">")) { |
||||
return ret("=>", "operator"); |
||||
} else if (ch == "0" && stream.eat(/x/i)) { |
||||
stream.eatWhile(/[\da-f]/i); |
||||
return ret("number", "number"); |
||||
} else if (/\d/.test(ch)) { |
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); |
||||
return ret("number", "number"); |
||||
} else if (ch == "/") { |
||||
if (stream.eat("*")) { |
||||
state.tokenize = tokenComment; |
||||
return tokenComment(stream, state); |
||||
} else if (stream.eat("/")) { |
||||
stream.skipToEnd(); |
||||
return ret("comment", "comment"); |
||||
} else if (state.lastType == "operator" || state.lastType == "keyword c" || |
||||
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { |
||||
readRegexp(stream); |
||||
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); |
||||
return ret("regexp", "string-2"); |
||||
} else { |
||||
stream.eatWhile(isOperatorChar); |
||||
return ret("operator", "operator", stream.current()); |
||||
} |
||||
} else if (ch == "`") { |
||||
state.tokenize = tokenQuasi; |
||||
return tokenQuasi(stream, state); |
||||
} else if (ch == "#") { |
||||
stream.skipToEnd(); |
||||
return ret("error", "error"); |
||||
} else if (isOperatorChar.test(ch)) { |
||||
stream.eatWhile(isOperatorChar); |
||||
return ret("operator", "operator", stream.current()); |
||||
} else if (wordRE.test(ch)) { |
||||
stream.eatWhile(wordRE); |
||||
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; |
||||
return (known && state.lastType != ".") ? ret(known.type, known.style, word) : |
||||
ret("variable", "variable", word); |
||||
} |
||||
} |
||||
|
||||
function tokenString(quote) { |
||||
return function(stream, state) { |
||||
var escaped = false, next; |
||||
if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ |
||||
state.tokenize = tokenBase; |
||||
return ret("jsonld-keyword", "meta"); |
||||
} |
||||
while ((next = stream.next()) != null) { |
||||
if (next == quote && !escaped) break; |
||||
escaped = !escaped && next == "\\"; |
||||
} |
||||
if (!escaped) state.tokenize = tokenBase; |
||||
return ret("string", "string"); |
||||
}; |
||||
} |
||||
|
||||
function tokenComment(stream, state) { |
||||
var maybeEnd = false, ch; |
||||
while (ch = stream.next()) { |
||||
if (ch == "/" && maybeEnd) { |
||||
state.tokenize = tokenBase; |
||||
break; |
||||
} |
||||
maybeEnd = (ch == "*"); |
||||
} |
||||
return ret("comment", "comment"); |
||||
} |
||||
|
||||
function tokenQuasi(stream, state) { |
||||
var escaped = false, next; |
||||
while ((next = stream.next()) != null) { |
||||
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { |
||||
state.tokenize = tokenBase; |
||||
break; |
||||
} |
||||
escaped = !escaped && next == "\\"; |
||||
} |
||||
return ret("quasi", "string-2", stream.current()); |
||||
} |
||||
|
||||
var brackets = "([{}])"; |
||||
// This is a crude lookahead trick to try and notice that we're
|
||||
// parsing the argument patterns for a fat-arrow function before we
|
||||
// actually hit the arrow token. It only works if the arrow is on
|
||||
// the same line as the arguments and there's no strange noise
|
||||
// (comments) in between. Fallback is to only notice when we hit the
|
||||
// arrow, and not declare the arguments as locals for the arrow
|
||||
// body.
|
||||
function findFatArrow(stream, state) { |
||||
if (state.fatArrowAt) state.fatArrowAt = null; |
||||
var arrow = stream.string.indexOf("=>", stream.start); |
||||
if (arrow < 0) return; |
||||
|
||||
var depth = 0, sawSomething = false; |
||||
for (var pos = arrow - 1; pos >= 0; --pos) { |
||||
var ch = stream.string.charAt(pos); |
||||
var bracket = brackets.indexOf(ch); |
||||
if (bracket >= 0 && bracket < 3) { |
||||
if (!depth) { ++pos; break; } |
||||
if (--depth == 0) break; |
||||
} else if (bracket >= 3 && bracket < 6) { |
||||
++depth; |
||||
} else if (wordRE.test(ch)) { |
||||
sawSomething = true; |
||||
} else if (/["'\/]/.test(ch)) { |
||||
return; |
||||
} else if (sawSomething && !depth) { |
||||
++pos; |
||||
break; |
||||
} |
||||
} |
||||
if (sawSomething && !depth) state.fatArrowAt = pos; |
||||
} |
||||
|
||||
// Parser
|
||||
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; |
||||
|
||||
function JSLexical(indented, column, type, align, prev, info) { |
||||
this.indented = indented; |
||||
this.column = column; |
||||
this.type = type; |
||||
this.prev = prev; |
||||
this.info = info; |
||||
if (align != null) this.align = align; |
||||
} |
||||
|
||||
function inScope(state, varname) { |
||||
for (var v = state.localVars; v; v = v.next) |
||||
if (v.name == varname) return true; |
||||
for (var cx = state.context; cx; cx = cx.prev) { |
||||
for (var v = cx.vars; v; v = v.next) |
||||
if (v.name == varname) return true; |
||||
} |
||||
} |
||||
|
||||
function parseJS(state, style, type, content, stream) { |
||||
var cc = state.cc; |
||||
// Communicate our context to the combinators.
|
||||
// (Less wasteful than consing up a hundred closures on every call.)
|
||||
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; |
||||
|
||||
if (!state.lexical.hasOwnProperty("align")) |
||||
state.lexical.align = true; |
||||
|
||||
while(true) { |
||||
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; |
||||
if (combinator(type, content)) { |
||||
while(cc.length && cc[cc.length - 1].lex) |
||||
cc.pop()(); |
||||
if (cx.marked) return cx.marked; |
||||
if (type == "variable" && inScope(state, content)) return "variable-2"; |
||||
return style; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Combinator utils
|
||||
|
||||
var cx = {state: null, column: null, marked: null, cc: null}; |
||||
function pass() { |
||||
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); |
||||
} |
||||
function cont() { |
||||
pass.apply(null, arguments); |
||||
return true; |
||||
} |
||||
function register(varname) { |
||||
function inList(list) { |
||||
for (var v = list; v; v = v.next) |
||||
if (v.name == varname) return true; |
||||
return false; |
||||
} |
||||
var state = cx.state; |
||||
if (state.context) { |
||||
cx.marked = "def"; |
||||
if (inList(state.localVars)) return; |
||||
state.localVars = {name: varname, next: state.localVars}; |
||||
} else { |
||||
if (inList(state.globalVars)) return; |
||||
if (parserConfig.globalVars) |
||||
state.globalVars = {name: varname, next: state.globalVars}; |
||||
} |
||||
} |
||||
|
||||
// Combinators
|
||||
|
||||
var defaultVars = {name: "this", next: {name: "arguments"}}; |
||||
function pushcontext() { |
||||
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; |
||||
cx.state.localVars = defaultVars; |
||||
} |
||||
function popcontext() { |
||||
cx.state.localVars = cx.state.context.vars; |
||||
cx.state.context = cx.state.context.prev; |
||||
} |
||||
function pushlex(type, info) { |
||||
var result = function() { |
||||
var state = cx.state, indent = state.indented; |
||||
if (state.lexical.type == "stat") indent = state.lexical.indented; |
||||
else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev) |
||||
indent = outer.indented; |
||||
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); |
||||
}; |
||||
result.lex = true; |
||||
return result; |
||||
} |
||||
function poplex() { |
||||
var state = cx.state; |
||||
if (state.lexical.prev) { |
||||
if (state.lexical.type == ")") |
||||
state.indented = state.lexical.indented; |
||||
state.lexical = state.lexical.prev; |
||||
} |
||||
} |
||||
poplex.lex = true; |
||||
|
||||
function expect(wanted) { |
||||
function exp(type) { |
||||
if (type == wanted) return cont(); |
||||
else if (wanted == ";") return pass(); |
||||
else return cont(exp); |
||||
}; |
||||
return exp; |
||||
} |
||||
|
||||
function statement(type, value) { |
||||
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); |
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); |
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex); |
||||
if (type == "{") return cont(pushlex("}"), block, poplex); |
||||
if (type == ";") return cont(); |
||||
if (type == "if") { |
||||
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) |
||||
cx.state.cc.pop()(); |
||||
return cont(pushlex("form"), expression, statement, poplex, maybeelse); |
||||
} |
||||
if (type == "function") return cont(functiondef); |
||||
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); |
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel); |
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), |
||||
block, poplex, poplex); |
||||
if (type == "case") return cont(expression, expect(":")); |
||||
if (type == "default") return cont(expect(":")); |
||||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), |
||||
statement, poplex, popcontext); |
||||
if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); |
||||
if (type == "class") return cont(pushlex("form"), className, poplex); |
||||
if (type == "export") return cont(pushlex("form"), afterExport, poplex); |
||||
if (type == "import") return cont(pushlex("form"), afterImport, poplex); |
||||
return pass(pushlex("stat"), expression, expect(";"), poplex); |
||||
} |
||||
function expression(type) { |
||||
return expressionInner(type, false); |
||||
} |
||||
function expressionNoComma(type) { |
||||
return expressionInner(type, true); |
||||
} |
||||
function expressionInner(type, noComma) { |
||||
if (cx.state.fatArrowAt == cx.stream.start) { |
||||
var body = noComma ? arrowBodyNoComma : arrowBody; |
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); |
||||
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); |
||||
} |
||||
|
||||
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; |
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); |
||||
if (type == "function") return cont(functiondef, maybeop); |
||||
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); |
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); |
||||
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); |
||||
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); |
||||
if (type == "{") return contCommasep(objprop, "}", null, maybeop); |
||||
if (type == "quasi") { return pass(quasi, maybeop); } |
||||
return cont(); |
||||
} |
||||
function maybeexpression(type) { |
||||
if (type.match(/[;\}\)\],]/)) return pass(); |
||||
return pass(expression); |
||||
} |
||||
function maybeexpressionNoComma(type) { |
||||
if (type.match(/[;\}\)\],]/)) return pass(); |
||||
return pass(expressionNoComma); |
||||
} |
||||
|
||||
function maybeoperatorComma(type, value) { |
||||
if (type == ",") return cont(expression); |
||||
return maybeoperatorNoComma(type, value, false); |
||||
} |
||||
function maybeoperatorNoComma(type, value, noComma) { |
||||
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; |
||||
var expr = noComma == false ? expression : expressionNoComma; |
||||
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); |
||||
if (type == "operator") { |
||||
if (/\+\+|--/.test(value)) return cont(me); |
||||
if (value == "?") return cont(expression, expect(":"), expr); |
||||
return cont(expr); |
||||
} |
||||
if (type == "quasi") { return pass(quasi, me); } |
||||
if (type == ";") return; |
||||
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); |
||||
if (type == ".") return cont(property, me); |
||||
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); |
||||
} |
||||
function quasi(type, value) { |
||||
if (type != "quasi") return pass(); |
||||
if (value.slice(value.length - 2) != "${") return cont(quasi); |
||||
return cont(expression, continueQuasi); |
||||
} |
||||
function continueQuasi(type) { |
||||
if (type == "}") { |
||||
cx.marked = "string-2"; |
||||
cx.state.tokenize = tokenQuasi; |
||||
return cont(quasi); |
||||
} |
||||
} |
||||
function arrowBody(type) { |
||||
findFatArrow(cx.stream, cx.state); |
||||
return pass(type == "{" ? statement : expression); |
||||
} |
||||
function arrowBodyNoComma(type) { |
||||
findFatArrow(cx.stream, cx.state); |
||||
return pass(type == "{" ? statement : expressionNoComma); |
||||
} |
||||
function maybelabel(type) { |
||||
if (type == ":") return cont(poplex, statement); |
||||
return pass(maybeoperatorComma, expect(";"), poplex); |
||||
} |
||||
function property(type) { |
||||
if (type == "variable") {cx.marked = "property"; return cont();} |
||||
} |
||||
function objprop(type, value) { |
||||
if (type == "variable" || cx.style == "keyword") { |
||||
cx.marked = "property"; |
||||
if (value == "get" || value == "set") return cont(getterSetter); |
||||
return cont(afterprop); |
||||
} else if (type == "number" || type == "string") { |
||||
cx.marked = jsonldMode ? "property" : (cx.style + " property"); |
||||
return cont(afterprop); |
||||
} else if (type == "jsonld-keyword") { |
||||
return cont(afterprop); |
||||
} else if (type == "[") { |
||||
return cont(expression, expect("]"), afterprop); |
||||
} |
||||
} |
||||
function getterSetter(type) { |
||||
if (type != "variable") return pass(afterprop); |
||||
cx.marked = "property"; |
||||
return cont(functiondef); |
||||
} |
||||
function afterprop(type) { |
||||
if (type == ":") return cont(expressionNoComma); |
||||
if (type == "(") return pass(functiondef); |
||||
} |
||||
function commasep(what, end) { |
||||
function proceed(type) { |
||||
if (type == ",") { |
||||
var lex = cx.state.lexical; |
||||
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; |
||||
return cont(what, proceed); |
||||
} |
||||
if (type == end) return cont(); |
||||
return cont(expect(end)); |
||||
} |
||||
return function(type) { |
||||
if (type == end) return cont(); |
||||
return pass(what, proceed); |
||||
}; |
||||
} |
||||
function contCommasep(what, end, info) { |
||||
for (var i = 3; i < arguments.length; i++) |
||||
cx.cc.push(arguments[i]); |
||||
return cont(pushlex(end, info), commasep(what, end), poplex); |
||||
} |
||||
function block(type) { |
||||
if (type == "}") return cont(); |
||||
return pass(statement, block); |
||||
} |
||||
function maybetype(type) { |
||||
if (isTS && type == ":") return cont(typedef); |
||||
} |
||||
function maybedefault(_, value) { |
||||
if (value == "=") return cont(expressionNoComma); |
||||
} |
||||
function typedef(type) { |
||||
if (type == "variable") {cx.marked = "variable-3"; return cont();} |
||||
} |
||||
function vardef() { |
||||
return pass(pattern, maybetype, maybeAssign, vardefCont); |
||||
} |
||||
function pattern(type, value) { |
||||
if (type == "variable") { register(value); return cont(); } |
||||
if (type == "[") return contCommasep(pattern, "]"); |
||||
if (type == "{") return contCommasep(proppattern, "}"); |
||||
} |
||||
function proppattern(type, value) { |
||||
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { |
||||
register(value); |
||||
return cont(maybeAssign); |
||||
} |
||||
if (type == "variable") cx.marked = "property"; |
||||
return cont(expect(":"), pattern, maybeAssign); |
||||
} |
||||
function maybeAssign(_type, value) { |
||||
if (value == "=") return cont(expressionNoComma); |
||||
} |
||||
function vardefCont(type) { |
||||
if (type == ",") return cont(vardef); |
||||
} |
||||
function maybeelse(type, value) { |
||||
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); |
||||
} |
||||
function forspec(type) { |
||||
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); |
||||
} |
||||
function forspec1(type) { |
||||
if (type == "var") return cont(vardef, expect(";"), forspec2); |
||||
if (type == ";") return cont(forspec2); |
||||
if (type == "variable") return cont(formaybeinof); |
||||
return pass(expression, expect(";"), forspec2); |
||||
} |
||||
function formaybeinof(_type, value) { |
||||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } |
||||
return cont(maybeoperatorComma, forspec2); |
||||
} |
||||
function forspec2(type, value) { |
||||
if (type == ";") return cont(forspec3); |
||||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } |
||||
return pass(expression, expect(";"), forspec3); |
||||
} |
||||
function forspec3(type) { |
||||
if (type != ")") cont(expression); |
||||
} |
||||
function functiondef(type, value) { |
||||
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} |
||||
if (type == "variable") {register(value); return cont(functiondef);} |
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext); |
||||
} |
||||
function funarg(type) { |
||||
if (type == "spread") return cont(funarg); |
||||
return pass(pattern, maybetype, maybedefault); |
||||
} |
||||
function className(type, value) { |
||||
if (type == "variable") {register(value); return cont(classNameAfter);} |
||||
} |
||||
function classNameAfter(type, value) { |
||||
if (value == "extends") return cont(expression, classNameAfter); |
||||
if (type == "{") return cont(pushlex("}"), classBody, poplex); |
||||
} |
||||
function classBody(type, value) { |
||||
if (type == "variable" || cx.style == "keyword") { |
||||
if (value == "static") { |
||||
cx.marked = "keyword"; |
||||
return cont(classBody); |
||||
} |
||||
cx.marked = "property"; |
||||
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); |
||||
return cont(functiondef, classBody); |
||||
} |
||||
if (value == "*") { |
||||
cx.marked = "keyword"; |
||||
return cont(classBody); |
||||
} |
||||
if (type == ";") return cont(classBody); |
||||
if (type == "}") return cont(); |
||||
} |
||||
function classGetterSetter(type) { |
||||
if (type != "variable") return pass(); |
||||
cx.marked = "property"; |
||||
return cont(); |
||||
} |
||||
function afterModule(type, value) { |
||||
if (type == "string") return cont(statement); |
||||
if (type == "variable") { register(value); return cont(maybeFrom); } |
||||
} |
||||
function afterExport(_type, value) { |
||||
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } |
||||
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } |
||||
return pass(statement); |
||||
} |
||||
function afterImport(type) { |
||||
if (type == "string") return cont(); |
||||
return pass(importSpec, maybeFrom); |
||||
} |
||||
function importSpec(type, value) { |
||||
if (type == "{") return contCommasep(importSpec, "}"); |
||||
if (type == "variable") register(value); |
||||
if (value == "*") cx.marked = "keyword"; |
||||
return cont(maybeAs); |
||||
} |
||||
function maybeAs(_type, value) { |
||||
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } |
||||
} |
||||
function maybeFrom(_type, value) { |
||||
if (value == "from") { cx.marked = "keyword"; return cont(expression); } |
||||
} |
||||
function arrayLiteral(type) { |
||||
if (type == "]") return cont(); |
||||
return pass(expressionNoComma, maybeArrayComprehension); |
||||
} |
||||
function maybeArrayComprehension(type) { |
||||
if (type == "for") return pass(comprehension, expect("]")); |
||||
if (type == ",") return cont(commasep(maybeexpressionNoComma, "]")); |
||||
return pass(commasep(expressionNoComma, "]")); |
||||
} |
||||
function comprehension(type) { |
||||
if (type == "for") return cont(forspec, comprehension); |
||||
if (type == "if") return cont(expression, comprehension); |
||||
} |
||||
|
||||
function isContinuedStatement(state, textAfter) { |
||||
return state.lastType == "operator" || state.lastType == "," || |
||||
isOperatorChar.test(textAfter.charAt(0)) || |
||||
/[,.]/.test(textAfter.charAt(0)); |
||||
} |
||||
|
||||
// Interface
|
||||
|
||||
return { |
||||
startState: function(basecolumn) { |
||||
var state = { |
||||
tokenize: tokenBase, |
||||
lastType: "sof", |
||||
cc: [], |
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), |
||||
localVars: parserConfig.localVars, |
||||
context: parserConfig.localVars && {vars: parserConfig.localVars}, |
||||
indented: 0 |
||||
}; |
||||
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") |
||||
state.globalVars = parserConfig.globalVars; |
||||
return state; |
||||
}, |
||||
|
||||
token: function(stream, state) { |
||||
if (stream.sol()) { |
||||
if (!state.lexical.hasOwnProperty("align")) |
||||
state.lexical.align = false; |
||||
state.indented = stream.indentation(); |
||||
findFatArrow(stream, state); |
||||
} |
||||
if (state.tokenize != tokenComment && stream.eatSpace()) return null; |
||||
var style = state.tokenize(stream, state); |
||||
if (type == "comment") return style; |
||||
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; |
||||
return parseJS(state, style, type, content, stream); |
||||
}, |
||||
|
||||
indent: function(state, textAfter) { |
||||
if (state.tokenize == tokenComment) return CodeMirror.Pass; |
||||
if (state.tokenize != tokenBase) return 0; |
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; |
||||
// Kludge to prevent 'maybelse' from blocking lexical scope pops
|
||||
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { |
||||
var c = state.cc[i]; |
||||
if (c == poplex) lexical = lexical.prev; |
||||
else if (c != maybeelse) break; |
||||
} |
||||
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; |
||||
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") |
||||
lexical = lexical.prev; |
||||
var type = lexical.type, closing = firstChar == type; |
||||
|
||||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); |
||||
else if (type == "form" && firstChar == "{") return lexical.indented; |
||||
else if (type == "form") return lexical.indented + indentUnit; |
||||
else if (type == "stat") |
||||
return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0); |
||||
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) |
||||
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); |
||||
else if (lexical.align) return lexical.column + (closing ? 0 : 1); |
||||
else return lexical.indented + (closing ? 0 : indentUnit); |
||||
}, |
||||
|
||||
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, |
||||
blockCommentStart: jsonMode ? null : "/*", |
||||
blockCommentEnd: jsonMode ? null : "*/", |
||||
lineComment: jsonMode ? null : "//", |
||||
fold: "brace", |
||||
closeBrackets: "()[]{}''\"\"``", |
||||
|
||||
helperType: jsonMode ? "json" : "javascript", |
||||
jsonldMode: jsonldMode, |
||||
jsonMode: jsonMode |
||||
}; |
||||
}); |
||||
|
||||
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/); |
||||
|
||||
CodeMirror.defineMIME("text/javascript", "javascript"); |
||||
CodeMirror.defineMIME("text/ecmascript", "javascript"); |
||||
CodeMirror.defineMIME("application/javascript", "javascript"); |
||||
CodeMirror.defineMIME("application/x-javascript", "javascript"); |
||||
CodeMirror.defineMIME("application/ecmascript", "javascript"); |
||||
CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); |
||||
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); |
||||
CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); |
||||
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); |
||||
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); |
||||
|
||||
}); |
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
browserify worker_src/worker.js -o worker/wumbo.js |
||||
cat worker_src/madeline.js worker/wumbo.js > worker/worker.js |
||||
rm worker/wumbo.js |
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
#wow { |
||||
box-shadow: 0px 0px 20px 0px rgba(0,0,0,.2); |
||||
background-color: #fff; |
||||
} |
||||
|
||||
#splash { |
||||
border-bottom: solid 1px #ddd; |
||||
/*background-color: #222*/ |
||||
} |
||||
|
||||
#desc { |
||||
color: #444; |
||||
} |
||||
|
||||
.header { |
||||
background-color: #27C6F9; |
||||
} |
||||
|
||||
#marterial { |
||||
background: linear-gradient(#27C6F9 80%, #0CB5EB 100%); |
||||
} |
||||
|
||||
#runbutton { |
||||
color: #27C6F9; |
||||
cursor: pointer; |
||||
-webkit-transition: all 0.7s ease; |
||||
transition: all 0.7s ease; |
||||
} |
||||
|
||||
#runbutton:hover { |
||||
text-shadow: 0px 0px 10px #27C6F9; |
||||
} |
||||
|
||||
#wow { |
||||
box-shadow: 0px 0px 20px -2px rgba(0,0,0,.2); |
||||
} |
||||
|
||||
#hint { |
||||
font-size: 10px; |
||||
color: #aaa; |
||||
|
||||
} |
||||
|
||||
|
||||
a { |
||||
color: #f90; |
||||
} |
||||
|
||||
button { |
||||
color: #000; |
||||
background: #fff; |
||||
border-radius: 5px; |
||||
border: solid 1px #fff; |
||||
} |
||||
|
||||
button:hover { |
||||
background: rgba(255,255,255,1); |
||||
border: solid 1px #ddd; |
||||
} |
||||
|
||||
@media (max-width: 914px) { |
||||
button{ |
||||
color: #fff; |
||||
background-color: rgba(0,0,0,0) |
||||
} |
||||
|
||||
button:hover { |
||||
background: rgba(255,255,255,.3); |
||||
border: solid 1px #fff; |
||||
} |
||||
|
||||
#desc { |
||||
color: rgba(255,255,255,.9); |
||||
} |
||||
|
||||
#splash { |
||||
background-color: #27C6F9; |
||||
} |
||||
} |
@ -0,0 +1,210 @@
@@ -0,0 +1,210 @@
|
||||
.fullscreen { |
||||
width:100%; |
||||
min-height: 100%; |
||||
} |
||||
|
||||
#runwrap { |
||||
position: relative; |
||||
right:0px; |
||||
width: 100%; |
||||
height: 0px; |
||||
text-align: right; |
||||
background: green; |
||||
z-index: 2; |
||||
|
||||
} |
||||
|
||||
#run, #running { |
||||
width: 100%; |
||||
height: 42px; |
||||
text-align: center; |
||||
} |
||||
|
||||
#run { |
||||
display: none |
||||
} |
||||
|
||||
#runbutton { |
||||
padding-top: 6px; |
||||
padding-bottom: 10px; |
||||
font-weight: 500; |
||||
|
||||
} |
||||
|
||||
a { |
||||
text-decoration: none; |
||||
/*font-weight: bold;*/ |
||||
} |
||||
|
||||
#display { |
||||
position: absolute; |
||||
/*background: rgba(0,0,255,.1);*/ |
||||
} |
||||
|
||||
#marterial { |
||||
position: absolute; |
||||
width: 100%; |
||||
height: 90px; |
||||
z-index: -1; |
||||
} |
||||
|
||||
#out { |
||||
padding: 10px; |
||||
padding-bottom: 0px; |
||||
text-align: center; |
||||
font-family: monospace; |
||||
} |
||||
|
||||
#hint { |
||||
text-align: left; |
||||
padding-left: 14px |
||||
|
||||
} |
||||
|
||||
#prog { |
||||
width: 400px; |
||||
max-width: 100%; |
||||
position: relative; |
||||
} |
||||
|
||||
#drag { |
||||
padding: 10px; |
||||
/*padding-top: 0px;*/ |
||||
text-align: center |
||||
} |
||||
|
||||
#logo { |
||||
text-align: center; |
||||
padding-top: 5%; |
||||
} |
||||
|
||||
#to_ocr { |
||||
width: 100%; |
||||
} |
||||
|
||||
#wow { |
||||
border-radius: 5px; |
||||
overflow: hidden; |
||||
width:500px; |
||||
margin-top: 10px; |
||||
text-align: left |
||||
} |
||||
|
||||
#canvas { |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
pointer-events:none; |
||||
z-index: 0; |
||||
background-image: url(../img/logowhite.png); |
||||
background-size: cover; |
||||
} |
||||
|
||||
#splash { |
||||
text-align: center; |
||||
} |
||||
|
||||
#desc { |
||||
text-align: left; |
||||
font-size: 18px; |
||||
} |
||||
|
||||
#demo { |
||||
} |
||||
|
||||
#notconvinced { |
||||
max-width: 960; |
||||
|
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
margin-top: 8%; |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
.randombold { |
||||
font-size: 18px; |
||||
/*font-family: Georgia;*/ |
||||
letter-spacing: .8px; |
||||
line-height: 37px; |
||||
} |
||||
|
||||
.rant { |
||||
padding-left: 8%; |
||||
padding-right: 8%; |
||||
} |
||||
/*#editor { |
||||
border-radius: 5px 5px 0px 0px; |
||||
} |
||||
*/ |
||||
#code { |
||||
text-align: center; |
||||
width: 335px; |
||||
border-radius: 5px; |
||||
margin-right: 40px; |
||||
margin-left: 40px; |
||||
margin-top: 140px; |
||||
|
||||
} |
||||
|
||||
#fork { |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
border: 0; |
||||
width: 149px; |
||||
} |
||||
|
||||
|
||||
|
||||
#two { |
||||
width: 100%; |
||||
paddin-left: 8%; |
||||
paddin-right: 8%; |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
justify-content: center; |
||||
margin-bottom: 8%; |
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
body { |
||||
padding: 0px; |
||||
margin: 0px; |
||||
font-family: Lato;/*, Helvetica, Arial, sans-serif;*/ |
||||
font-weight: 300; |
||||
|
||||
} |
||||
|
||||
button { |
||||
|
||||
height: 60px; |
||||
width: 240px; |
||||
|
||||
margin-top: 10px; |
||||
|
||||
font: inherit; |
||||
font-size: 30px; |
||||
|
||||
-webkit-transition: all 0.7s ease; |
||||
transition: all 0.7s ease; |
||||
|
||||
outline: 0; |
||||
} |
||||
|
||||
button:hover { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
@media (max-width: 914px) { |
||||
#marterial { |
||||
height: 300px; |
||||
} |
||||
|
||||
#code { |
||||
margin-top: 20px; |
||||
margin-bottom: 20px |
||||
} |
||||
} |
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
<canvas id="c"></canvas> |
||||
<script type="text/javascript" src="./lib/Tesseract.js"></script> |
||||
<script type="text/javascript"> |
||||
var canvas = document.getElementById('c') |
||||
canvas.width = 400 |
||||
canvas.height = 400 |
||||
var ctx = canvas.getContext('2d'); |
||||
ctx.font = '30px "Arial Black"' |
||||
ctx.fillText('Hell0 World', 100, 40) |
||||
// ctx.fillText("囚犯離奇掙脫囚犯離奇掙脫", 100, 40) |
||||
ctx.font = '30px "Times New Roman"' |
||||
ctx.fillText('from beyond', 100, 80) |
||||
// ctx.fillText('2小時可換乘2次2小時可換乘2次', 100, 80) |
||||
ctx.font = '30px sans-serif' |
||||
ctx.fillText('the Cosmic Void', 100, 120) |
||||
|
||||
Tesseract.recognize(canvas,{ |
||||
tessedit_char_blacklist:'e', |
||||
progress: function(e){ |
||||
console.log(e) |
||||
} |
||||
}).then( function(d){ console.log(d) } ) |
||||
|
||||
</script> |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 953 KiB |
After Width: | Height: | Size: 357 KiB |
@ -0,0 +1,208 @@
@@ -0,0 +1,208 @@
|
||||
<html> |
||||
<head> |
||||
<title>Wau Demo</title> |
||||
<link rel="stylesheet" type="text/css" href="./css/wau.css"> |
||||
<link rel="stylesheet" type="text/css" href="./css/color.css"> |
||||
|
||||
<script src="codemirror/codemirror.js"></script> |
||||
<link rel="stylesheet" href="codemirror/codemirror.css"> |
||||
<script src="codemirror/javascript.js"></script> |
||||
|
||||
|
||||
<link href='http://fonts.googleapis.com/css?family=Lato:300,400' rel='stylesheet' type='text/css'> |
||||
|
||||
</head> |
||||
<body> |
||||
<!-- <a href="https://github.com/you"><img id="fork" src="img/fork.png" alt="Fork me on GitHub"></a> --> |
||||
|
||||
<div id="splash" class="fullscreen"> |
||||
<div id="logo" class="header"> |
||||
<canvas id="canvas"></canvas> |
||||
</div> |
||||
|
||||
<div id ="marterial" class="header"></div> |
||||
|
||||
<div id="two"> |
||||
<div id="code"> |
||||
<div id="desc"> |
||||
Tesseract.js is a <b>pure javascript</b> version of the <a href="https://github.com/tesseract-ocr/Tesseract">Tesseract OCR Engine</a>. It can recognize <b>over 20 languages</b>, including <b>English</b>, <b>Chinese</b>, and <b>Meme</b>. |
||||
</div> |
||||
<br> |
||||
<button>Download</button><br> |
||||
<a href="https://github.com/naptha/tesseract.js"><button>View on Github</button></a> |
||||
</div> |
||||
<div id="wow"> |
||||
|
||||
<div id='editor'></div> |
||||
<div id="hint"> |
||||
Hint: you can, like, edit this code yo |
||||
</div> |
||||
<div id ="running"> |
||||
<div id="out">Initializing Magic...</div> |
||||
<progress id="prog" value="0" max="1"></progress> |
||||
</div> |
||||
<div id = "run"> |
||||
|
||||
<div id="runbutton">Run Code</div> |
||||
</div> |
||||
<canvas id="display"></canvas> |
||||
<img src="img/poem.png" width = "500px" id ="to_ocr"> |
||||
<div id="drag"> |
||||
<a href="">New Image</a> (or drop an image on this page) |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
<div id="notconvinced" class="fullscreen"> |
||||
<div class="rant randombold"> |
||||
"Last time I got here, before I <b>even</b> arrived, they had ‘fuck <b>Kanye’</b> on the motherfuckin’ <b>port-a-potties.</b> But this year, we gon’ piss on ‘em, on they motherfuckin’ port-a-potties. How many of <b>y'all</b> don't give a fuck about <b>what</b> the press <b>say?</b> It's 2014. College Dropout came out 2004. I want y'all to know, <b>every</b> time I go to the studio, every time I <b>do</b> <b>an</b> <b>interview,</b> every time I make a motherfuckin' <b>t-shirt,</b> the thing <b>I</b> do, I give it <b>everything</b> <b>I</b> got. And when I talk that shit, it's so that <b>you</b> can talk that shit. If you a fan of me, you a fan of your motherfuckin' self. You can do something that'll change the world. Look at how they try to make me look. They <b>try</b> to make me look crazy.", |
||||
<b></b> "I <b>need</b> a new cool. <b>What's</b> the new shit out? What's the new shit <b>out</b> <b>with</b> the most commercials at the Super Bowl? <b>Let's</b> <b>just</b> stop the music and play a Bruno Mars song right <b>now,</b> how about that? <b>They</b> told me I would never play at the Super Bowl. They told me I could never play at the Super Bowl. Not until I'm <b>super</b> old. Not until I'm <b>super</b> old... They told me I would never play at the <b>Super</b> Bowl. They told <b>me</b> I would never play at the <b>Super</b> <b>Bowl,</b> at least not until I'm super old. So I think it's time–hold up, f—k that toast.", |
||||
<b></b> "I know people get mad at me when I compare myself, but that's the only way I <b>can</b> explain what <b>my</b> aspirations are. When I'm talkin' 'bout Walt Disney, when I'm talkin' 'bout Howard Hughes, when I'm talkin' 'bout Henry Ford, when I'm talkin' 'bout Beethoven, when I talk about <b>Mozart,</b> when I talk about Shakespeare, and they all had their time on this earth. And I'm only 37. And right now I'm rockin' to 90,000, of y'all motherfuckers <b>right</b> now. So I ain't goin' at anybody on the radio. I'm goin' <b>after</b> Shakespeare. I'm <b>goin'</b> after <b>Walt</b> Disney. I'm <b>going</b> after <b>Howard</b> Hughes. I'm going after David Stern. I'm goin' <b>after</b> Henry Ford. I'm going <b>after</b> Elon Musk. Okay, he is living, but he's my boy.", |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
<!-- |
||||
<script src="./core/temple.js"></script> |
||||
|
||||
--> |
||||
<script src="https://rawgit.com/naptha/tesseract.js/master/lib/Tesseract.js"></script> |
||||
|
||||
<script> |
||||
var prog = document.getElementById('prog') |
||||
var out = document.getElementById('out') |
||||
|
||||
var disp = document.getElementById('display') |
||||
var dctx = disp.getContext('2d') |
||||
disp.width = 0 |
||||
disp.height = 0 |
||||
|
||||
document.getElementById('runbutton').onclick = function(){ |
||||
setrunning(0) |
||||
run(myCodeMirror) |
||||
} |
||||
|
||||
function show_progress(p){ |
||||
|
||||
if(p.loaded_lang_model) prog.value = p.loaded_lang_model |
||||
if(p.recognized) prog.value = p.recognized |
||||
setrunning(p.recognized) |
||||
out.innerText = JSON.stringify(p) |
||||
|
||||
} |
||||
|
||||
function setrunning(v){ |
||||
if (v == 1) { |
||||
document.getElementById('running').style.display = 'none' |
||||
document.getElementById('run').style.display = 'block' |
||||
// out.style.visibility = 'hidden' |
||||
} |
||||
else { |
||||
document.getElementById('running').style.display = 'block' |
||||
document.getElementById('run').style.display = 'none' |
||||
} |
||||
} |
||||
|
||||
function display(result) { |
||||
console.log(result) |
||||
|
||||
disp.width = document.getElementById('to_ocr').naturalWidth |
||||
disp.height = document.getElementById('to_ocr').naturalHeight |
||||
|
||||
disp.style.width = document.getElementById('to_ocr').offsetWidth |
||||
disp.style.height = document.getElementById('to_ocr').offsetHeight |
||||
|
||||
|
||||
dctx.shadowColor = "#fff" |
||||
dctx.shadowOffsetX = 0; |
||||
dctx.shadowOffsetY = 0; |
||||
dctx.shadowBlur = 10; |
||||
|
||||
var m = result.words.map(function(w){ |
||||
|
||||
var b = w.bbox |
||||
|
||||
var k = (function(){ |
||||
|
||||
dctx.font = '20px Comic Sans MS' |
||||
dctx.font = 20*(b.x1-b.x0)/dctx.measureText(w.text).width+"px Comic Sans MS" |
||||
|
||||
// dctx.fillStyle="rgba(255,255,255,.01)" |
||||
// dctx.fillRect(b.x0,b.y0,b.x1-b.x0, b.y1-b.y0) |
||||
dctx.fillStyle="rgba(255,0,255,.1)" |
||||
dctx.fillText(w.text, b.x0, w.baseline.y0); |
||||
|
||||
// dctx.strokeStyle = "rgba(255,255,255,.1)" |
||||
// dctx.strokeText(w.text, b.x0, w.baseline.y0); |
||||
}) |
||||
|
||||
// k() |
||||
return k |
||||
}) |
||||
|
||||
var times = 0 |
||||
function draw(i){ |
||||
times++ |
||||
for (var j = 0; j < i; j++) { |
||||
m[j]() |
||||
}; |
||||
if(times<200){ |
||||
setTimeout(function(){ |
||||
if(i+1<m.length){ |
||||
draw(i+1) |
||||
} |
||||
else { |
||||
draw(i) |
||||
} |
||||
},10) |
||||
} |
||||
else{ |
||||
console.log('done') |
||||
} |
||||
} |
||||
draw(0) |
||||
|
||||
} |
||||
|
||||
window.onresize = function() { |
||||
disp.style.width = document.getElementById('to_ocr').offsetWidth |
||||
disp.style.height = document.getElementById('to_ocr').offsetHeight |
||||
} |
||||
|
||||
function run(c){ |
||||
eval(c.getValue()) |
||||
} |
||||
|
||||
var val = |
||||
"var img = document.querySelector('img#to_ocr')\n\ |
||||
\n\ |
||||
Tesseract\n\ |
||||
.recognize( img, {progress: show_progress} )\n\ |
||||
.then( display )" |
||||
|
||||
var myCodeMirror = CodeMirror(document.getElementById('editor'),{ |
||||
// lineNumbers: true, |
||||
viewportMargin: Infinity, |
||||
value: val |
||||
}); |
||||
|
||||
|
||||
|
||||
var img = document.getElementById('to_ocr') |
||||
|
||||
if (img.complete) { |
||||
run(myCodeMirror) |
||||
} else{ |
||||
img.onload = function(){ |
||||
run(myCodeMirror) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<script src="animation/raf.js"></script> |
||||
<script src="animation/mouse.js"></script> |
||||
<script src="animation/dimensions.js"></script> |
||||
<script src="animation/main.js"></script> |
||||
</body> |
||||
</html> |
@ -1,79 +0,0 @@
@@ -1,79 +0,0 @@
|
||||
var Tesseract = {} |
||||
|
||||
Tesseract.recognize = function(image, options, callback){ |
||||
var lang = options.lang |
||||
if(typeof lang === "undefined"){ |
||||
lang = 'eng' |
||||
} |
||||
|
||||
if (typeof options === 'string') { |
||||
lang = options |
||||
options = {} |
||||
} |
||||
|
||||
if (typeof options === "function") { |
||||
callback = options |
||||
options = {} |
||||
} |
||||
|
||||
|
||||
if(image.getContext){ |
||||
image = image.getContext('2d'); |
||||
}else if(image.tagName == "IMG" || image.tagName == "VIDEO"){ |
||||
var c = document.createElement('canvas'); |
||||
if(image.tagName == "IMG"){ |
||||
c.width = image.naturalWidth; |
||||
c.height = image.naturalHeight; |
||||
}else if(image.tagName == "VIDEO"){ |
||||
c.width = image.videoWidth; |
||||
c.height = image.videoHeight; |
||||
} |
||||
var ctx = c.getContext('2d'); |
||||
ctx.drawImage(image, 0, 0); |
||||
image = ctx; |
||||
} |
||||
if(image.getImageData) image = image.getImageData(0, 0, image.canvas.width, image.canvas.height); |
||||
|
||||
|
||||
var blob = new Blob(["importScripts('https://cdn.rawgit.com/naptha/tesseract.js/master/worker/worker.js');"]); |
||||
|
||||
var worker = new Worker(window.URL.createObjectURL(blob)); |
||||
|
||||
var progress = (function(){ |
||||
if(typeof options.progress === 'function'){ |
||||
var p = options.progress |
||||
delete options.progress |
||||
return p |
||||
} |
||||
return function(){} |
||||
})() |
||||
|
||||
|
||||
if(typeof callback === "function"){ |
||||
worker.onmessage = function(e){ |
||||
if(e.data.progress){ |
||||
progress(e.data.progress) |
||||
} |
||||
else{ |
||||
callback(e.data.err, e.data.result) |
||||
} |
||||
} |
||||
worker.postMessage({image: image, lang: lang}) |
||||
} |
||||
else { |
||||
return new Promise(function(resolve, reject){ |
||||
worker.onmessage = function(e){ |
||||
if(e.data.progress){ |
||||
progress(e.data.progress) |
||||
} |
||||
else if(e.data.err){ |
||||
reject(e.data.err) |
||||
} |
||||
else { |
||||
resolve(e.data.result) |
||||
} |
||||
} |
||||
worker.postMessage({image: image, lang: lang, options: options}) |
||||
}) |
||||
} |
||||
} |
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
{ |
||||
"name": "tesseract.js", |
||||
"version": "1.0.0", |
||||
"description": "", |
||||
"main": "Tesseract.js", |
||||
"dependencies": { |
||||
"level-js": "^2.1.6", |
||||
"pako": "^0.2.7" |
||||
}, |
||||
"devDependencies": {}, |
||||
"scripts": { |
||||
"test": "echo \"Error: no test specified\" && exit 1" |
||||
}, |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "https://github.com/naptha/tesseract.js.git" |
||||
}, |
||||
"author": "", |
||||
"license": "ISC", |
||||
"bugs": { |
||||
"url": "https://github.com/naptha/tesseract.js/issues" |
||||
}, |
||||
"homepage": "https://github.com/naptha/tesseract.js" |
||||
} |
@ -1,394 +0,0 @@
@@ -1,394 +0,0 @@
|
||||
var db = (require('level-js'))('./tessdata') |
||||
// var db = leveljs('./tessdata')
|
||||
|
||||
var filesizes = {"afr": 1079573, "ara": 1701536, "aze": 1420865, "bel": 1276820, "ben": 6772012, "bul": 1605615, "cat": 1652368, "ces": 1035441, "chi_sim": 17710414, "chi_tra": 24717749, "chr": 320649, "dan-frak": 677656, "dan": 1972936, "deu-frak": 822644, "deu": 991656, "ell": 859719, "eng": 9453554, "enm": 619254, "epo": 1241212, "equ": 821130, "est": 1905040, "eus": 1641190, "fin": 979418, "fra": 1376221, "frk": 5912963, "frm": 5147082, "glg": 1674938, "grc": 3012615, "heb": 1051501, "hin": 6590065, "hrv": 1926995, "hun": 3074473, "ind": 1874776, "isl": 1634041, "ita": 948593, "ita_old": 3436571, "jpn": 13507168, "kan": 4390317, "kor": 5353098, "lav": 1843944, "lit": 1779240, "mal": 5966263, "meme": 88453, "mkd": 1163087, "mlt": 1463001, "msa": 1665427, "nld": 1134708, "nor": 2191610, "osd": 4274649, "pol": 7024662, "por": 909359, "ron": 915680, "rus": 5969957, "slk-frak": 289885, "slk": 2217342, "slv": 1611338, "spa": 883170, "spa_old": 5647453, "sqi": 1667041, "srp": 1770244, "swa": 757916, "swe": 2451917, "tam": 3498763, "tel": 5795246, "tgl": 1496256, "tha": 3811136, "tur": 3563264, "ukr": 937566, "vie": 2195922} |
||||
|
||||
var pako = require('pako') |
||||
|
||||
var recognize = (function createTesseractInstance(){ |
||||
|
||||
var Module = Tesseract304({ |
||||
TOTAL_MEMORY: 6*16777216, //must be a multiple of 10 megabytes
|
||||
TesseractProgress: function(percent){ |
||||
postMessage({ |
||||
'progress': { |
||||
'recognized': Math.max(0,(percent-30)/70) |
||||
} |
||||
}) |
||||
}//,
|
||||
// onRuntimeInitialized: function(){
|
||||
// console.log('wau')
|
||||
// }
|
||||
}) |
||||
|
||||
var base = new Module.TessBaseAPI() |
||||
var loaded_langs = [] |
||||
var loadLanguage = function(lang, cb){ // NodeJS style callback
|
||||
if(loaded_langs.indexOf(lang) != -1){ |
||||
cb(null, lang) |
||||
} |
||||
else{ |
||||
Module.FS_createPath("/","tessdata",true,true) |
||||
|
||||
var downloadlang = function(shouldcache){ |
||||
postMessage({ |
||||
'progress': { |
||||
'loaded_lang_model': 0, |
||||
cached: false, |
||||
requesting: true |
||||
} |
||||
}) |
||||
var xhr = new XMLHttpRequest(); |
||||
xhr.open('GET', 'https://cdn.rawgit.com/naptha/tessdata/gh-pages/3.02/'+lang+'.traineddata.gz', true); |
||||
xhr.responseType = 'arraybuffer'; |
||||
xhr.onerror = function(){ cb(xhr, null) } |
||||
xhr.onprogress = function(e){ |
||||
postMessage({ |
||||
'progress': { |
||||
'loaded_lang_model': e.loaded/filesizes[lang], |
||||
cached: false |
||||
} |
||||
}) |
||||
} |
||||
xhr.onload = function(){ |
||||
if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { |
||||
postMessage({ |
||||
'progress': 'unzipping_lang_model' |
||||
}) |
||||
|
||||
var response = new Uint8Array(xhr.response) |
||||
|
||||
var data = pako.inflate(response) |
||||
postMessage({ |
||||
'progress': 'unzipped_lang_model' |
||||
}) |
||||
|
||||
Module.FS_createDataFile('tessdata', lang +".traineddata", data, true, false); |
||||
|
||||
if(shouldcache){ |
||||
db.put(lang, response, function(err){ |
||||
console.log('cached lang') |
||||
}) |
||||
} |
||||
|
||||
loaded_langs.push(lang) |
||||
|
||||
cb(null, lang) |
||||
} else cb(xhr, null); |
||||
} |
||||
xhr.send(null) |
||||
} |
||||
|
||||
db.open({compression: false},function(err){ |
||||
if (err) { |
||||
downloadlang(false) |
||||
} |
||||
else { |
||||
db.get(lang, function (err, value) { |
||||
|
||||
// err = true
|
||||
|
||||
if (err) { |
||||
downloadlang(true) |
||||
} |
||||
else { |
||||
value = pako.inflate(value) |
||||
|
||||
postMessage({ |
||||
'progress': { |
||||
loaded_lang_model:1, |
||||
cached: true |
||||
} |
||||
}) |
||||
|
||||
Module.FS_createDataFile('tessdata', lang +".traineddata", value, true, false); |
||||
loaded_langs.push(lang) |
||||
cb(null, lang) |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
|
||||
function circularize(page){ |
||||
page.paragraphs = [] |
||||
page.lines = [] |
||||
page.words = [] |
||||
page.symbols = [] |
||||
|
||||
page.blocks.forEach(function(block){ |
||||
block.page = page; |
||||
|
||||
block.lines = [] |
||||
block.words = [] |
||||
block.symbols = [] |
||||
|
||||
block.paragraphs.forEach(function(para){ |
||||
para.block = block; |
||||
para.page = page; |
||||
|
||||
para.words = [] |
||||
para.symbols = [] |
||||
|
||||
para.lines.forEach(function(line){ |
||||
line.paragraph = para; |
||||
line.block = block; |
||||
line.page = page; |
||||
|
||||
line.symbols = [] |
||||
|
||||
line.words.forEach(function(word){ |
||||
word.line = line; |
||||
word.paragraph = para; |
||||
word.block = block; |
||||
word.page = page; |
||||
word.symbols.forEach(function(sym){ |
||||
sym.word = word; |
||||
sym.line = line; |
||||
sym.paragraph = para; |
||||
sym.block = block; |
||||
sym.page = page; |
||||
|
||||
sym.line.symbols.push(sym) |
||||
sym.paragraph.symbols.push(sym) |
||||
sym.block.symbols.push(sym) |
||||
sym.page.symbols.push(sym) |
||||
}) |
||||
word.paragraph.words.push(word) |
||||
word.block.words.push(word) |
||||
word.page.words.push(word) |
||||
}) |
||||
line.block.lines.push(line) |
||||
line.page.lines.push(line) |
||||
}) |
||||
para.page.paragraphs.push(para) |
||||
}) |
||||
}) |
||||
return page |
||||
} |
||||
|
||||
|
||||
|
||||
function DumpLiterallyEverything(){ |
||||
var ri = base.GetIterator(); |
||||
var blocks = []; |
||||
var block, para, textline, word, symbol; |
||||
|
||||
function enumToString(value, prefix){ |
||||
return (Object.keys(Module) |
||||
.filter(function(e){ return e.startsWith(prefix + '_') }) |
||||
.filter(function(e){ return Module[e] === value }) |
||||
.map(function(e){ return e.slice(prefix.length + 1) })[0]) |
||||
} |
||||
|
||||
ri.Begin() |
||||
do { |
||||
if(ri.IsAtBeginningOf(Module.RIL_BLOCK)){ |
||||
var poly = ri.BlockPolygon(); |
||||
var polygon = null; |
||||
// BlockPolygon() returns null when automatic page segmentation is off
|
||||
if(Module.getPointer(poly) > 0){ |
||||
var n = poly.get_n(), |
||||
px = poly.get_x(), |
||||
py = poly.get_y(), |
||||
polygon = []; |
||||
for(var i = 0; i < n; i++){ |
||||
polygon.push([px.getValue(i), py.getValue(i)]); |
||||
} |
||||
Module._ptaDestroy(Module.getPointer(poly)); |
||||
} |
||||
|
||||
block = { |
||||
paragraphs: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_BLOCK), |
||||
confidence: ri.Confidence(Module.RIL_BLOCK), |
||||
baseline: ri.getBaseline(Module.RIL_BLOCK), |
||||
bbox: ri.getBoundingBox(Module.RIL_BLOCK), |
||||
|
||||
blocktype: enumToString(ri.BlockType(), 'PT'), |
||||
polygon: polygon |
||||
} |
||||
blocks.push(block) |
||||
} |
||||
if(ri.IsAtBeginningOf(Module.RIL_PARA)){ |
||||
para = { |
||||
lines: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_PARA), |
||||
confidence: ri.Confidence(Module.RIL_PARA), |
||||
baseline: ri.getBaseline(Module.RIL_PARA), |
||||
bbox: ri.getBoundingBox(Module.RIL_PARA), |
||||
|
||||
is_ltr: !!ri.ParagraphIsLtr() |
||||
} |
||||
block.paragraphs.push(para) |
||||
} |
||||
if(ri.IsAtBeginningOf(Module.RIL_TEXTLINE)){ |
||||
textline = { |
||||
words: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_TEXTLINE), |
||||
confidence: ri.Confidence(Module.RIL_TEXTLINE), |
||||
baseline: ri.getBaseline(Module.RIL_TEXTLINE), |
||||
bbox: ri.getBoundingBox(Module.RIL_TEXTLINE) |
||||
} |
||||
para.lines.push(textline) |
||||
} |
||||
if(ri.IsAtBeginningOf(Module.RIL_WORD)){ |
||||
var fontInfo = ri.getWordFontAttributes(), |
||||
wordDir = ri.WordDirection(); |
||||
word = { |
||||
symbols: [], |
||||
choices: [], |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_WORD), |
||||
confidence: ri.Confidence(Module.RIL_WORD), |
||||
baseline: ri.getBaseline(Module.RIL_WORD), |
||||
bbox: ri.getBoundingBox(Module.RIL_WORD), |
||||
|
||||
is_numeric: !!ri.WordIsNumeric(), |
||||
in_dictionary: !!ri.WordIsFromDictionary(), |
||||
direction: enumToString(wordDir, 'DIR'), |
||||
language: ri.WordRecognitionLanguage(), |
||||
|
||||
is_bold: fontInfo.is_bold, |
||||
is_italic: fontInfo.is_italic, |
||||
is_underlined: fontInfo.is_underlined, |
||||
is_monospace: fontInfo.is_monospace, |
||||
is_serif: fontInfo.is_serif, |
||||
is_smallcaps: fontInfo.is_smallcaps, |
||||
font_size: fontInfo.pointsize, |
||||
font_id: fontInfo.font_id, |
||||
font_name: fontInfo.font_name, |
||||
} |
||||
var wc = new Module.WordChoiceIterator(ri); |
||||
do { |
||||
word.choices.push({ |
||||
text: wc.GetUTF8Text(), |
||||
confidence: wc.Confidence() |
||||
}) |
||||
} while (wc.Next()); |
||||
Module.destroy(wc) |
||||
textline.words.push(word) |
||||
} |
||||
|
||||
var image = null; |
||||
// var pix = ri.GetBinaryImage(Module.RIL_SYMBOL)
|
||||
// var image = pix2array(pix);
|
||||
// // for some reason it seems that things stop working if you destroy pics
|
||||
// Module._pixDestroy(Module.getPointer(pix));
|
||||
if(ri.IsAtBeginningOf(Module.RIL_SYMBOL)){ |
||||
symbol = { |
||||
choices: [], |
||||
image: image, |
||||
|
||||
text: ri.GetUTF8Text(Module.RIL_SYMBOL), |
||||
confidence: ri.Confidence(Module.RIL_SYMBOL), |
||||
baseline: ri.getBaseline(Module.RIL_SYMBOL), |
||||
bbox: ri.getBoundingBox(Module.RIL_SYMBOL), |
||||
|
||||
is_superscript: !!ri.SymbolIsSuperscript(), |
||||
is_subscript: !!ri.SymbolIsSubscript(), |
||||
is_dropcap: !!ri.SymbolIsDropcap(), |
||||
} |
||||
word.symbols.push(symbol) |
||||
var ci = new Module.ChoiceIterator(ri); |
||||
do { |
||||
symbol.choices.push({ |
||||
text: ci.GetUTF8Text(), |
||||
confidence: ci.Confidence() |
||||
}) |
||||
} while (ci.Next()); |
||||
Module.destroy(ci) |
||||
} |
||||
} while (ri.Next(Module.RIL_SYMBOL)); |
||||
Module.destroy(ri) |
||||
|
||||
return { |
||||
text: base.GetUTF8Text(), |
||||
html: base.GetHOCRText(), |
||||
|
||||
confidence: base.MeanTextConf(), |
||||
|
||||
blocks: blocks, |
||||
|
||||
psm: enumToString(base.GetPageSegMode(), 'PSM'), |
||||
oem: enumToString(base.oem(), 'OEM'), |
||||
version: base.Version(), |
||||
} |
||||
} |
||||
|
||||
function recognize(image, lang, options,cb){ |
||||
var width, height; |
||||
if(image.data){ |
||||
var src = image.data; |
||||
width = image.width, height = image.height; |
||||
var dst = new Uint8Array(width * height); |
||||
var srcLength = src.length | 0, srcLength_16 = (srcLength - 16) | 0; |
||||
|
||||
for (var i = 0, j = 0; i <= srcLength_16; i += 16, j += 4) { |
||||
// convert to grayscale 4 pixels at a time; eveything with alpha get put in front of 50% gray
|
||||
dst[j] = (((src[i] * 77 + src[i+1] * 151 + src[i+2] * 28) * src[i+3]) + ((255-src[i+3]) << 15) + 32768) >> 16 |
||||
dst[j+1] = (((src[i+4] * 77 + src[i+5] * 151 + src[i+6] * 28) * src[i+7]) + ((255-src[i+7]) << 15) + 32768) >> 16 |
||||
dst[j+2] = (((src[i+8] * 77 + src[i+9] * 151 + src[i+10] * 28) * src[i+11]) + ((255-src[i+11]) << 15) + 32768) >> 16 |
||||
dst[j+3] = (((src[i+12] * 77 + src[i+13] * 151 + src[i+14] * 28) * src[i+15]) + ((255-src[i+15]) << 15) + 32768) >> 16 |
||||
|
||||
} |
||||
for (; i < srcLength; i += 4, ++j) //finish up
|
||||
dst[j] = (((src[i] * 77 + src[i+1] * 151 + src[i+2] * 28) * src[i+3]) + ((255-src[i+3]) << 15) + 32768) >> 16 |
||||
|
||||
image = dst; |
||||
} |
||||
else { |
||||
throw 'Expected ImageData' |
||||
} |
||||
var ptr = Module.allocate(image, 'i8', Module.ALLOC_NORMAL); |
||||
|
||||
loadLanguage(lang, function(err, result){ |
||||
|
||||
if(err){ |
||||
console.error("error loading", lang); |
||||
Module._free(ptr); |
||||
cb(err, null) |
||||
} |
||||
else { |
||||
base.Init(null, lang) |
||||
for (var option in options) { |
||||
if (options.hasOwnProperty(option)) { |
||||
base.SetVariable(option, options[option]); |
||||
postMessage({ |
||||
progress: { |
||||
set_variable: { |
||||
variable: option, |
||||
value: options[option] |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
|
||||
base.SetImage(Module.wrapPointer(ptr), width, height, 1, width) |
||||
base.SetRectangle(0, 0, width, height) |
||||
// base.GetUTF8Text()
|
||||
base.Recognize(null) |
||||
var everything = circularize(DumpLiterallyEverything()) |
||||
base.End(); |
||||
Module._free(ptr); |
||||
cb(null, everything) |
||||
|
||||
} |
||||
}) |
||||
} |
||||
|
||||
return recognize |
||||
})() |
||||
|
||||
onmessage = function(e) { |
||||
recognize(e.data.image, e.data.lang, e.data.options, function(err, result){ |
||||
postMessage({err:err, result: result}) |
||||
}) |
||||
} |