Compare commits

...

54 Commits

Author SHA1 Message Date
jeromewu d6e9177290
Merge pull request #389 from moebrowne/security/sri 5 years ago
jeromewu 3d1aa49c33
Merge pull request #390 from moebrowne/feature/update-image-preview-first 5 years ago
MoeBrowne a86cb05519
Updates the image preview to update immediately 5 years ago
MoeBrowne 95e74bdbed
Adds an SRI attribute to the tesseract.js dependency 5 years ago
Jerome Wu 363ecd7b22 Upgrade to v2.0.0 5 years ago
Jerome Wu 9863bd8f74 Upgrade to tesseract.js@2.0.0-beta.1 5 years ago
jeromewu 18dde5cbac
Upgrade to tesseract.js v2.0.0-alpha.11 6 years ago
jeromewu ebe263ad0f
Update index.html 6 years ago
Jerome Wu 91c39ceaa5 Upgrade to alpha.8 6 years ago
Jerome Wu 24ebdeacb8 Upgrade to latest version of tesseract.js 6 years ago
Jerome Wu d58b778d0b Add redirection from http to https 6 years ago
Jerome Wu 233cc8bdd3 Update font url to be https 6 years ago
Jerome Wu b2c819b219 Upgrade to tesseract.js@2.0.0-alpha.3 6 years ago
Jerome Wu 8ef238714b Replace jsdeliver with unpack 6 years ago
Jerome Wu 2ec4a0433f Upgrade to tesseract.js@2.0.0-alpha.2 6 years ago
jeromewu 1a4da18407
Revert changes as it doesn't work 6 years ago
jeromewu 232d8e854d
Fix unable to fetch chi_sim traineddata issue 6 years ago
jeromewu 7128fc5572
Add one more name 6 years ago
jeromewu ab5776f2a9
Fix typo 6 years ago
jeromewu 8978faa04a
Update usage from v1 to v2 6 years ago
jeromewu ef1ac48467
Add another GA tracker and upgrade tesseract.js 6 years ago
Guillermo 8e755745b7 add link 8 years ago
Kevin Kwok 0709222de3 new update 8 years ago
Kevin Kwok 2f3fd699d7 Merge branch 'gh-pages' of github.com:naptha/tesseract.js into gh-pages 8 years ago
Kevin Kwok d00d676fc9 updating index 8 years ago
bijection 7f23b4c073 Merge pull request #24 from pborreli/typos 8 years ago
Pascal Borreli 476fa56084 Fixed typos 8 years ago
Guillermo 1896dc0807 fix progress 8 years ago
Guillermo 325747e0a7 ad ga to demo page 8 years ago
Kevin Kwok be29f9ab92 words 8 years ago
Kevin Kwok 244d0b98d7 fixing demo 8 years ago
Guillermo 8a79897546 make image smaller 8 years ago
Guillermo cb9e2d5928 demo 8 years ago
Guillermo 200b770c97 interim 8 years ago
Guillermo 0243eb6bd0 walp 8 years ago
Guillermo 8527a70b36 simplify 8 years ago
Guillermo 923d75a047 nautical theme 9 years ago
Guillermo 26d7681e72 new progress bar, fixed onload issue, changed to tenso.rs 10 years ago
Guillermo 2d85c0fbe8 fixed some safari flex problems 10 years ago
Guillermo 5660a8c454 added lato 10 years ago
Guillermo 73f381f595 meme is still broken 10 years ago
Guillermo 5b02e236c1 wow it all works kinda 10 years ago
Guillermo 1270e278c9 geen 10 years ago
Guillermo 8d23fa0bdf oops fixed relative url problem 10 years ago
Guillermo abf7ae1190 push all the things 10 years ago
Guillermo 379781c8a5 merch 10 years ago
Guillermo e23d75f0a9 moved main login into separate file 10 years ago
bijection 1073a8ca61 woo i can type! 10 years ago
Guillermo 61415571bd yay new internet page\! 10 years ago
Guillermo 58b816a40b I like turtles 10 years ago
Guillermo 78d70d73d4 changed to remote webworkers 10 years ago
Guillermo 3a47aed70f added local language model caching 10 years ago
Guillermo b2ff251c7d added progress callback 10 years ago
Guillermo 0f0ed005e5 browserified worker.js 10 years ago
  1. 3
      .gitignore
  2. 1
      CNAME
  3. 1
      README.md
  4. 60
      Tesseract.js
  5. 70
      animation/animate.js
  6. 43
      animation/dimensions.js
  7. 79
      animation/hypercube.js
  8. 56
      animation/mouse.js
  9. 27
      animation/raf.js
  10. 329
      codemirror/codemirror.css
  11. 8735
      codemirror/codemirror.js
  12. 704
      codemirror/javascript.js
  13. 72
      codemirror/runmode.js
  14. 384
      codemirror/xml.js
  15. 84
      css/explorer.css
  16. 313
      css/main.css
  17. 435
      css/wau.css
  18. 229
      demo.js
  19. 17
      example.htm
  20. 392
      explorer/explorer.js
  21. 19602
      explorer/react.js
  22. 16
      explorer/react.min.js
  23. BIN
      img/bg.jpg
  24. BIN
      img/bg.png
  25. BIN
      img/chi_sim.png
  26. BIN
      img/deu.png
  27. BIN
      img/eng.jpg
  28. BIN
      img/eng.png
  29. BIN
      img/eng_bw.png
  30. BIN
      img/fork.png
  31. BIN
      img/hayden.jpg
  32. BIN
      img/keyboard.png
  33. BIN
      img/logo.png
  34. BIN
      img/logo.psd
  35. BIN
      img/logo_small.png
  36. BIN
      img/logoblue.png
  37. BIN
      img/logowhite.png
  38. BIN
      img/meme.png
  39. BIN
      img/redstars.png
  40. BIN
      img/run.png
  41. BIN
      img/rus.png
  42. BIN
      img/shake.png
  43. BIN
      img/splash.png
  44. BIN
      img/starblur.jpg
  45. BIN
      img/stars.jpeg
  46. 110
      index.html
  47. 163
      index_dev.html
  48. 162
      index_old.html
  49. 242
      main.js
  50. 227
      main_dev.js
  51. 23
      package.json
  52. 61
      perlinish/perlinish.js
  53. 191
      src/explorer.js
  54. 163
      src/index.html
  55. 247
      src/main.js
  56. 90
      test.htm
  57. 583
      worker_src/madeline.js
  58. 324
      worker_src/worker.js

3
.gitignore vendored

@ -1,2 +1,3 @@ @@ -1,2 +1,3 @@
.DS_Store
node_modules/*
node_modules/*
explorer/.module-cache/*

1
CNAME

@ -0,0 +1 @@ @@ -0,0 +1 @@
tesseract.projectnaptha.com

1
README.md

@ -1 +0,0 @@ @@ -1 +0,0 @@
# tesseract.js

60
Tesseract.js

@ -1,60 +0,0 @@ @@ -1,60 +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 worker = new Worker('./worker.js')
if(typeof callback === "function"){
worker.onmessage = function(e){
callback(e.data.err, e.data.result)
}
worker.postMessage({image: image, lang: lang})
console.log('callback')
}
else {
return new Promise(function(resolve, reject){
worker.onmessage = function(e){
if(e.data.err){
reject(e.data.err)
}
else {
resolve(e.data.result)
}
}
worker.postMessage({image: image, lang: lang, options: options})
console.log('promise')
})
}
}

70
animation/animate.js

@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
var canvas = document.getElementById('logo-canvas'),
ctx = canvas.getContext('2d'),
logo_wrap = document.getElementById('logo-wrap'),
splash = document.getElementById('splash'),
logo_img = document.getElementById('logo-img'),
color = "white",
lasttime,
freeze
function fixdim() {
dimensions.update()
var displaywidth = Math.sqrt(dimensions.width)*18//dimensions.width > 900 ? 900 : 450
var doc = document.documentElement;
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
// logo_wrap.style.top = top / 2 + 'px'
var rect = splash.getBoundingClientRect()
var bottom = rect.top + rect.height
var fadestart = rect.height/2
logo_wrap.style.opacity = Math.max(Math.min((bottom-fadestart)/fadestart,1),0)
logo_img.style.width = displaywidth + 'px'
if(!freeze){
var displayheight = displaywidth * 4/15 //dimensions.width > 900 ? 250 : 125
canvas.width = displayheight*window.devicePixelRatio
canvas.style.width = displayheight + 'px'
canvas.height = displayheight*window.devicePixelRatio
canvas.style.height = displayheight + 'px'
}
}
addEventListener('scroll', fixdim)
var gh = .12;
function main (time) {
fixdim()
ctx.clearRect(0,0,canvas.width,canvas.height)
var t = time/10000
ctx.strokeStyle = ctx.fillStyle = color
var sm = 1
var m = tesseractwithrotation(t, t*2, t*3, mouse.x/100, mouse.y/100, 0)
drawtesseract(ctx, m, {
x: canvas.width/2,
y: canvas.height/2,
size: gh*canvas.height,
line_width: 2,
})
lasttime = time
requestAnimationFrame(main)
}
requestAnimationFrame(function init(t) {
fixdim()
lasttime = t
requestAnimationFrame(main)
})

43
animation/dimensions.js

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
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
}
return false
}
}

79
animation/hypercube.js

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
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 drawtesseract(ctx, 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()
}

56
animation/mouse.js

@ -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);

27
animation/raf.js

@ -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); };
}
}());

329
codemirror/codemirror.css

@ -0,0 +1,329 @@ @@ -0,0 +1,329 @@
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: auto;
color: rgb(156, 154, 193);
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: #0DAEFF;}
.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 {
color: black;
}
.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: #DB0000;}
.cm-s-default .cm-string {color: #5426C9;}
.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: #050216;}
.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: transparent;
}
.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; }

8735
codemirror/codemirror.js

File diff suppressed because it is too large Load Diff

704
codemirror/javascript.js

@ -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 });
});

72
codemirror/runmode.js

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(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.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
if (callback.nodeType == 1) {
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
if (text == "\n") {
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
// Emitting a carriage return makes everything ok.
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
});

384
codemirror/xml.js

@ -0,0 +1,384 @@ @@ -0,0 +1,384 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(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("xml", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
var Kludges = parserConfig.htmlMode ? {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true, 'menuitem': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
contextGrabbers: {
'dd': {'dd': true, 'dt': true},
'dt': {'dd': true, 'dt': true},
'li': {'li': true},
'option': {'option': true, 'optgroup': true},
'optgroup': {'optgroup': true},
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
'rp': {'rp': true, 'rt': true},
'rt': {'rp': true, 'rt': true},
'tbody': {'tbody': true, 'tfoot': true},
'td': {'td': true, 'th': true},
'tfoot': {'tbody': true},
'th': {'td': true, 'th': true},
'thead': {'tbody': true, 'tfoot': true},
'tr': {'tr': true}
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: true,
caseFold: true
} : {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
caseFold: false
};
var alignCDATA = parserConfig.alignCDATA;
// Return variables for tokenizers
var type, setStyle;
function inText(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
}
var ch = stream.next();
if (ch == "<") {
if (stream.eat("!")) {
if (stream.eat("[")) {
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
else return null;
} else if (stream.match("--")) {
return chain(inBlock("comment", "-->"));
} else if (stream.match("DOCTYPE", true, true)) {
stream.eatWhile(/[\w\._\-]/);
return chain(doctype(1));
} else {
return null;
}
} else if (stream.eat("?")) {
stream.eatWhile(/[\w\._\-]/);
state.tokenize = inBlock("meta", "?>");
return "meta";
} else {
type = stream.eat("/") ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag bracket";
}
} else if (ch == "&") {
var ok;
if (stream.eat("#")) {
if (stream.eat("x")) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
} else {
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
}
} else {
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
}
return ok ? "atom" : "error";
} else {
stream.eatWhile(/[^&<]/);
return null;
}
}
function inTag(stream, state) {
var ch = stream.next();
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag bracket";
} else if (ch == "=") {
type = "equals";
return null;
} else if (ch == "<") {
state.tokenize = inText;
state.state = baseState;
state.tagName = state.tagStart = null;
var next = state.tokenize(stream, state);
return next ? next + " tag error" : "tag error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
return "word";
}
}
function inAttribute(quote) {
var closure = function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inTag;
break;
}
}
return "string";
};
closure.isInAttribute = true;
return closure;
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = inText;
break;
}
stream.next();
}
return style;
};
}
function doctype(depth) {
return function(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch == "<") {
state.tokenize = doctype(depth + 1);
return state.tokenize(stream, state);
} else if (ch == ">") {
if (depth == 1) {
state.tokenize = inText;
break;
} else {
state.tokenize = doctype(depth - 1);
return state.tokenize(stream, state);
}
}
}
return "meta";
};
}
function Context(state, tagName, startOfLine) {
this.prev = state.context;
this.tagName = tagName;
this.indent = state.indented;
this.startOfLine = startOfLine;
if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
this.noIndent = true;
}
function popContext(state) {
if (state.context) state.context = state.context.prev;
}
function maybePopContext(state, nextTagName) {
var parentTagName;
while (true) {
if (!state.context) {
return;
}
parentTagName = state.context.tagName;
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
return;
}
popContext(state);
}
}
function baseState(type, stream, state) {
if (type == "openTag") {
state.tagStart = stream.column();
return tagNameState;
} else if (type == "closeTag") {
return closeTagNameState;
} else {
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
popContext(state);
if (state.context && state.context.tagName == tagName) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
return closeState;
}
popContext(state);
return baseState;
}
function closeStateErr(type, stream, state) {
setStyle = "error";
return closeState(type, stream, state);
}
function attrState(type, _stream, state) {
if (type == "word") {
setStyle = "attribute";
return attrEqState;
} else if (type == "endTag" || type == "selfcloseTag") {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
state.context = new Context(state, tagName, tagStart == state.indented);
}
return baseState;
}
setStyle = "error";
return attrState;
}
function attrEqState(type, stream, state) {
if (type == "equals") return attrValueState;
if (!Kludges.allowMissing) setStyle = "error";
return attrState(type, stream, state);
}
function attrValueState(type, stream, state) {
if (type == "string") return attrContinuedState;
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
setStyle = "error";
return attrState(type, stream, state);
}
function attrContinuedState(type, stream, state) {
if (type == "string") return attrContinuedState;
return attrState(type, stream, state);
}
return {
startState: function() {
return {tokenize: inText,
state: baseState,
indented: 0,
tagName: null, tagStart: null,
context: null};
},
token: function(stream, state) {
if (!state.tagName && stream.sol())
state.indented = stream.indentation();
if (stream.eatSpace()) return null;
type = null;
var style = state.tokenize(stream, state);
if ((style || type) && style != "comment") {
setStyle = null;
state.state = state.state(type || style, stream, state);
if (setStyle)
style = setStyle == "error" ? style + " error" : setStyle;
}
return style;
},
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
if (state.tagStart == state.indented)
return state.stringStartCol + 1;
else
return state.indented + indentUnit;
}
if (context && context.noIndent) return CodeMirror.Pass;
if (state.tokenize != inTag && state.tokenize != inText)
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
// Indent the starts of attribute names.
if (state.tagName) {
if (multilineTagIndentPastTag)
return state.tagStart + state.tagName.length + 2;
else
return state.tagStart + indentUnit * multilineTagIndentFactor;
}
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
if (tagAfter && tagAfter[1]) { // Closing tag spotted
while (context) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
} else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
context = context.prev;
} else {
break;
}
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
var grabbers = Kludges.contextGrabbers[context.tagName];
if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
context = context.prev;
else
break;
}
}
while (context && !context.startOfLine)
context = context.prev;
if (context) return context.indent + indentUnit;
else return 0;
},
electricInput: /<\/[\s\w:]+>$/,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
configuration: parserConfig.htmlMode ? "html" : "xml",
helperType: parserConfig.htmlMode ? "html" : "xml"
};
});
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
});

84
css/explorer.css

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
#explorer {
max-height: 500px;
white-space: nowrap;
overflow: scroll;
padding: 10px;
/*border: 1px solid #eee;*/
border-radius: 5px;
font-family: monospace;
background-color: #fff;
}
.textNode {
display: inline-block;
max-width: 400px;
vertical-align: middle;
white-space: pre;
overflow: scroll;
margin-bottom: 1px;
margin-top: 1px;
}
.textNode {
background-color: rgb(255, 238, 174);
color: rgb(48, 48, 97);
padding: 2px;
border-radius: 3px;
}
.html {
background-color: #F5F5F5;
}
.comma, .ellipsis {
color: grey;
}
.nullNode {
color: grey;
}
.numberNode {
color: rgb(203, 48, 48);
}
.booleanNode {
color: rgb(174, 44, 164);
}
.label {
color: rgb(76, 162, 242);
}
.clickable {
cursor: pointer;
}
.indent {
padding-left: 30px;
display: inline-block;
}
/*.collapsed, .expanded {
position: relative;
}
*/
/*.collapsed::before {
content: "▶";
position: absolute;
left: -16px;
}
.expanded::before {
content: "▼";
position: absolute;
left: -16px;
}
.swiper{
padding-left: 40px;
margin-top: 8px;
}
*/

313
css/main.css

@ -0,0 +1,313 @@ @@ -0,0 +1,313 @@
body, html{
position: absolute;
top: 0;
margin: 0;
width: 100%;
font-family: Lato;
font-weight: 300;
}
#slogan {
text-align: center;
margin-top: -26px;
color: #fff;
}
#splash {
overflow: hidden;
background-color: #425565;
background: url(../img/bg.jpg);
background-size: cover;
background-position: center;
}
#logo-wrap {
margin-top: 50px;
text-align: center;
position: relative;
}
#demo-instructions {
display: none;
}
#logo-canvas {
margin-left: auto;
margin-right: auto;
pointer-events: none;
z-index: 0;
position: absolute;
}
#logo-img {
max-width: 100%;
}
.get-started-wrap {
text-align: center;
position: relative;
padding: 0 20px;
}
.get-started {
display: inline-block;
color: #714d26;
background: #fff;
padding: 17px 25px;
font-size: 30px;
margin: 50px 0;
border-radius: 7px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
}
#demo-title {
padding: 40px 0;
color: #714d26;
font-size: 30px;
// text-align: center;
}
#options {
display: flex;
justify-content: space-around;
font-size: 20px;
color: #3580c0;
padding: 0 15px;
max-width: 700px;
margin-left: auto;
margin-right: auto;
box-sizing: border-box;
}
.option {
padding: 10px;
border-radius: 5px;
cursor: pointer;
text-align: center;
}
.option.selected {
color: #3580c0;
background: #d8edff;
font-weight: 400;
}
#input {
max-width: 100%;
box-sizing: border-box;
padding: 20px;
margin-top: 30px;
border: 1px solid #ddd;
}
#input-overlay {
position: absolute;
max-width: 100%;
box-sizing: border-box;
margin-top: 30px;
padding: 20px;
}
#github {
height: 1em;
width: 1em;
margin-bottom: -3px;
margin-right: 10px;
}
#github path {
fill: #826f5c;
}
#demo-content > #arrow {
text-align: center;
font-size: 30px;
color: #826f5c;
flex: 0;
}
#arrow::before {
content: '\2193'
}
#output {
max-width: 100%;
box-sizing: border-box;
padding: 20px;
}
#output-overlay {
white-space: pre;
font-family: Monaco, monospace;
position: absolute;
height: 100%;
width: 100%;
overflow: scroll;
border: 20px solid transparent;
box-sizing: border-box;
}
#clickme {
color: #2374b7;
text-decoration: underline;
cursor: pointer;
}
#footer {
color: #826f5c;
background-color: #f6f6f6;
text-align: right;
padding: 0 20px;
}
#lengle {
margin-top: 8%;
margin-bottom: 8%;
line-height: normal;
display: inline-block;
vertical-align: middle;
}
#lengle img {
height: .7em;
}
#demo-content > div {
position: relative;
flex: 1;
border: 20px solid transparent;
}
#drop-instructions-main {
display: none;
}
.commentary {
position: relative;
padding: 20px;
max-width: 700px;
margin-left: auto;
margin-right: auto;
line-height: 180%;
letter-spacing: .5 px;
}
#output-text {
margin: 0px;
width: 100%;
min-height: 200px;
box-sizing: border-box;
padding: 20px;
border: 1px solid #ddd;
}
#demo-instructions {
border: 1px solid #dadada;
padding: 20px;
}
#log > div {
color: #313131;
border-top: 1px solid #dadada;
padding: 10px 0;
display: flex;
}
#log > div:first-child {
border: 0;
}
#log .status {
min-width: 250px;
}
#log {
border: 1px solid #dadada;
padding: 20px;
overflow: auto;
}
#log progress {
display: block;
width: 100%;
transition: opacity 0.5s linear;
}
#log progress[value="1"] {
opacity: 0.5;
}
#footer {
color: #ffffff;
background-color: #f6f6f6;
text-align: right;
padding: 0 20px;
background-color: #425565;
background: url(../img/bg.jpg);
background-size: cover;
background-position: bottom;
}
#footer a {
color: white !important;
}
@media (min-width: 900px) {
#drop-instructions-main {
display: block;
text-align: center;
color: #b1a79c;
}
#demo-content {
display: flex;
align-items: center;
}
#input, #input-overlay {
margin-top: 0;
}
#arrow::before {
content: '\2192';
}
#options {
margin: 40px auto;
}
// #demo-title {
// width: 250px;
// background: #fff;
// margin-top: -70px;
// margin-left: 40px;
// position: relative;
// padding: 20px 0;
// }
// #demo-title::after {
// border-right: 40px solid transparent;
// border-bottom: 70px solid white;
// content: ' ';
// position: absolute;
// top: 0;
// left: 100%;
// }
// #demo-title::before {
// border-left: 40px solid transparent;
// border-bottom: 70px solid white;
// content: ' ';
// position: absolute;
// top: 0;
// left: -40px;
// }
// body {
// box-sizing: border-box;
// border: 20px solid #425565;
// }
}

435
css/wau.css

@ -0,0 +1,435 @@ @@ -0,0 +1,435 @@
@import 'explorer.css';
.fullscreen {
width: 100%;
min-height: 100%;
}
.stretch {
max-width: 100%
}
.langpair {
display: inline-block;
padding: -1px;
font-family: monospace;
text-align: center;
/*border: 1px solid #F3F3F3;*/
margin-bottom: 10px;
margin-right: 5px;
font-size: initial;
line-height: 1.5em;
flex-grow:1;
-webkit-flex-grow:1;
}
.footer {
width: 100%;
color: #fff;
background-color: #6A6A6A;
text-align: right;
}
.lengle {
margin-top: 8%;
margin-bottom: 8%;
line-height: normal;
display: inline-block;
vertical-align: middle;
}
.lengle img {
height: .7em;
}
.shortlang {
/*background-color: #FFEEAE;*/
}
.longlang {
background-color: #59C6FF;
color:#fff;
padding-left: 5px;
padding-right: 5px;
border-radius: 3px;
}
.explorersection{
background-color: rgba(102, 142, 195, 0.19);
width: 100%;
padding-top: 8%;
padding-bottom: 8%;
}
.noheight{
height: 0;
}
.columnwrap {
max-width: 1100;
margin-left: auto;
margin-right: auto;
}
.column {
padding-left: 8%;
padding-right: 8%;
}
.smalllogo {
height: 50px;
vertical-align: middle;
position: absolute;
left: 3%;
opacity: 0;
}
.stickyheader {
position: absolute;
width: 100%;
z-index: 3;
text-align: right;
line-height: 50px;
}
.headernav {
padding-right: 3%;
color: #fff;
}
.run,
.running {
width: 100%;
height: 47px;
text-align: center;
position: relative;
}
.running {
display: none
}
#wow .notrunning {
display: none
}
#wow .running {
display: block
}
.runbutton {
padding-top: 9px;
padding-bottom: 10px;
font-weight: 500;
text-align: center;
color: #FFFFFF;
cursor: pointer;
-webkit-transition: all 0.7s ease;
transition: all 0.7s ease;
width: 100px;
margin-left: auto;
margin-right: auto;
background-color: #6A6A6A;
border-radius: 5px;
margin-bottom: 9px;
}
.runbutton:hover {
text-shadow: 0px 0px 10px #27C6F9;
}
a {
text-decoration: none;
color: #5BA9F2;
/*font-weight: bold;*/
}
.display {
// position: absolute;
/*background: rgba(0,0,255,.1);*/
}
svg {
height: 100%
}
.marterial {
/*position: absolute;*/
width: 100%;
z-index: -1;
overflow: hidden;
background-color: #668EC3;
/*background-image: url(../img/stars.jpeg);*/
background-size: cover;
background-position: bottom;
}
.out {
padding: 10px;
padding-bottom: 0px;
text-align: center;
font-family: monospace;
}
.hint {
text-align: left;
padding-left: 14px;
font-size: 10px;
color: #56607D;
}
.langlabel {
display: inline-block;
flex-grow: 1;
-webkit-flex-grow: 1;
height: 40px;
line-height: 40px;
cursor: pointer;
color: #fff;
background-color: #6A6A6A;
}
.selected {
background-color: #668EC3;
}
.bookend {
display: inline-block;
}
.prog {
height: 4px;
width: 100%;
position: absolute;
bottom:0;
background-color: #6a6a6a;
}
.prog div{
height: 100%;
background-color: #5BA9F2;
}
.demofooter {
padding: 10px;
/*padding-top: 0px;*/
text-align: center;
/*display: flex*/
}
#wow .demofooter {
display: flex;
display: -webkit-flex;
padding: 0px;
justify-content: space-between;
-webkit-justify-content: space-between;
align-items: center;
-webkit-align-items: center;
}
#logo {
text-align: center;
margin-top: 6%;
margin-bottom: 6%;
height: 182px;
position: relative;
/*z-index: 4;*/
}
.to_ocr {
width: 100%;
}
.demo {
border-radius: 5px;
width: 500px;
max-width: 100%;
text-align: left;
top:-50px;
overflow: hidden;
box-shadow: 0px 40px 60px 10px rgba(0, 0, 0, .2);
position: relative;
background-color: #fff;
opacity: 1;
-webkit-transition: .7s ease-out;
-moz-transition: .7s ease-out;
-ms-transition: .7s ease-out;
-o-transition: .7s ease-out;
transition: .7s ease-out;
}
/*.opaque {
top:-30;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, .2);
}*/
.demoheader {
overflow: hidden;
border-radius: 5px 5px 0px 0px;
font-size: 8.3px;
}
#canvas {
margin-left: auto;
margin-right: auto;
pointer-events: none;
z-index: 0;
position: absolute;
/* background-image: url(../img/logowhite.png);
background-size: cover;
*/}
.desc {
text-align: left;
font-size: 21px;
color: #343E70;
}
.vr {
display: inline-block;
height: 40px;
border-left: 1px solid #5C5C5C;
}
.getStarted {
display: inline-block;
background-color: #668EC3;
color: white;
font-size: 40px;
padding: 20px;
padding-left: 50px;
border-radius: 5px;
margin-top: 40;
padding-right: 50px;
cursor: pointer;
}
.randombold
{
font-size: 18px;
/*font-family: Georgia;*/
letter-spacing: .8px;
line-height: 37px;
}
.rant {
padding-left: 8%;
padding-right: 8%;
}
.npm {
margin-top: 20px;
padding-left: 15px;
background-color: #F3F3F3;
border-radius: 5px;
margin-bottom: 0px;
padding-top: 10px;
padding-bottom: 10px;
border-left: 6px solid #303061;
color: rgb(48, 48, 97);
font-size: 19px;
font-family: monospace;
}
.longasstag {
text-align: left;
white-space: normal;
word-break: break-all;
}
#code {
text-align: center;
width: 335px;
border-radius: 5px;
margin-top: 80px;
margin-bottom: 80px;
max-width: 100%;
}
.woloasdf {
padding-top: 8%;
}
.fork {
position: absolute;
top: 0;
right: 0;
border: 0;
z-index: 2;
}
.fork img {
width: 149px;
}
.two {
width: 100%;
display: -webkit-flex;
display: flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
justify-content: space-between;
-webkit-justify-content: space-between;
max-width: 1100px;
margin-left: auto;
margin-right: auto;
}
.demoheader .CodeMirror {
padding-bottom: 9px;
padding-top: 9px;
padding-left: 13px;
background-color: rgb(255, 238, 174);
}
hr {
border: none;
border-top: 1px solid #ddd;
margin: 0px;
}
.ocroutput {
position: relative;
z-index: 2;
}
.manylangs{
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
}
body {
padding: 0px;
margin: 0px;
font-family: Lato;
/*, Helvetica, Arial, sans-serif;*/
font-weight: 300;
background-color: white;
}
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;
color: #FFF;
background: #5A4E60;
border-radius: 5px;
border: solid 1px #fff;
}
button:hover {
cursor: pointer;
background: rgba(255, 255, 255, 1);
border: solid 1px #ddd;
}
@media (max-width: 1015px) {
button {
color: #fff;
background-color: rgba(0, 0, 0, 0)
}
/* .desc {
color: #FFFFFF;
text-shadow: 0px 0px 3px rgba(58, 58, 58, 1);
}
.desc a {
color: #FFEEAE;
}
*/
.getStarted {
font-size: 33px;
}
.noheight {
height: auto;
}
.demo {
top:0;
margin-bottom: 20px;
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, .2);
}
#logo {
height: auto;
}
.two {
justify-content: space-around;
-webkit-justify-content: space-around;
}
#code {
margin-top: 20px;
margin-bottom: 20px;
width: 400px;
}
#fork {
width: 28%;
}
}

229
demo.js

@ -0,0 +1,229 @@ @@ -0,0 +1,229 @@
var input = document.getElementById('input')
var input_overlay = document.getElementById('input-overlay')
var ioctx = input_overlay.getContext('2d')
// var output = document.getElementById('output')
// var output_overlay = document.getElementById('output-overlay')
var output_text = document.getElementById('log')
var demo_instructions = document.getElementById('demo-instructions')
var drop_instructions = [].slice.call(document.querySelectorAll('.drop-instructions'))
var options = [].slice.call(document.querySelectorAll('.option'))
// var octx = output.getContext('2d')
var language = 'eng'
var demoStarted = false
var lang_demo_images = {
eng: 'img/eng_bw.png',
chi_sim: 'img/chi_sim.png',
rus: 'img/rus.png'
}
var lang_drop_instructions = {
eng: 'an English',
chi_sim: 'a Chinese',
rus: 'a Russian'
}
var worker = new Tesseract.createWorker({
logger: progressUpdate,
});
function setUp(){
input_overlay.width = input.naturalWidth
input_overlay.height = input.naturalHeight
output_text.style.height = input.height + 'px'
}
setUp()
input.onload = setUp
function isOutputVisible(){
return output_text.getBoundingClientRect().top < dimensions.height
}
function startDemoIfVisible(argument) {
if(isOutputVisible() && !demoStarted) startDemo();
}
function startDemo(){
demoStarted = true
async function start(){
await worker.load();
await worker.loadLanguage('eng');
await worker.initialize('eng');
const { data } = await worker.recognize(input);
result(data);
input.removeEventListener('load', start)
}
if(input.complete) start();
else input.addEventListener('load', start)
}
// function progress(p){
// var text = JSON.stringify(p)
// // octx.clearRect(0, 0, output.width, output.height)
// // octx.textAlign = 'center'
// // octx.fillText(text, output.width/2, output.height/2)
// output_overlay.style.display = 'block'
// output_overlay.innerHTML += output_overlay.innerHTML.length ? "\n" + text : text
// output_overlay.scrollTop = output_overlay.scrollHeight;
// }
function progressUpdate(packet){
var log = document.getElementById('log');
if(log.firstChild && log.firstChild.status === packet.status){
if('progress' in packet){
var progress = log.firstChild.querySelector('progress')
progress.value = packet.progress
}
}else{
var line = document.createElement('div');
line.status = packet.status;
var status = document.createElement('div')
status.className = 'status'
status.appendChild(document.createTextNode(packet.status))
line.appendChild(status)
if('progress' in packet){
var progress = document.createElement('progress')
progress.value = packet.progress
progress.max = 1
line.appendChild(progress)
}
if(packet.status == 'done'){
var pre = document.createElement('pre')
pre.appendChild(document.createTextNode(packet.data.text))
line.innerHTML = ''
line.appendChild(pre)
}
log.insertBefore(line, log.firstChild)
}
}
function result(res){
// octx.clearRect(0, 0, output.width, output.height)
// octx.textAlign = 'left'
console.log('result was:', res)
// output_overlay.style.display = 'none'
// output_text.innerHTML = res.text
progressUpdate({ status: 'done', data: res })
res.words.forEach(function(w){
var b = w.bbox;
ioctx.strokeWidth = 2
ioctx.strokeStyle = 'red'
ioctx.strokeRect(b.x0, b.y0, b.x1-b.x0, b.y1-b.y0)
ioctx.beginPath()
ioctx.moveTo(w.baseline.x0, w.baseline.y0)
ioctx.lineTo(w.baseline.x1, w.baseline.y1)
ioctx.strokeStyle = 'green'
ioctx.stroke()
// octx.font = '20px Times';
// octx.font = 20 * (b.x1 - b.x0) / octx.measureText(w.text).width + "px Times";
// octx.fillText(w.text, b.x0, w.baseline.y0);
})
}
document.addEventListener('scroll', startDemoIfVisible)
startDemoIfVisible()
function clearOverLayAndOutput(){
ioctx.clearRect(0,0, input_overlay.width, input_overlay.height)
output_text.style.display = 'none'
demo_instructions.style.display = 'block'
// octx.clearRect(0,0,output.width, output.height)
}
// function displayPlayButtonFor(lang){
// output.addEventListener('click', function play(){
// output.removeEventListener('click', play)
// tessWorker.recognize(input, lang)
// .progress( progress )
// .then( result )
// })
// }
async function play(){
demo_instructions.style.display = 'none'
output_text.style.display = 'block'
output_text.innerHTML = ''
// output_overlay.innerHTML = ''
await worker.load();
await worker.loadLanguage(language);
await worker.initialize(language);
const { data } = await worker.recognize(input);
result(data);
}
options.forEach(function(option){
option.addEventListener('click', function(){
clearOverLayAndOutput()
drop_instructions.forEach(function(di){
di.innerHTML = lang_drop_instructions[option.lang]
})
language = option.lang
options.forEach(function(option){option.className = 'option'})
option.className = 'option selected'
if(option.lang in lang_demo_images){
input.src = lang_demo_images[option.lang]
// displayPlayButtonFor(option.lang)
}
})
})
document.body.addEventListener('drop', async function(e){
e.stopPropagation();
e.preventDefault();
var file = e.dataTransfer.files[0]
var reader = new FileReader();
reader.onload = function(e){
input.src = e.target.result;
input.onload = function(){
setUp();
}
};
reader.readAsDataURL(file);
await worker.load();
await worker.loadLanguage(language);
await worker.initialize(language);
const { data } = await worker.recognize(file);
result(data);
})

17
example.htm

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
<canvas id="c"></canvas>
<script type="text/javascript" src="./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'}).then( function(d){ console.log(d) } )
</script>

392
explorer/explorer.js

@ -0,0 +1,392 @@ @@ -0,0 +1,392 @@
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function array_join(array, glue) {
var new_array = [];
for (var i = 0; i < array.length; i++) {
new_array.push(array[i]);
if (i != array.length - 1) new_array.push(glue);
}
return new_array;
}
var Node = (function (_React$Component) {
_inherits(Node, _React$Component);
function Node(props) {
var _this = this;
_classCallCheck(this, Node);
_get(Object.getPrototypeOf(Node.prototype), "constructor", this).call(this, props);
this.toggleExpand = function (e) {
_this.setState({ expanded: !_this.state.expanded });
};
this.state = {
expanded: props.expanded
};
}
_createClass(Node, [{
key: "render",
value: function render() {
var _props = this.props;
var node = _props.node;
var label = _props.label;
var expanded = this.state.expanded;
var rep;
if (typeof node === "string") {
rep = React.createElement(TextNode, { html: label === "html", node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded });
} else if (typeof node === "boolean") {
rep = React.createElement(BooleanNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded });
} else if (typeof node === "number") {
rep = React.createElement(NumberNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded });
} else if (Array.isArray(node)) {
rep = React.createElement(ListNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded });
} else {
rep = React.createElement(ObjectNode, { node: node, className: "clickable", onClick: this.toggleExpand, toggleExpand: this.toggleExpand, expanded: expanded });
}
if (!label) {
return rep;
}
return React.createElement(
"span",
null,
React.createElement(
"span",
{ className: "label clickable", onClick: this.toggleExpand },
label
),
": ",
rep
);
}
}]);
return Node;
})(React.Component);
var TextNode = (function (_React$Component2) {
_inherits(TextNode, _React$Component2);
function TextNode() {
_classCallCheck(this, TextNode);
_get(Object.getPrototypeOf(TextNode.prototype), "constructor", this).apply(this, arguments);
}
_createClass(TextNode, [{
key: "render",
value: function render() {
var _props2 = this.props;
var node = _props2.node;
var expanded = _props2.expanded;
var html = _props2.html;
var toggleExpand = _props2.toggleExpand;
if (expanded) {
var content = node;
if (html) {
var content = [];
CodeMirror.runMode(node, { name: 'xml', htmlMode: true }, function (text, className) {
content.push(React.createElement(
"span",
{ className: "cm-" + className },
text
));
});
}
return React.createElement(
"span",
{ className: (html ? "cm-s-default html " : "") + "textNode expanded clickable", onClick: toggleExpand },
content
);
} else {
return React.createElement(
"span",
null,
React.createElement(
"span",
{ className: (html ? "html " : "") + "textNode clickable", onClick: toggleExpand },
node.substring(0, 30)
),
node.length > 30 ? React.createElement(Ellipsis, null) : ''
);
}
}
}]);
return TextNode;
})(React.Component);
var BooleanNode = (function (_React$Component3) {
_inherits(BooleanNode, _React$Component3);
function BooleanNode() {
_classCallCheck(this, BooleanNode);
_get(Object.getPrototypeOf(BooleanNode.prototype), "constructor", this).apply(this, arguments);
}
_createClass(BooleanNode, [{
key: "render",
value: function render() {
var node = this.props.node;
return React.createElement(
"span",
{ className: "booleanNode" },
JSON.stringify(node)
);
}
}]);
return BooleanNode;
})(React.Component);
var NumberNode = (function (_React$Component4) {
_inherits(NumberNode, _React$Component4);
function NumberNode() {
_classCallCheck(this, NumberNode);
_get(Object.getPrototypeOf(NumberNode.prototype), "constructor", this).apply(this, arguments);
}
_createClass(NumberNode, [{
key: "render",
value: function render() {
var node = this.props.node;
return React.createElement(
"span",
{ className: "numberNode" },
JSON.stringify(node)
);
}
}]);
return NumberNode;
})(React.Component);
var ListNode = (function (_React$Component5) {
_inherits(ListNode, _React$Component5);
function ListNode() {
_classCallCheck(this, ListNode);
_get(Object.getPrototypeOf(ListNode.prototype), "constructor", this).apply(this, arguments);
}
_createClass(ListNode, [{
key: "render",
value: function render() {
var _props3 = this.props;
var node = _props3.node;
var expanded = _props3.expanded;
var toggleExpand = _props3.toggleExpand;
if (expanded) {
return React.createElement(
"span",
{ className: "listNode expanded" },
React.createElement(
"span",
{ className: "clickable", onClick: toggleExpand },
"["
),
React.createElement("br", null),
React.createElement(
"span",
{ className: "indent" },
array_join(node.map(function (e, i) {
return React.createElement(Node, { node: e, key: i });
}), React.createElement(Comma, { br: true }))
),
React.createElement("br", null),
React.createElement(
"span",
{ onClick: toggleExpand },
"]"
)
);
} else {
return React.createElement(
"span",
{ className: "listNode clickable", onClick: toggleExpand },
"[",
node.length,
"]"
);
}
}
}]);
return ListNode;
})(React.Component);
var ObjectNode = (function (_React$Component6) {
_inherits(ObjectNode, _React$Component6);
function ObjectNode() {
_classCallCheck(this, ObjectNode);
_get(Object.getPrototypeOf(ObjectNode.prototype), "constructor", this).apply(this, arguments);
}
_createClass(ObjectNode, [{
key: "render",
value: function render() {
var _props4 = this.props;
var node = _props4.node;
var expanded = _props4.expanded;
var toggleExpand = _props4.toggleExpand;
if (null === node) {
return React.createElement(
"span",
{ className: "nullNode" },
"null"
);
} else if (expanded) {
return React.createElement(
"span",
{ className: "objectNode expanded" },
React.createElement(
"span",
{ className: "clickable", onClick: toggleExpand },
"{"
),
React.createElement("br", null),
React.createElement(
"span",
{ className: "indent" },
array_join(Object.keys(node).map(function (key) {
return React.createElement(Node, { node: node[key], label: key, key: key });
}), React.createElement(Comma, { br: true }))
),
React.createElement("br", null),
React.createElement(
"span",
{ onClick: toggleExpand },
"}"
)
);
} else {
var keys = Object.keys(node),
toolong = false;
if (keys.length > 4) {
keys = keys.slice(0, 4);
toolong = true;
}
var contents = array_join(keys.map(function (k) {
return React.createElement(
"span",
{ className: "label" },
k
);
}), React.createElement(Comma, null));
return React.createElement(
"span",
{ className: "objectNode clickable", onClick: toggleExpand },
"{",
contents,
toolong ? React.createElement(Ellipsis, null) : '',
"}"
);
}
}
}]);
return ObjectNode;
})(React.Component);
var Comma = (function (_React$Component7) {
_inherits(Comma, _React$Component7);
function Comma() {
_classCallCheck(this, Comma);
_get(Object.getPrototypeOf(Comma.prototype), "constructor", this).apply(this, arguments);
}
_createClass(Comma, [{
key: "render",
value: function render() {
var br = this.props.br;
return React.createElement(
"span",
{ className: "comma" },
", ",
br ? React.createElement("br", null) : ''
);
}
}]);
return Comma;
})(React.Component);
var Ellipsis = (function (_React$Component8) {
_inherits(Ellipsis, _React$Component8);
function Ellipsis() {
_classCallCheck(this, Ellipsis);
_get(Object.getPrototypeOf(Ellipsis.prototype), "constructor", this).apply(this, arguments);
}
_createClass(Ellipsis, [{
key: "render",
value: function render() {
return React.createElement(
"span",
{ className: "ellipsis" },
"..."
);
}
}]);
return Ellipsis;
})(React.Component);
var simplething = {
hello: 42,
derp: 324,
wumbo: [1, 2, 3, 4, "hello", {
blah: 32,
asdf: [],
walp: 32,
strings: "asdfsd"
}],
merp: {
blah: 32,
asdf: [],
walp: 32,
strings: "asdfsd"
},
strings: "asdfsd",
asdoijfo: {
strings: "asdfsd",
adfds: {
asdf: {
asdfadsf: {},
merp: 32
}
}
}
};
// React.render(<Node node={simplething} />, document.getElementById('explorer'))

19602
explorer/react.js vendored

File diff suppressed because it is too large Load Diff

16
explorer/react.min.js vendored

File diff suppressed because one or more lines are too long

BIN
img/bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
img/bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
img/chi_sim.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

BIN
img/deu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

BIN
img/eng.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
img/eng.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
img/eng_bw.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
img/fork.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
img/hayden.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
img/keyboard.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
img/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
img/logo.psd

Binary file not shown.

BIN
img/logo_small.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
img/logoblue.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
img/logowhite.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
img/meme.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 KiB

BIN
img/redstars.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 MiB

BIN
img/run.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
img/rus.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
img/shake.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 KiB

BIN
img/splash.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

BIN
img/starblur.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
img/stars.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

110
index.html

@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tesseract.js | Pure Javascript OCR for 100 Languages!</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<link href='https://fonts.googleapis.com/css?family=Lato:300,400' rel='stylesheet' type='text/css'>
<script>
if (location.protocol === "http:" && !location.host.startsWith('localhost')) {
location.replace("https" + window.location.href.slice(4));
}
</script>
</head>
<body ondragover="return false">
<div id="splash">
<div id="logo-wrap" class="header">
<canvas id="logo-canvas"></canvas>
<img id="logo-img" src="img/logowhite.png">
<div id='slogan'>Pure Javascript Multilingual OCR</div>
</div>
<div class='get-started-wrap'>
<a href="https://github.com/naptha/tesseract.js#tesseractjs">
<div class='get-started'>
<svg id="github" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
Get Started
</div>
</a>
</div>
</div>
<div id='demo'>
<!-- <div class="commentary">
<div id='demo-title'>Demo</div>
<p>Wherein we show you that Tesseract.js works, and let you try it with your own images.</p>
</div>
-->
<div class='commentary'>
<p><b>Tesseract.js</b> is a pure Javascript port of the popular <a href='https://github.com/tesseract-ocr/tesseract'>Tesseract OCR engine</a>. </p>
<p>This library supports <b>more than 100 languages</b>, automatic text <b>orientation and script detection</b>, a simple interface for reading paragraph, word, and character <b>bounding boxes</b>. Tesseract.js can run either in a <b>browser</b> and on a server with <b>NodeJS</b>. </p>
<p>Check out the <a href='https://github.com/naptha/tesseract.js#tesseractjs'>Example code and API docs on GitHub</a>.</p>
</div>
<div id='demo-body'>
<div id='options'>
<div class="option selected" lang='eng'>English Demo</div>
<div class="option" lang='chi_sim'>Chinese Demo</div>
<div class="option" lang='rus'>Russian Demo</div>
</div>
<div id='drop-instructions-main'><p>Drop <span class='drop-instructions'>an English</span> image on this page to OCR it!</p></div>
<div id='demo-content'>
<div>
<canvas id='input-overlay'></canvas>
<img id='input' src="img/eng_bw.png"/>
</div>
<div id='arrow'></div>
<div>
<!-- <div id='output-overlay'></div> -->
<!-- <textarea id='output-text'></textarea> -->
<div id='log'></div>
<div id='demo-instructions'>
<span id='clickme' onclick='play()'>Click here to recognize text in the demo image</span>, or drop <span class='drop-instructions'>an English</span> image anywhere on this page.
</div>
<!-- <canvas id='output'></canvas> -->
</div>
</div>
<div class='get-started-wrap'>
<br/>
<a href="https://github.com/naptha/tesseract.js#tesseractjs">
<div class='get-started'>
<svg id="github" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
Actually Get Started
</div>
</a>
</div>
</div>
</div>
<div id='footer'>
<span id="lengle">“Speaking of ways, pet, by the way, <b>there <i>is</i> such a thing as a tesseract</b>.”
<br>
<br>
<!-- Made with <img src="img/keyboard.png"> --> By <a href="https://twitter.com/biject">@biject</a>, <a href="https://twitter.com/antimatter15">@antimatter15</a> and <a href="https://github.com/jeromewu">@jeromewu</a></span>
</div>
<script src="animation/raf.js"></script>
<script src="animation/mouse.js"></script>
<script src="animation/dimensions.js"></script>
<script src="animation/hypercube.js"></script>
<script src="animation/animate.js"></script>
<script src="https://unpkg.com/tesseract.js@2.0.0/dist/tesseract.min.js" integrity="sha384-MTEb82ufpBJ2VCTmPZlD/+vgiT5z6zmOwqU/uDO9IobYm9xCOUEN0WH3czf6ppl8" crossorigin="anonymous"></script>
<script src="demo.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-83153710-3', 'auto', 'origin');
ga('origin.send', 'pageview');
ga('create', 'UA-139963961-1', 'auto', 'addon');
ga('addon.send', 'pageview');
</script>
</body>
</html>

163
index_dev.html

File diff suppressed because one or more lines are too long

162
index_old.html

File diff suppressed because one or more lines are too long

242
main.js

@ -0,0 +1,242 @@ @@ -0,0 +1,242 @@
'use strict';
function builddemo(id, val) {
var demo = document.getElementById(id);
var prog = demo.querySelector('.prog');
var out = demo.querySelector('.out');
var disp = demo.querySelector('.display');
var dctx = disp.getContext('2d');
disp.width = 0;
disp.height = 0;
demo.querySelector('.runbutton').onclick = function () {
setrunning(0);
run(editor);
editor.clear();
prog.setValue(0);
};
prog.setValue = function (v) {
prog.querySelector('div').style.width = v * 100 + '%';
};
function show_progress(p) {
setrunning(0);
console.log(p);
if (p.loaded_lang_model) prog.setValue(p.loaded_lang_model);
if (p.recognized) prog.setValue(p.recognized);
out.innerText = JSON.stringify(p);
}
function setrunning(v) {
if (v == 1) {
demo.querySelector('.running').style.display = 'none';
demo.querySelector('.notrunning').style.display = 'block';
// out.style.visibility = 'hidden'
} else {
demo.querySelector('.running').style.display = 'block';
demo.querySelector('.notrunning').style.display = 'none';
}
}
function display(result) {
React.render(React.createElement(Node, { node: result, expanded: true, label: "output_of_above_demo_plz_click_stuff" }), document.getElementById("explorer"));
setrunning(1);
out.innerText = "Lightning Speeeeeeed";
prog.value = 0;
console.log(result);
disp.width = demo.querySelector('.to_ocr').naturalWidth;
disp.height = demo.querySelector('.to_ocr').naturalHeight;
disp.style.width = demo.querySelector('.to_ocr').offsetWidth;
disp.style.height = demo.querySelector('.to_ocr').offsetHeight;
// dctx.shadowColor = "rgba(255,255,255,.1)";
// dctx.shadowOffsetX = 0;
// dctx.shadowOffsetY = 0;
// dctx.shadowBlur = 10;
// dctx.fillRect(0, 0, disp.width, disp.height);
var m = result.words.map(function (w) {
var b = w.bbox;
dctx.font = '20px Times';
var font = 20 * (b.x1 - b.x0) / dctx.measureText(w.text).width + "px Times";
return function k() {
dctx.font = font;
// dctx.font = '40px Times';
dctx.fillText(w.text, b.x0, w.baseline.y0);
// dctx.fillStyle='rgba(255,255,255,.3)'
// dctx.fillRect(b.x0, b.y0, b.x1 - b.x0, b.y1 - b.y0);
return font;
};
});
var times = 0;
var maxtimes = m.length + 100;
function draw(i) {
times++;
// dctx.fillStyle="rgba(30, 29, 49, .8)"
dctx.fillStyle = "rgba(0, 219, 157, " + Math.min(i / 100, 1) + ")";
// dctx.fillStyle="rgba(0, 219, 199, "+Math.min(i/100,1)+")"
// dctx.globalAlpha = .1;
dctx.clearRect(0, 0, disp.width, disp.height);
// dctx.fillRect(0, 0, disp.width, disp.height);
for (var j = 0; j < Math.min(i, m.length); j++) {
var asdf = Math.min(Math.max(i - j, 0), 100);
dctx.fillStyle = "rgba(0,0,0," + asdf * .01 + ")";
m[j]();
};
if (i < maxtimes) {
setTimeout(function () {
draw(i + 1);
}, 10);
} else {
console.log('done');
}
}
draw(0);
result.words.forEach(function (word, index) {
var wdiv = document.createElement('div');
wdiv.innerText = word.text + ' ';
wdiv.style['font-family'] = "Times";
wdiv.style.position = 'absolute';
var to_ocr = document.querySelector('.to_ocr');
var scale = to_ocr.offsetHeight / to_ocr.naturalHeight;
wdiv.style['font-size'] = parseFloat(m[index]().split('px')[0]) * scale;
wdiv.style.color = "rgba(0,0,0,0)";
wdiv.style.top = word.bbox.y0 * scale;
wdiv.style.left = word.bbox.x0 * scale;
wdiv.style.height = (word.bbox.y1 - word.bbox.y0) * scale;
wdiv.style.width = (word.bbox.x1 - word.bbox.x0) * scale;
document.querySelector('.ocroutput').appendChild(wdiv);
});
}
window.addEventListener('resize', function () {
disp.style.width = demo.querySelector('.to_ocr').offsetWidth;
disp.style.height = demo.querySelector('.to_ocr').offsetHeight;
});
function run(c) {
eval(c.getValue());
}
var editor = CodeMirror(demo.querySelector('.editor'), {
// lineNumbers: true,
viewportMargin: Infinity,
value: val
});
var sc = demo.querySelector('.demoheader');
// var scdiv = document.createElement('div');
// sc.appendChild(scdiv);
// scdiv.className = 'CodeMirror cm-s-default';
// // scdiv.className = 'cm-s-default'
// CodeMirror.runMode('<script src="http://tenso.rs/tesseract.js"></script>', {
// name: 'xml',
// htmlMode: true
// }, scdiv);
// var scripttag = CodeMirror(,{
// mode: {name: 'xml', htmlMode: true},
// readOnly: 'nocursor',
// value:
// });
editor.clear = function () {
dctx.clearRect(0, 0, disp.width, disp.height);
disp.style.height = 0;
document.querySelector('.ocroutput').innerHTML = '';
};
editor.img = demo.querySelector('.to_ocr');
editor.run = function () {
if (editor.img.complete) {
run(editor);
} else {
editor.img.onload = function () {
run(editor);
editor.img.onload = function () {};
};
}
};
return editor;
}
setTimeout(function () {
document.getElementById('wow').className += ' opaque';
}, 100);
var wow = builddemo('wow',
["var img = demo.querySelector('img.to_ocr')",
"Tesseract",
" .recognize( img )",
" .progress( show_progress )",
" .then( display ) // scroll down for full output",
" // you can edit this code"].join('\n'));
wow.run();
var tabs = Array.prototype.slice.call(document.querySelectorAll('.langlabel'));
var ltabs = Array.prototype.slice.call(document.querySelectorAll('.ltab'));
var langs = ['eng', 'chi_sim', 'rus', 'meme'];
var langims = langs.map(function (lang) {
var limg = new Image();
limg.src = 'img/' + lang + '.png';
return limg;
});
function setlang(i) {
tabs.forEach(function (t) {
t.className = 'langlabel';
});
tabs[i].className = 'langlabel selected';
console.log(tabs[i]);
wow.setValue(["var img = demo.querySelector('img.to_ocr')",
"Tesseract",
" .recognize( img, '"+langs[i]+"' )",
" .progress( show_progress )",
" .then( display ) // scroll down for full output",
" // you can edit this code"].join('\n'));
wow.img.src = 'img/' + langs[i] + '.png';
wow.clear();
wow.run()
}
ltabs.forEach(function (ltab, i) {
ltab.onclick = function () {
setlang(i);
};
});
tabs.forEach(function (tab, i) {
tab.onclick = function () {
setlang(i);
};
});
// document.querySelector('.getStarted')[0].onclick = function(){
// location.href = '#'
// location.href = '#get_started'
// }
// builddemo('demo2',
// "var img = demo.querySelector('img.to_ocr')\n\n\
// Tesseract\n\
// .recognize( img, {progress: show_progress, lang:'chi_sim'} )\n\
// .then( display )")

227
main_dev.js

@ -0,0 +1,227 @@ @@ -0,0 +1,227 @@
'use strict';
function builddemo(id, val) {
var demo = document.getElementById(id);
var prog = demo.querySelector('.prog');
var out = demo.querySelector('.out');
var disp = demo.querySelector('.display');
var dctx = disp.getContext('2d');
disp.width = 0;
disp.height = 0;
demo.querySelector('.runbutton').onclick = function () {
setrunning(0);
run(editor);
editor.clear();
prog.setValue(0);
};
prog.setValue = function (v) {
prog.querySelector('div').style.width = v * 100 + '%';
};
function show_progress(p) {
setrunning(0);
console.log(p);
if (p.loaded_lang_model) prog.setValue(p.loaded_lang_model);
if (p.recognized) prog.setValue(p.recognized);
out.innerText = JSON.stringify(p);
}
function setrunning(v) {
if (v == 1) {
demo.querySelector('.running').style.display = 'none';
demo.querySelector('.notrunning').style.display = 'block';
// out.style.visibility = 'hidden'
} else {
demo.querySelector('.running').style.display = 'block';
demo.querySelector('.notrunning').style.display = 'none';
}
}
function display(result) {
React.render(React.createElement(Node, { node: result, expanded: true, label: "output_of_above_demo_plz_click_stuff" }), document.getElementById("explorer"));
setrunning(1);
out.innerText = "Lightning Speeeeeeed";
prog.value = 0;
console.log(result);
disp.width = demo.querySelector('.to_ocr').naturalWidth;
disp.height = demo.querySelector('.to_ocr').naturalHeight;
disp.style.width = demo.querySelector('.to_ocr').offsetWidth;
disp.style.height = demo.querySelector('.to_ocr').offsetHeight;
dctx.shadowColor = "rgba(255,255,255,.1)";
dctx.shadowOffsetX = 0;
dctx.shadowOffsetY = 0;
dctx.shadowBlur = 10;
dctx.fillRect(0, 0, disp.width, disp.height);
var m = result.words.map(function (w) {
var b = w.bbox;
dctx.font = '20px Times';
var font = 20 * (b.x1 - b.x0) / dctx.measureText(w.text).width + "px Times";
var k = function k() {
dctx.font = font;
dctx.fillText(w.text, b.x0, w.baseline.y0);
return font;
};
return k;
});
var times = 0;
var maxtimes = m.length + 100;
function draw(i) {
times++;
// dctx.fillStyle="rgba(30, 29, 49, .8)"
dctx.fillStyle = "rgba(0, 219, 157, " + Math.min(i / 100, 1) + ")";
// dctx.fillStyle="rgba(0, 219, 199, "+Math.min(i/100,1)+")"
// dctx.globalAlpha = .1;
dctx.clearRect(0, 0, disp.width, disp.height);
dctx.fillRect(0, 0, disp.width, disp.height);
for (var j = 0; j < Math.min(i, m.length); j++) {
var asdf = Math.min(Math.max(i - j, 0), 100);
dctx.fillStyle = "rgba(255,255,255," + asdf * .01 + ")";
m[j]();
};
if (i < maxtimes) {
setTimeout(function () {
draw(i + 1);
}, 10);
} else {
console.log('done');
}
}
draw(0);
result.words.forEach(function (word, index) {
var wdiv = document.createElement('div');
wdiv.innerText = word.text + ' ';
wdiv.style['font-family'] = "Times";
wdiv.style.position = 'absolute';
var to_ocr = document.querySelector('.to_ocr');
var scale = to_ocr.offsetHeight / to_ocr.naturalHeight;
wdiv.style['font-size'] = parseFloat(m[index]().split('px')[0]) * scale;
wdiv.style.color = "rgba(0,0,0,0)";
wdiv.style.top = word.bbox.y0 * scale;
wdiv.style.left = word.bbox.x0 * scale;
wdiv.style.height = (word.bbox.y1 - word.bbox.y0) * scale;
wdiv.style.width = (word.bbox.x1 - word.bbox.x0) * scale;
document.querySelector('.ocroutput').appendChild(wdiv);
});
}
window.addEventListener('resize', function () {
disp.style.width = demo.querySelector('.to_ocr').offsetWidth;
disp.style.height = demo.querySelector('.to_ocr').offsetHeight;
});
function run(c) {
eval(c.getValue());
}
var editor = CodeMirror(demo.querySelector('.editor'), {
// lineNumbers: true,
viewportMargin: Infinity,
value: val
});
var sc = demo.querySelector('.demoheader');
var scdiv = document.createElement('div');
sc.appendChild(scdiv);
scdiv.className = 'CodeMirror cm-s-default';
// scdiv.className = 'cm-s-default'
CodeMirror.runMode('<script src="http://localhost:1234/master/lib/Tesseract_dev.js"></script>', {
name: 'xml',
htmlMode: true
}, scdiv);
// var scripttag = CodeMirror(,{
// mode: {name: 'xml', htmlMode: true},
// readOnly: 'nocursor',
// value:
// });
editor.clear = function () {
dctx.clearRect(0, 0, disp.width, disp.height);
document.querySelector('.ocroutput').innerHTML = '';
};
editor.img = demo.querySelector('.to_ocr');
editor.run = function () {
if (editor.img.complete) {
run(editor);
} else {
editor.img.onload = function () {
run(editor);
editor.img.onload = function () {};
};
}
};
return editor;
}
setTimeout(function () {
document.getElementById('wow').className += ' opaque';
}, 100);
var wow = builddemo('wow', "var img = demo.querySelector('img.to_ocr')\n\n" + "Tesseract\n" + " .recognize( img, {\n" + " progress: show_progress} )\n" + " .then( display ) // scroll down for full output\n" + " // you can edit this code");
wow.run();
var tabs = Array.prototype.slice.call(document.querySelectorAll('.langlabel'));
var ltabs = Array.prototype.slice.call(document.querySelectorAll('.ltab'));
var langs = ['eng', 'chi_sim', 'rus', 'meme'];
var langims = langs.map(function (lang) {
var limg = new Image();
limg.src = 'img/' + lang + '.png';
return limg;
});
function setlang(i) {
tabs.forEach(function (t) {
t.className = 'langlabel';
});
tabs[i].className = 'langlabel selected';
console.log(tabs[i]);
wow.setValue("var img = demo.querySelector('img.to_ocr')\n\n" + "Tesseract\n" + " .recognize( img, {\n" + " progress: show_progress, lang: '" + langs[i] + "'} )\n" + " .then( display ) // scroll down for full output\n" + " // you can edit this code");
wow.img.src = 'img/' + langs[i] + '.png';
wow.clear();
}
ltabs.forEach(function (ltab, i) {
ltab.onclick = function () {
setlang(i);
};
});
tabs.forEach(function (tab, i) {
tab.onclick = function () {
setlang(i);
};
});
// document.querySelector('.getStarted')[0].onclick = function(){
// location.href = '#'
// location.href = '#get_started'
// }
// builddemo('demo2',
// "var img = demo.querySelector('img.to_ocr')\n\n\
// Tesseract\n\
// .recognize( img, {progress: show_progress, lang:'chi_sim'} )\n\
// .then( display )")

23
package.json

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
{
"name": "tesseract.js",
"version": "1.0.0",
"description": "",
"main": "Tesseract.js",
"dependencies": {
"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"
}

61
perlinish/perlinish.js

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
var svg = (function(colors){
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = 10
canvas.height = 2
var upscale = 10
var im = ctx.getImageData(0,0,canvas.width,canvas.height)
for (var i = 0; i < im.data.length; i+=4) {
im.data[i] = Math.round(Math.random()*255)
im.data[i+1] = Math.round(Math.random()*255)
im.data[i+2] = Math.round(Math.random()*255)
im.data[i+3] = 255
};
ctx.putImageData(im,0,0)
var url = canvas.toDataURL()
im = new Image()
im.src = url
canvas.width *= upscale
canvas.height *= upscale
ctx.drawImage(im,0,0,canvas.width, canvas.height)
im = ctx.getImageData(0,0,canvas.width,canvas.height)
var xmlns = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(xmlns, 'svg')
svg.setAttribute('viewBox',"0 0 "+im.width+" "+im.height)
for (var i = 0; i < im.data.length; i+=4) {
var mindist = 195075
var mincolor = [0,0,0]
var pix = [im.data[i],im.data[i+1],im.data[i+2]]
for (var j = 0; j < colors.length; j++) {
var color = colors[j]
var d0 = color[0] - pix[0]
var d1 = color[1] - pix[1]
var d2 = color[2] - pix[2]
var d = Math.abs(d0)+Math.abs(d1)+Math.abs(d2)
if (d<mindist) {
mindist = d
mincolor = color
}
};
var n = i/4
var elem = document.createElementNS(xmlns, "rect");
elem.setAttributeNS(null,"x",n%im.width);
elem.setAttributeNS(null,"y",Math.floor(n/im.width));
elem.setAttributeNS(null,"width",1.5);
elem.setAttributeNS(null,"height",1.5);
elem.setAttributeNS(null,"fill", 'rgba('+Math.min(mincolor[0]+0%2*20,255)+', '+mincolor[1]+', '+mincolor[2]+',1)');
svg.appendChild(elem);
};
return svg
})([
[39, 198, 249],
[6, 188, 249],
// [154, 218, 198],
[116, 218, 251],
[91, 211, 251]])
document.getElementById('marterial').appendChild(svg)

191
src/explorer.js

@ -0,0 +1,191 @@ @@ -0,0 +1,191 @@
function array_join(array, glue){
var new_array = []
for(var i = 0; i < array.length; i++){
new_array.push(array[i])
if(i != array.length - 1) new_array.push(glue);
}
return new_array
}
class Node extends React.Component {
constructor(props){
super(props)
this.state = {
expanded: props.expanded
}
}
toggleExpand = e => {
this.setState({expanded: !this.state.expanded})
}
render(){
var {node, label} = this.props
var {expanded} = this.state
var rep
if(typeof node === "string"){
rep = <TextNode html={label === "html"} node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/>
}
else if(typeof node === "boolean"){
rep = <BooleanNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/>
}
else if(typeof node === "number"){
rep = <NumberNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/>
}
else if(Array.isArray(node)){
rep = <ListNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/>
}
else {
rep = <ObjectNode node={node} className="clickable" onClick={this.toggleExpand} toggleExpand={this.toggleExpand} expanded={expanded}/>
}
if(!label){
return rep
}
return <span><span className="label clickable" onClick={this.toggleExpand}>{label}</span>: {rep}</span>
}
}
class TextNode extends React.Component {
render(){
var {node, expanded, html, toggleExpand} = this.props
if(expanded){
var content = node
if (html) {
var content = []
CodeMirror.runMode(node, {name: 'xml', htmlMode: true}, (text, className) => {
content.push(<span className={"cm-"+className}>{text}</span>)
})
}
return <span className={(html ? "cm-s-default html ":"") + "textNode expanded clickable"} onClick={toggleExpand} >{content}</span>
}
else{
return <span>
<span className={(html? "html " : "")+"textNode clickable"} onClick={toggleExpand} >{node.substring(0,30)}</span>
{node.length > 30 ? <Ellipsis /> : ''}
</span>
}
}
}
class BooleanNode extends React.Component {
render(){
var {node} = this.props
return <span className="booleanNode">{JSON.stringify(node)}</span>
}
}
class NumberNode extends React.Component {
render(){
var {node} = this.props
return <span className="numberNode">{JSON.stringify(node)}</span>
}
}
class ListNode extends React.Component {
render(){
var {node, expanded, toggleExpand} = this.props
if(expanded){
return <span className="listNode expanded">
<span className="clickable" onClick={toggleExpand}>[</span>
<br />
<span className="indent">
{array_join(node.map((e, i) =>
<Node node={e} key={i}/>
),<Comma br/>)}
</span>
<br />
<span onClick={toggleExpand}>]</span>
</span>
}
else{
return <span className="listNode clickable" onClick={toggleExpand}>[{node.length}]</span>
}
}
}
class ObjectNode extends React.Component {
render(){
var {node, expanded, toggleExpand} = this.props
if(null === node){
return <span className="nullNode">null</span>
}
else if(expanded){
return <span className="objectNode expanded">
<span className="clickable" onClick={toggleExpand}>{"{"}</span>
<br />
<span className="indent">
{array_join(Object.keys(node).map(
key => <Node node={node[key]} label={key} key={key}/>
),<Comma br/>)}
</span>
<br />
<span onClick={toggleExpand}>{"}"}</span>
</span>
}
else{
var keys = Object.keys(node), toolong = false
if (keys.length > 4) {
keys = keys.slice(0,4)
toolong = true
}
var contents = array_join(keys.map(k => <span className="label">{k}</span>), <Comma />)
return <span className="objectNode clickable" onClick={toggleExpand} >{"{"}{contents}{toolong?<Ellipsis /> : ''}{"}"}</span>
}
}
}
class Comma extends React.Component {
render(){
var {br} = this.props
return <span className="comma">, {br?<br />:''}</span>
}
}
class Ellipsis extends React.Component {
render(){
return <span className="ellipsis">...</span>
}
}
var simplething = {
hello: 42,
derp: 324,
wumbo: [
1,
2,
3,
4,
"hello",
{
blah: 32,
asdf: [],
walp: 32,
strings: "asdfsd",
}
],
merp: {
blah: 32,
asdf: [],
walp: 32,
strings: "asdfsd",
},
strings: "asdfsd",
asdoijfo: {
strings: "asdfsd",
adfds: {
asdf: {
asdfadsf: {},
merp: 32
}
}
}
}
// React.render(<Node node={simplething} />, document.getElementById('explorer'))

163
src/index.html

File diff suppressed because one or more lines are too long

247
src/main.js

@ -0,0 +1,247 @@ @@ -0,0 +1,247 @@
function builddemo(id, val){
var demo = document.getElementById(id)
var prog = demo.querySelector('.prog')
var out = demo.querySelector('.out')
var disp = demo.querySelector('.display')
var dctx = disp.getContext('2d')
disp.width = 0
disp.height = 0
demo.querySelector('.runbutton').onclick = function(){
setrunning(0)
run(editor)
editor.clear()
prog.setValue(0)
}
prog.setValue = function(v){
prog.querySelector('div').style.width = v*100+'%'
}
function show_progress(p){
setrunning(0)
console.log(p)
if(p.loaded_lang_model) prog.setValue(p.loaded_lang_model)
if(p.recognized) prog.setValue(p.recognized)
out.innerText = JSON.stringify(p)
}
function setrunning(v){
if (v == 1) {
demo.querySelector('.running').style.display = 'none'
demo.querySelector('.notrunning').style.display = 'block'
// out.style.visibility = 'hidden'
}
else {
demo.querySelector('.running').style.display = 'block'
demo.querySelector('.notrunning').style.display = 'none'
}
}
function display(result) {
React.render(React.createElement(Node, { node: result, expanded: true, label: "output_of_above_demo_plz_click_stuff"}), document.getElementById("explorer"));
setrunning(1)
out.innerText = "Lightning Speeeeeeed"
prog.value = 0
console.log(result)
disp.width = demo.querySelector('.to_ocr').naturalWidth
disp.height = demo.querySelector('.to_ocr').naturalHeight
disp.style.width = demo.querySelector('.to_ocr').offsetWidth
disp.style.height = demo.querySelector('.to_ocr').offsetHeight
dctx.shadowColor = "rgba(255,255,255,.1)"
dctx.shadowOffsetX = 0;
dctx.shadowOffsetY = 0;
dctx.shadowBlur = 10;
dctx.fillRect(0,0,disp.width, disp.height)
var m = result.words.map(function(w){
var b = w.bbox
dctx.font = '20px Times'
var font = 20*(b.x1-b.x0)/dctx.measureText(w.text).width+"px Times"
var k = function(){
dctx.font = font
dctx.fillText(w.text, b.x0, w.baseline.y0);
return font
}
return k
})
var times = 0
var maxtimes = m.length + 100
function draw(i){
times++
// dctx.fillStyle="rgba(30, 29, 49, .8)"
dctx.fillStyle="rgba(0, 219, 157, "+Math.min(i/100,1)+")"
// dctx.fillStyle="rgba(0, 219, 199, "+Math.min(i/100,1)+")"
// dctx.globalAlpha = .1;
dctx.clearRect(0,0,disp.width, disp.height)
dctx.fillRect(0,0,disp.width, disp.height)
for (var j = 0; j < Math.min(i,m.length); j++) {
var asdf = Math.min(Math.max(i - j,0), 100)
dctx.fillStyle = "rgba(255,255,255,"+asdf*.01+")"
m[j]()
};
if(i<maxtimes){
setTimeout(function(){
draw(i+1)
},10)
}
else{
console.log('done')
}
}
draw(0)
result.words.forEach(function(word, index){
var wdiv = document.createElement('div')
wdiv.innerText = word.text+' '
wdiv.style['font-family'] = "Times"
wdiv.style.position = 'absolute'
var to_ocr = document.querySelector('.to_ocr')
var scale = to_ocr.offsetHeight / to_ocr.naturalHeight
wdiv.style['font-size'] = parseFloat(m[index]().split('px')[0]) * scale
wdiv.style.color = "rgba(0,0,0,0)"
wdiv.style.top = word.bbox.y0 * scale
wdiv.style.left = word.bbox.x0 * scale
wdiv.style.height = (word.bbox.y1 - word.bbox.y0)*scale
wdiv.style.width = (word.bbox.x1 - word.bbox.x0)*scale
document.querySelector('.ocroutput').appendChild(wdiv)
})
}
window.addEventListener('resize', function() {
disp.style.width = demo.querySelector('.to_ocr').offsetWidth
disp.style.height = demo.querySelector('.to_ocr').offsetHeight
})
function run(c){
eval(c.getValue())
}
var editor = CodeMirror(demo.querySelector('.editor'),{
// lineNumbers: true,
viewportMargin: Infinity,
value: val
});
var sc = demo.querySelector('.demoheader')
var scdiv = document.createElement('div')
sc.appendChild(scdiv)
scdiv.className = 'CodeMirror cm-s-default'
// scdiv.className = 'cm-s-default'
CodeMirror.runMode('<script src="__tesseractjs__"></script>', {
name: 'xml',
htmlMode: true
}, scdiv)
// var scripttag = CodeMirror(,{
// mode: {name: 'xml', htmlMode: true},
// readOnly: 'nocursor',
// value:
// });
editor.clear = function(){
dctx.clearRect(0,0,disp.width, disp.height)
document.querySelector('.ocroutput').innerHTML = ''
}
editor.img = demo.querySelector('.to_ocr')
editor.run = function(){
if (editor.img.complete) {
run(editor)
} else{
editor.img.onload = function(){
run(editor)
editor.img.onload = function(){}
}
}
}
return editor
}
setTimeout(function(){
document.getElementById('wow').className += ' opaque'
}, 100)
var wow = builddemo('wow',
"var img = demo.querySelector('img.to_ocr')\n\n"
+"Tesseract\n"
+" .recognize( img, {\n"
+" progress: show_progress} )\n"
+" .then( display ) // scroll down for full output\n"
+" // you can edit this code")
wow.run()
var tabs = Array.prototype.slice.call(document.querySelectorAll('.langlabel'))
var ltabs = Array.prototype.slice.call(document.querySelectorAll('.ltab'))
var langs = ['eng', 'chi_sim', 'rus', 'meme']
var langims = langs.map(lang => {
var limg = new Image()
limg.src = 'img/'+lang+'.png'
return limg
})
function setlang(i){
tabs.forEach(function(t){
t.className = 'langlabel'
})
tabs[i].className = 'langlabel selected'
console.log(tabs[i])
wow.setValue(
"var img = demo.querySelector('img.to_ocr')\n\n"
+"Tesseract\n"
+" .recognize( img, {\n"
+" progress: show_progress, lang: '"+langs[i]+"'} )\n"
+" .then( display ) // scroll down for full output\n"
+" // you can edit this code")
wow.img.src = 'img/'+langs[i]+'.png'
wow.clear()
}
ltabs.forEach(function(ltab,i){
ltab.onclick = function(){
setlang(i)
}
})
tabs.forEach(function(tab,i){
tab.onclick = function(){
setlang(i)
}
})
// document.querySelector('.getStarted')[0].onclick = function(){
// location.href = '#'
// location.href = '#get_started'
// }
// builddemo('demo2',
// "var img = demo.querySelector('img.to_ocr')\n\n\
// Tesseract\n\
// .recognize( img, {progress: show_progress, lang:'chi_sim'} )\n\
// .then( display )")

90
test.htm

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
<html>
<head>
<title></title>
<style type="text/css">
body {
margin: 0px
}
</style>
</head>
<body>
<script type="text/javascript">
var svg = (function(colors){
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = 10
canvas.height = 5
var upscale = 10
var im = ctx.getImageData(0,0,canvas.width,canvas.height)
for (var i = 0; i < im.data.length; i+=4) {
im.data[i] = Math.round(Math.random()*255)
im.data[i+1] = Math.round(Math.random()*255)
im.data[i+2] = Math.round(Math.random()*255)
im.data[i+3] = 255
};
ctx.putImageData(im,0,0)
var url = canvas.toDataURL()
im = new Image()
im.src = url
canvas.width *= upscale
canvas.height *= upscale
ctx.drawImage(im,0,0,canvas.width, canvas.height)
im = ctx.getImageData(0,0,canvas.width,canvas.height)
var xmlns = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(xmlns, 'svg')
svg.setAttribute('viewBox',"0 0 "+im.width+" "+im.height)
for (var i = 0; i < im.data.length; i+=4) {
var mindist = 195075
var mincolor = [0,0,0]
var pix = [im.data[i],im.data[i+1],im.data[i+2]]
for (var j = 0; j < colors.length; j++) {
var color = colors[j]
var d0 = color[0] - pix[0]
var d1 = color[1] - pix[1]
var d2 = color[2] - pix[2]
var d = Math.abs(d0)+Math.abs(d1)+Math.abs(d2)
if (d<mindist) {
mindist = d
mincolor = color
}
};
var n = i/4
ctx.fillStyle = 'rgba('+Math.min(mincolor[0]+n%2*20,255)+', '+mincolor[1]+', '+mincolor[2]+',1)'
var elem = document.createElementNS(xmlns, "rect");
elem.setAttributeNS(null,"x",n%im.width);
elem.setAttributeNS(null,"y",Math.floor(n/im.width));
elem.setAttributeNS(null,"width",1.5);
elem.setAttributeNS(null,"height",1.5);
elem.setAttributeNS(null,"fill", 'rgba('+Math.min(mincolor[0]+n%2*20,255)+', '+mincolor[1]+', '+mincolor[2]+',1)');
svg.appendChild(elem);
};
return svg
})([[39, 198, 249], [6, 188, 249], [116, 218, 251], [91, 211, 251]])
document.body.appendChild(svg)
// wrap.appendChild(svg)
// document.body.style.backgroundImage = "url(data:image/svg+xml;utf8,"+wrap.innerHTML+")"
// document.styleSheets[0].insertRule("body {background: url('data:image/svg+xml;utf8,"+wrap.innerHTML+"')}",0)
// ctx.putImageData(im,0,0)
// canvas.style.width = 2000
// canvas.style.height = 2000
// document.body.appendChild(canvas)
</script>
<!-- <script type="text/javascript" src="wolo.js"></script> -->
</body>
</html>

583
worker_src/madeline.js

File diff suppressed because one or more lines are too long

324
worker_src/worker.js

@ -1,324 +0,0 @@ @@ -1,324 +0,0 @@
importScripts('madeline.js')
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 recognize = (function createTesseractInstance(){
var Module = Tesseract304({
TOTAL_MEMORY: 90e6,
TesseractProgress: function(percent){
console.log('recognized',percent+'%')
}
})
var base = new Module.TessBaseAPI()
var loaded_langs = []
var loadLanguage = (function(){
return (function loadLanguage(lang, cb){ // NodeJS style callback
if(loaded_langs.indexOf(lang) != -1){
cb(null, lang)
}
else{
Module.FS_createPath("/","tessdata",true,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){console.log('loading',lang,'language model:',Math.round(e.loaded/filesizes[lang]*100)+'%')}
xhr.onload = function(){
if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) {
console.log('unzipping language model...')
var data = new Uint8Array(unzip(new Uint8Array(xhr.response)))
console.log(lang +".traineddata", 'sucessfully unzipped')
Module.FS_createDataFile('tessdata', lang +".traineddata", data, true, false);
loaded_langs.push(lang)
cb(null, lang)
} else cb(xhr, null);
}
xhr.send(null)
}
})
})()
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])
}
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));
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;
var coeff_r = 4899, coeff_g = 9617, coeff_b = 1868;
for (var i = 0, j = 0; i <= srcLength_16; i += 16, j += 4) {
// convert to grayscale 4 pixels at a time;
// add 8192 = 1<<13 so for int n, float k >= .5, ((n + k)*(1<<14) >> 14) = 1 + ((n)*(1<<14) >> 14)
dst[j] = src[i+3] //(((src[i] * coeff_r + src[i+1] * coeff_g + src[i+2] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
dst[j + 1] = src[i+4+3]//(((src[i+4] * coeff_r + src[i+5] * coeff_g + src[i+6] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
dst[j + 2] = src[i+8+3]//(((src[i+8] * coeff_r + src[i+9] * coeff_g + src[i+10] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
dst[j + 3] = src[i+12+3]//(((src[i+12] * coeff_r + src[i+13] * coeff_g + src[i+14] * coeff_b + 8192) >> 14) * src[i+3]) >> 8 + 255 - src[i+3];
}
for (; i < srcLength; i += 4, ++j) //finish up
dst[j] = (src[i] * coeff_r + src[i+1] * coeff_g + src[i+2] * coeff_b + 8192) >> 14;
image = dst;
// for(var i = 0; i < image.length; i++) image[i] = image[i] > 128;
}
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);
cb(err, null)
}
base.Init(null, lang)
for (var option in options) {
if (options.hasOwnProperty(option)) {
base.SetVariable(option, options[option]);
console.log('setting', option, '=', options[option]);
}
}
base.SetImage(Module.wrapPointer(ptr), width, height, 1, width)
base.SetRectangle(0, 0, width, height)
base.GetUTF8Text()
var everything = DumpLiterallyEverything()
base.End();
Module._free(ptr);
cb(null, everything)
})
}
// base._simple = _simple
return recognize
})()
onmessage = function(e) {
recognize(e.data.image, e.data.lang, e.data.options, function(err, result){
postMessage({err:err, result: result})
})
}
Loading…
Cancel
Save