diff --git a/reader/vendor/cbrjs/cbr.js-refactor-in-progress b/reader/vendor/cbrjs/cbr.js-refactor-in-progress deleted file mode 100644 index d9c8f0d..0000000 --- a/reader/vendor/cbrjs/cbr.js-refactor-in-progress +++ /dev/null @@ -1,2712 +0,0 @@ -var CBRJS = {}; -CBRJS.VERSION = "0.0.1"; - -CBRJS.Render = {}; -CBRJS.reader = {}; - -CBRJS.Reader = function(bookPath, _options) { - - var $progressbar = $('.bar'); - - function extractImages(url, opts) { - - var images = []; - var xhr = new XMLHttpRequest(); - var re_file_ext = new RegExp(/\.([a-z]+)$/); - var filename = decodeURIComponent(url.split('/').pop()); - var archive_class = ({ cbz: 'Unzipper', cbr: 'Unrarrer' })[filename.toLowerCase().match(re_file_ext)[1]]; - var options = $.extend({ - start: function () {}, - extract: function (page_url) {}, - progress: function (percent_complete) {}, - finish: function (images) {}, - }, opts); - - if (!archive_class) { - alert('invalid file type, only cbz and cbr are supported.'); - return false; - } - - xhr.responseType = "arraybuffer"; - - xhr.open('GET',url, true); - - options.start(filename); - console.log("filename: " + filename); - - xhr.onprogress = function (e) { - if (e.lengthComputable) { - $progressbar.css('width', Math.floor((e.loaded / e.total) * 100) + '%'); - } - } - - xhr.onloadstart = function (e) { - $progressbar.css('width', '0%'); - } - - xhr.onload = function () { - if ((this.status === 200) && this.response) { - var done = false; - var ua = new bitjs.archive[archive_class](this.response, 'vendor/bitjs/'); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.START, function (e) { - $progressbar.css('width', '0%'); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.EXTRACT, function (e) { - - var mimetype, blob, url; - var file_extension = e.unarchivedFile.filename.toLowerCase().match(re_file_ext)[1]; - - switch (file_extension) { - case 'jpg': - case 'jpeg': - mimetype = 'image/jpeg'; - break; - case 'png': - mimetype = 'image/png'; - break; - case 'gif': - mimetype = 'image/gif'; - break; - default: - return false; - } - - blob = new Blob([e.unarchivedFile.fileData], { type: mimetype }); - url = window.URL.createObjectURL(blob); - - images.push(url); - - options.extract(url, blob); - console.log(url, file_extension); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.PROGRESS, function (e) { - options.progress(Math.floor(e.currentBytesUnarchived / e.totalUncompressedBytesInArchive * 100)); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.FINISH, function (e) { - options.finish(images); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.ERROR, function (e) { - $('#message').text('Failed to extract images from archive, file corrupted?'); - - }); - } - - ua.start(); - }; - - xhr.send(); - } - - function openComicArchive(url) { - - console.log("openComicArchive " + url); - - var title, page = 0; - - extractImages(url, { - start: function (filename) { - this.filename = filename; - $('#message').text('Opening ' + filename); - $('#progressbar').show(); - }, - extract: function (url, blob) { - // $('body').append($('').attr('src', url).css('width', '10px')); - console.log(url, Math.floor(blob.size / 1024)); - $('#message').text('extracting page #' + ++page); - }, - progress: function (percent_complete) { - $progressbar.css('width', percent_complete + '%'); - }, - finish: function (pages) { - - var name = this.filename.replace(/\.[a-z]+$/, ''); - var id = encodeURIComponent(name.toLowerCase()); - var book = new ComicBook('cbreader', pages, {vendorPath: 'vendor/'}); - - document.title = name; - - $('#progressbar').hide(); - $('#cbreader').show(); - - book.draw(); - - $(window).on('resize', function () { - book.draw(); - }); - } - }); - } - - openComicArchive(bookPath); - - return this; -}; - - -/*! - * Pixastic - JavaScript Image Processing - * http://pixastic.com/ - * Copyright 2012, Jacob Seidelin - * - * Dual licensed under the MPL 1.1 or GPLv3 licenses. - * http://pixastic.com/license-mpl.txt - * http://pixastic.com/license-gpl-3.0.txt - * - */ - - var Pixastic = (function() { - - var worker; - - function createImageData(ctx, width, height) { - if (ctx.createImageData) { - return ctx.createImageData(width, height); - } else { - return ctx.getImageData(0, 0, width, height); - } - } - - function Pixastic(ctx, workerControlPath) { - - var P = {}, - width = ctx.canvas.width, - height = ctx.canvas.height, - queue = [], - workerControlPath = workerControlPath || "vendor/pixastic/"; - - if (!worker) { - if (typeof window.Worker != "undefined") { - try { - worker = new window.Worker(workerControlPath + "pixastic.worker.control.js"); - } catch(e) { - if (location.protocol == "file:") { - Pixastic.log("Could not create native worker, running from file://") - } else { - Pixastic.log("Could not create native worker.") - } - } - } - if (!worker) { - worker = new Pixastic.Worker(); - } - } - - for (var e in Pixastic.Effects) { - if (Pixastic.Effects.hasOwnProperty(e)) { - (function(e) { - P[e] = function(options) { - queue.push({ - effect : e, - options : options - }); - return P; - } - - P.done = function(callback, progress) { - var inData, outData; - - try { - inData = ctx.getImageData(0, 0, width, height); - } catch(e) { - if (location.protocol == "file:") { - throw new Error("Could not access image data, running from file://"); - } else { - throw new Error("Could not access image data, is canvas tainted by cross-origin data?"); - } - } - - outData = createImageData(ctx, width, height); - - worker.postMessage({ - queue : queue, - inData : inData, - outData : outData, - width : width, - height : height - }); - - worker.onmessage = function(message) { - var d = message.data; - switch (d.event) { - case "done" : - ctx.putImageData(d.data, 0, 0); - if (callback) { - callback(); - } - if (progress) { - progress(1); - } - break; - case "progress" : - if (progress) { - progress(d.data); - } - break; - case "error" : - break; - } - } - - if (progress) { - progress(0); - } - } - })(e); - } - } - return P; - } - - - Pixastic.Worker = function() { - var me = this; - function processMessage(data) { - var queue = data.queue, - inData = data.inData, - outData = data.outData, - width = data.width, - height = data.height, - tmpData; - - for (var i=0;i 0) { - tmpData = inData; - inData = outData; - outData = tmpData; - } - - if (typeof importScripts == "function") { - progressCallback = function(p) { - me.onmessage({ - data : { - event : "progress", - data : (i + p) / queue.length - } - }); - return p; - } - } - - Pixastic.Effects[e](inData.data, outData.data, width, height, options, progressCallback); - - me.onmessage({ - data : { - event : "progress", - data : (i+1) / queue.length - } - }); - } - - me.onmessage({ - data : { - event : "done", - data : outData - } - }); - } - - this.postMessage = function(data) { - setTimeout(function() { - processMessage(data) - }, 0); - }; - - this.onmessage = function() {}; - - } - - - - Pixastic.log = function(str) { - if (typeof console != "undefined" && console.log) { - console.log("Pixastic: " + str); - } - }; - - function toCanvas(o) { - var canvas; - if (typeof o == "object") { - if (typeof o.tagName == "string") { - if (o.tagName.toLowerCase() == "canvas" || o.tagName.toLowerCase() == "img") { - canvas = document.createElement("canvas"); - canvas.width = o.width; - canvas.height = o.height; - canvas.getContext("2d").drawImage(o, 0,0); - } - } else if ((window.ImageData && o instanceof window.ImageData) - || (typeof o.width == "number" && typeof o.height == "number" && typeof o.data == "object")) { - canvas = document.createElement("canvas"); - canvas.width = o.width; - canvas.height = o.height; - canvas.getContext("2d").putImageData(o, 0, 0); - } - } - return canvas; - }; - - function toImage(o) { - var canvas = toCanvas(o), - image = new Image(); - image.width = canvas.width; - image.height = canvas.height; - image.src = canvas.toDataURL(); - return image; - }; - - function toImageData(o) { - var canvas = toCanvas(o), - ctx = canvas.getContext("2d"); - return ctx.getImageData(0, 0, canvas.width, canvas.height); - }; - - function histogram(imageData) { - var values = [], - i, p, - data = imageData.data, - round = Math.round, - maxValue, - n = imageData.width * imageData.height; - - for (i=0;i<256;i++) { - values[i] = 0; - } - - for (i=0;i maxValue) { - maxValue = values[i]; - } - } - - return { - maxValue : maxValue, - values : values - }; - } - - Pixastic.toCanvas = toCanvas; - Pixastic.toImage = toImage; - Pixastic.toImageData = toImageData; - Pixastic.histogram = histogram; - - Pixastic.Color = { - rgb2hsl : function(r, g, b) { - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - if (r > 255) r = 0; - if (g > 255) g = 0; - if (b > 255) b = 0; - }, - - rgb2hsv : function(r, g, b) { - }, - - rgb2hex : function(r, g, b) { - }, - - hsl2rgb : function(h, s, l) { - }, - - hsv2rgb : function(h, s, v) { - } - - } - - return Pixastic; - -})(); - - -Pixastic.Effects = (function() { - - function defaultOptions(options, defaults) { - var O = {}; - for (var opt in defaults) { - if (typeof options[opt] == "undefined") { - O[opt] = defaults[opt]; - } else { - O[opt] = options[opt]; - } - } - return O; - } - - function clamp(val, min, max) { - return Math.min(max, Math.max(min, val)); - } - - function convolve3x3(inData, outData, width, height, kernel, progress, alpha, invert, mono) { - var idx, r, g, b, a, - pyc, pyp, pyn, - pxc, pxp, pxn, - x, y, - - prog, lastProg = 0, - n = width * height * 4, - - k00 = kernel[0][0], k01 = kernel[0][1], k02 = kernel[0][2], - k10 = kernel[1][0], k11 = kernel[1][1], k12 = kernel[1][2], - k20 = kernel[2][0], k21 = kernel[2][1], k22 = kernel[2][2], - - p00, p01, p02, - p10, p11, p12, - p20, p21, p22; - - for (y=0;y= width-1) pyn = pyc; - - for (x=0;x= width-1) pxn = pxc; - - p00 = pyp + pxp; p01 = pyp + pxc; p02 = pyp + pxn; - p10 = pyc + pxp; p11 = pyc + pxc; p12 = pyc + pxn; - p20 = pyn + pxp; p21 = pyn + pxc; p22 = pyn + pxn; - - r = inData[p00] * k00 + inData[p01] * k01 + inData[p02] * k02 - + inData[p10] * k10 + inData[p11] * k11 + inData[p12] * k12 - + inData[p20] * k20 + inData[p21] * k21 + inData[p22] * k22; - - g = inData[p00 + 1] * k00 + inData[p01 + 1] * k01 + inData[p02 + 1] * k02 - + inData[p10 + 1] * k10 + inData[p11 + 1] * k11 + inData[p12 + 1] * k12 - + inData[p20 + 1] * k20 + inData[p21 + 1] * k21 + inData[p22 + 1] * k22; - - b = inData[p00 + 2] * k00 + inData[p01 + 2] * k01 + inData[p02 + 2] * k02 - + inData[p10 + 2] * k10 + inData[p11 + 2] * k11 + inData[p12 + 2] * k12 - + inData[p20 + 2] * k20 + inData[p21 + 2] * k21 + inData[p22 + 2] * k22; - - if (alpha) { - a = inData[p00 + 3] * k00 + inData[p01 + 3] * k01 + inData[p02 + 3] * k02 - + inData[p10 + 3] * k10 + inData[p11 + 3] * k11 + inData[p12 + 3] * k12 - + inData[p20 + 3] * k20 + inData[p21 + 3] * k21 + inData[p22 + 3] * k22; - } else { - a = inData[idx+3]; - } - - if (mono) { - r = g = b = (r + g + b) / 3; - } - if (invert) { - r = 255 - r; - g = 255 - g; - b = 255 - b; - } - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = a; - - if (progress) { - prog = (idx/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - } - - function convolve5x5(inData, outData, width, height, kernel, progress, alpha, invert, mono) { - var idx, r, g, b, a, - pyc, pyp, pyn, pypp, pynn, - pxc, pxp, pxn, pxpp, pxnn, - x, y, - - prog, lastProg = 0, - n = width * height * 4, - - k00 = kernel[0][0], k01 = kernel[0][1], k02 = kernel[0][2], k03 = kernel[0][3], k04 = kernel[0][4], - k10 = kernel[1][0], k11 = kernel[1][1], k12 = kernel[1][2], k13 = kernel[1][3], k14 = kernel[1][4], - k20 = kernel[2][0], k21 = kernel[2][1], k22 = kernel[2][2], k23 = kernel[2][3], k24 = kernel[2][4], - k30 = kernel[3][0], k31 = kernel[3][1], k32 = kernel[3][2], k33 = kernel[3][3], k34 = kernel[3][4], - k40 = kernel[4][0], k41 = kernel[4][1], k42 = kernel[4][2], k43 = kernel[4][3], k44 = kernel[4][4], - - p00, p01, p02, p03, p04, - p10, p11, p12, p13, p14, - p20, p21, p22, p23, p24, - p30, p31, p32, p33, p34, - p40, p41, p42, p43, p44; - - for (y=0;y= width-1) pyn = pyc; - if (y < 2) pypp = pyp; - if (y >= width-2) pynn = pyn; - - for (x=0;x= width-1) pxn = pxc; - if (x < 2) pxpp = pxp; - if (x >= width-2) pxnn = pxn; - - p00 = pypp + pxpp; p01 = pypp + pxp; p02 = pypp + pxc; p03 = pypp + pxn; p04 = pypp + pxnn; - p10 = pyp + pxpp; p11 = pyp + pxp; p12 = pyp + pxc; p13 = pyp + pxn; p14 = pyp + pxnn; - p20 = pyc + pxpp; p21 = pyc + pxp; p22 = pyc + pxc; p23 = pyc + pxn; p24 = pyc + pxnn; - p30 = pyn + pxpp; p31 = pyn + pxp; p32 = pyn + pxc; p33 = pyn + pxn; p34 = pyn + pxnn; - p40 = pynn + pxpp; p41 = pynn + pxp; p42 = pynn + pxc; p43 = pynn + pxn; p44 = pynn + pxnn; - - r = inData[p00] * k00 + inData[p01] * k01 + inData[p02] * k02 + inData[p03] * k04 + inData[p02] * k04 - + inData[p10] * k10 + inData[p11] * k11 + inData[p12] * k12 + inData[p13] * k14 + inData[p12] * k14 - + inData[p20] * k20 + inData[p21] * k21 + inData[p22] * k22 + inData[p23] * k24 + inData[p22] * k24 - + inData[p30] * k30 + inData[p31] * k31 + inData[p32] * k32 + inData[p33] * k34 + inData[p32] * k34 - + inData[p40] * k40 + inData[p41] * k41 + inData[p42] * k42 + inData[p43] * k44 + inData[p42] * k44; - - g = inData[p00+1] * k00 + inData[p01+1] * k01 + inData[p02+1] * k02 + inData[p03+1] * k04 + inData[p02+1] * k04 - + inData[p10+1] * k10 + inData[p11+1] * k11 + inData[p12+1] * k12 + inData[p13+1] * k14 + inData[p12+1] * k14 - + inData[p20+1] * k20 + inData[p21+1] * k21 + inData[p22+1] * k22 + inData[p23+1] * k24 + inData[p22+1] * k24 - + inData[p30+1] * k30 + inData[p31+1] * k31 + inData[p32+1] * k32 + inData[p33+1] * k34 + inData[p32+1] * k34 - + inData[p40+1] * k40 + inData[p41+1] * k41 + inData[p42+1] * k42 + inData[p43+1] * k44 + inData[p42+1] * k44; - - b = inData[p00+2] * k00 + inData[p01+2] * k01 + inData[p02+2] * k02 + inData[p03+2] * k04 + inData[p02+2] * k04 - + inData[p10+2] * k10 + inData[p11+2] * k11 + inData[p12+2] * k12 + inData[p13+2] * k14 + inData[p12+2] * k14 - + inData[p20+2] * k20 + inData[p21+2] * k21 + inData[p22+2] * k22 + inData[p23+2] * k24 + inData[p22+2] * k24 - + inData[p30+2] * k30 + inData[p31+2] * k31 + inData[p32+2] * k32 + inData[p33+2] * k34 + inData[p32+2] * k34 - + inData[p40+2] * k40 + inData[p41+2] * k41 + inData[p42+2] * k42 + inData[p43+2] * k44 + inData[p42+2] * k44; - - if (alpha) { - a = inData[p00+3] * k00 + inData[p01+3] * k01 + inData[p02+3] * k02 + inData[p03+3] * k04 + inData[p02+3] * k04 - + inData[p10+3] * k10 + inData[p11+3] * k11 + inData[p12+3] * k12 + inData[p13+3] * k14 + inData[p12+3] * k14 - + inData[p20+3] * k20 + inData[p21+3] * k21 + inData[p22+3] * k22 + inData[p23+3] * k24 + inData[p22+3] * k24 - + inData[p30+3] * k30 + inData[p31+3] * k31 + inData[p32+3] * k32 + inData[p33+3] * k34 + inData[p32+3] * k34 - + inData[p40+3] * k40 + inData[p41+3] * k41 + inData[p42+3] * k42 + inData[p43+3] * k44 + inData[p42+3] * k44; - } else { - a = inData[idx+3]; - } - - if (mono) { - r = g = b = (r + g + b) / 3; - } - - if (invert) { - r = 255 - r; - g = 255 - g; - b = 255 - b; - } - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = a; - - if (progress) { - prog = (idx/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - } - - function gaussian(inData, outData, width, height, kernelSize, progress) { - var r, g, b, a, idx, - n = width * height * 4, - x, y, i, j, - inx, iny, w, - tmpData = [], - maxKernelSize = 13, - kernelSize = clamp(kernelSize, 3, maxKernelSize), - k1 = -kernelSize / 2 + (kernelSize % 2 ? 0.5 : 0), - k2 = kernelSize + k1, - weights, - kernels = [[1]], - prog, lastProg = 0; - - - for (i=1;i= width) { - inx = width - 1; - } - - idx = (iny * width + inx) * 4; - - r += inData[idx] * w; - g += inData[idx + 1] * w; - b += inData[idx + 2] * w; - a += inData[idx + 3] * w; - - } - - idx = (y * width + x) * 4; - - tmpData[idx] = r; - tmpData[idx+1] = g; - tmpData[idx+2] = b; - tmpData[idx+3] = a; - - if (progress) { - prog = (idx/n*50 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - - lastProg = 0; - - // pass 2 - for (y=0;y= height) { - iny = height - 1; - } - - idx = (iny * width + inx) * 4; - - r += tmpData[idx] * w; - g += tmpData[idx + 1] * w; - b += tmpData[idx + 2] * w; - a += tmpData[idx + 3] * w; - } - - idx = (y * width + x) * 4; - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = a; - - if (progress) { - prog = 0.5 + (idx/n*50 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - } - - - return { - - invert : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0; - - for (i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - sepia : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - r, g, b; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - solarize : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - r, g, b; - - for (i=0;i 127 ? 255 - r : r; - outData[i+1] = g > 127 ? 255 - g : g; - outData[i+2] = b > 127 ? 255 - b : b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - brightness : function(inData, outData, width, height, options, progress) { - options = defaultOptions(options, { - brightness : 0, - contrast : 0 - }); - - var contrast = clamp(options.contrast, -1, 1) / 2, - brightness = 1 + clamp(options.brightness, -1, 1), - prog, lastProg = 0, - r, g, b, - n = width * height * 4; - - var brightMul = brightness < 0 ? - brightness : brightness; - var brightAdd = brightness < 0 ? 0 : brightness; - - contrast = 0.5 * Math.tan((contrast + 1) * Math.PI/4); - contrastAdd = - (contrast - 0.5) * 255; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - desaturate : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - level; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - lighten : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - mul = 1 + clamp(options.amount, 0, 1); - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - noise : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - amount = clamp(options.amount, 0, 1), - strength = clamp(options.strength, 0, 1), - mono = !!options.mono, - random = Math.random, - rnd, r, g, b; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - flipv : function(inData, outData, width, height, options, progress) { - var inPix, outPix, - n = width * height * 4, - prog, lastProg = 0, - x, y; - for (y=0;y> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }, - - fliph : function(inData, outData, width, height, options, progress) { - var inPix, outPix, - n = width * height * 4, - prog, lastProg = 0, - x, y; - for (y=0;y> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }, - - blur : function(inData, outData, width, height, options, progress) { - gaussian(inData, outData, width, height, options.kernelSize, progress); - }, - - glow : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - i, r, g, b, - amount = options.amount, - tmpData = [], - gaussProgress, - prog, lastProg = 0; - - if (progress) { - gaussProgress = function(p) { - progress(p * 0.8); - return p; - } - } - - gaussian(inData, tmpData, width, height, options.kernelSize, gaussProgress); - - for (i=0;i 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - outData[i] = r; - outData[i+1] = g; - outData[i+2] = b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = 0.8 + (i/n*100 >> 0) / 100 * 0.2; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - convolve3x3 : function(inData, outData, width, height, options, progress) { - convolve3x3(inData, outData, width, height, options.kernel, progress); - }, - - convolve5x5 : function(inData, outData, width, height, options, progress) { - convolve5x5(inData, outData, width, height, options.kernel, progress); - }, - - // A 3x3 high-pass filter - sharpen3x3 : function(inData, outData, width, height, options, progress) { - var a = - clamp(options.strength, 0, 1); - convolve3x3( - inData, outData, width, height, - [[a, a, a], - [a, 1-a*8, a], - [a, a, a]], - progress - ); - }, - - // A 5x5 high-pass filter - sharpen5x5 : function(inData, outData, width, height, options, progress) { - var a = - clamp(options.strength, 0, 1); - convolve5x5( - inData, outData, width, height, - [[a, a, a, a, a], - [a, a, a, a, a], - [a, a, 1-a*24, a, a], - [a, a, a, a, a], - [a, a, a, a, a]], - progress - ); - }, - - // A 3x3 low-pass mean filter - soften3x3 : function(inData, outData, width, height, options, progress) { - var c = 1/9; - convolve3x3( - inData, outData, width, height, - [[c, c, c], - [c, c, c], - [c, c, c]], - progress - ); - }, - - // A 5x5 low-pass mean filter - soften5x5 : function(inData, outData, width, height, options, progress) { - var c = 1/25; - convolve5x5( - inData, outData, width, height, - [[c, c, c, c, c], - [c, c, c, c, c], - [c, c, c, c, c], - [c, c, c, c, c], - [c, c, c, c, c]], - progress - ); - }, - - // A 3x3 Cross edge-detect - crossedges : function(inData, outData, width, height, options, progress) { - var a = clamp(options.strength, 0, 1) * 5 - convolve3x3( - inData, outData, width, height, - [[ 0, -a, 0], - [-a, 0, a], - [ 0, a, 0]], - progress, - false, true - ); - }, - - // 3x3 directional emboss - emboss : function(inData, outData, width, height, options, progress) { - var amount = options.amount, - angle = options.angle, - x = Math.cos(-angle) * amount, - y = Math.sin(-angle) * amount, - n = width * height * 4, - - a00 = -x - y, - a10 = -x, - a20 = y - x, - a01 = -y, - a21 = y, - a02 = -y + x, - a12 = x, - a22 = y + x, - - tmpData = [], - - prog, lastProg = 0, - convProgress; - - if (progress) { - convProgress = function(p) { - progress(p * 0.5) - return p; - }; - } - - convolve3x3( - inData, tmpData, width, height, - [[a00, a01, a02], - [a10, 0, a12], - [a20, a21, a22]] - ); - - for (var i=0;i> 0) / 100 * 0.5; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - - // A 3x3 Sobel edge detect (similar to Photoshop's) - findedges : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - i, - data1 = [], - data2 = [], - gr1, gr2, gg1, gg2, gb1, gb2, - prog, lastProg = 0, - convProgress1, convProgress2; - - if (progress) { - convProgress1 = function(p) { - progress(p * 0.4); - return p; - }; - convProgress2 = function(p) { - progress(0.4 + p * 0.4); - return p; - }; - } - - convolve3x3(inData, data1, width, height, - [[-1, 0, 1], - [-2, 0, 2], - [-1, 0, 1]] - ); - convolve3x3(inData, data2, width, height, - [[-1, -2, -1], - [ 0, 0, 0], - [ 1, 2, 1]] - ); - - for (i=0;i> 0) / 100 * 0.2; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - // A 3x3 edge enhance - edgeenhance3x3 : function(inData, outData, width, height, options, progress) { - convolve3x3( - inData, outData, width, height, - [[-1/9, -1/9, -1/9], - [-1/9, 17/9, -1/9], - [-1/9, -1/9, -1/9]], - progress - ); - }, - - // A 5x5 edge enhance - edgeenhance5x5 : function(inData, outData, width, height, options, progress) { - convolve5x5( - inData, outData, width, height, - [[-1/25, -1/25, -1/25, -1/25, -1/25], - [-1/25, -1/25, -1/25, -1/25, -1/25], - [-1/25, -1/25, 49/25, -1/25, -1/25], - [-1/25, -1/25, -1/25, -1/25, -1/25], - [-1/25, -1/25, -1/25, -1/25, -1/25]], - progress - ); - }, - - // A 3x3 Laplacian edge-detect - laplace3x3 : function(inData, outData, width, height, options, progress) { - convolve3x3( - inData, outData, width, height, - [[-1, -1, -1], - [-1, 8, -1], - [-1, -1, -1]], - progress, - false, true, true - ); - }, - - // A 5x5 Laplacian edge-detect - laplace5x5 : function(inData, outData, width, height, options, progress) { - convolve5x5( - inData, outData, width, height, - [[-1, -1, -1, -1, -1], - [-1, -1, -1, -1, -1], - [-1, -1, 24, -1, -1], - [-1, -1, -1, -1, -1], - [-1, -1, -1, -1, -1]], - progress, - false, true, true - ); - }, - - coloradjust : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - r, g, b, - prog, lastProg = 0, - ar = clamp(options.r, -1, 1) * 255, - ag = clamp(options.g, -1, 1) * 255, - ab = clamp(options.b, -1, 1) * 255; - - for (var i=0;i 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - outData[i] = r; - outData[i+1] = g; - outData[i+2] = b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - colorfilter : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - i, r, g, b, - luminosity = !!options.luminosity, - prog, lastProg = 0, - min, max, h, l, h1, chroma, tmp, m, - ar = clamp(options.r, 0, 1), - ag = clamp(options.g, 0, 1), - ab = clamp(options.b, 0, 1); - - for (i=0;i max) max = g; - if (b > max) max = b; - if (g < min) min = g; - if (b < min) min = b; - chroma = (max - min); - - if (r == max) { - h = ((g - b) / chroma) % 6; - } else if (g == max) { - h = ((b - r) / chroma) + 2; - } else { - h = ((r - g) / chroma) + 4; - } - - h1 = h >> 0; - tmp = chroma * (h - h1); - r = g = b = l - (r * 0.3 + g * 0.59 + b * 0.11); - - if (h1 == 0) { - r += chroma; - g += tmp; - } else if (h1 == 1) { - r += chroma - tmp; - g += chroma; - } else if (h1 == 2) { - g += chroma; - b += tmp; - } else if (h1 == 3) { - g += chroma - tmp; - b += chroma; - } else if (h1 == 4) { - r += tmp; - b += chroma; - } else if (h1 == 5) { - r += chroma; - b += chroma - tmp; - } - } - - outData[i] = r * 255; - outData[i+1] = g * 255; - outData[i+2] = b * 255; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - hsl : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - hue = clamp(options.hue, -1, 1), - saturation = clamp(options.saturation, -1, 1), - lightness = clamp(options.lightness, -1, 1), - satMul = 1 + saturation * (saturation < 0 ? 1 : 2), - lightMul = lightness < 0 ? 1 + lightness : 1 - lightness, - lightAdd = lightness < 0 ? 0 : lightness * 255, - vs, ms, vm, h, s, l, v, m, vmh, sextant, - prog, lastProg = 0; - - hue = (hue * 6) % 6; - - for (var i=0;i vs) vs = g; - if (b > vs) vs = b; - ms = r; - if (g < ms) ms = g; - if (b < ms) ms = b; - vm = (vs-ms); - l = (ms+vs)/510; - - if (l > 0 && vm > 0) { - if (l <= 0.5) { - s = vm / (vs+ms) * satMul; - if (s > 1) s = 1; - v = (l * (1+s)); - } else { - s = vm / (510-vs-ms) * satMul; - if (s > 1) s = 1; - v = (l+s - l*s); - } - if (r == vs) { - if (g == ms) { - h = 5 + ((vs-b)/vm) + hue; - } else { - h = 1 - ((vs-g)/vm) + hue; - } - } else if (g == vs) { - if (b == ms) { - h = 1 + ((vs-r)/vm) + hue; - } else { - h = 3 - ((vs-b)/vm) + hue; - } - } else { - if (r == ms) { - h = 3 + ((vs-g)/vm) + hue; - } else { - h = 5 - ((vs-r)/vm) + hue; - } - } - if (h < 0) h += 6; - if (h >= 6) h -= 6; - m = (l + l - v); - sextant = h >> 0; - vmh = (v - m) * (h - sextant); - if (sextant == 0) { - r = v; - g = m + vmh; - b = m; - } else if (sextant == 1) { - r = v - vmh; - g = v; - b = m; - } else if (sextant == 2) { - r = m; - g = v; - b = m + vmh; - } else if (sextant == 3) { - r = m; - g = v - vmh; - b = v; - } else if (sextant == 4) { - r = m + vmh; - g = m; - b = v; - } else if (sextant == 5) { - r = v; - g = m; - b = v - vmh; - } - - r *= 255; - g *= 255; - b *= 255; - } - } - - r = r * lightMul + lightAdd; - g = g * lightMul + lightAdd; - b = b * lightMul + lightAdd; - - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - - outData[i] = r; - outData[i+1] = g; - outData[i+2] = b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - posterize : function(inData, outData, width, height, options, progress) { - var numLevels = clamp(options.levels, 2, 256), - numAreas = 256 / numLevels, - numValues = 256 / (numLevels-1), - r, g, b, - n = width * height * 4, - prog, lastProg = 0; - - for (i=0;i>0); - outData[i+1] = numValues * ((inData[i+1] / numAreas)>>0); - outData[i+2] = numValues * ((inData[i+2] / numAreas)>>0); - - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - - }, - - removenoise : function(inData, outData, width, height, options, progress) { - var r, g, b, c, y, x, idx, - pyc, pyp, pyn, - pxc, pxp, pxn, - minR, minG, minB, maxR, maxG, maxB, - n, prog, lastProg = 0; - - n = width * height * 4; - - for (y=0;y= width-1) pyn = pyc; - - for (x=0;x= width-1) pxn = pxc; - - minR = maxR = inData[pyc + pxp]; - c = inData[pyc + pxn]; - if (c < minR) minR = c; - if (c > maxR) maxR = c; - c = inData[pyp + pxc]; - if (c < minR) minR = c; - if (c > maxR) maxR = c; - c = inData[pyn + pxc]; - if (c < minR) minR = c; - if (c > maxR) maxR = c; - - minG = inData[pyc + pxp + 1]; - c = inData[pyc + pxn + 1]; - if (c < minG) minG = c; - c = inData[pyp + pxc + 1]; - if (c < minG) minG = c; - c = inData[pyn + pxc + 1]; - if (c < minG) minG = c; - - minB = inData[pyc + pxp + 2]; - c = inData[pyc + pxn + 2]; - if (c < minB) minB = c; - c = inData[pyp + pxc + 2]; - if (c < minB) minB = c; - c = inData[pyn + pxc + 2]; - if (c < minB) minB = c; - - r = inData[idx] - g = inData[idx + 1] - b = inData[idx + 2] - - if (r < minR) r = minR; - if (r > maxR) r = maxR; - if (g < minG) g = minG; - if (g > maxG) g = maxG; - if (b < minB) b = minB; - if (b > maxB) b = maxB; - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = inData[idx+3]; - - if (progress) { - prog = (idx/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }, - - mosaic : function(inData, outData, width, height, options, progress) { - - var blockSize = clamp(options.blockSize, 1, Math.max(width, height)), - yBlocks = Math.ceil(height / blockSize), - xBlocks = Math.ceil(width / blockSize), - y0, y1, x0, x1, idx, pidx, - n = yBlocks * xBlocks, - prog, lastProg = 0; - - for (i=0, y0=0, bidx=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - y0 = y1; - } - }, - - equalize : function(inData, outData, width, height, options, progress) { - var n = width * height, p, i, level, ratio, - prog, lastProg; - var round = Math.round; - // build histogram - var pdf = new Array(256); - for (i=0;i<256;i++) { - pdf[i] = 0; - } - - for (i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }; - -})(); - - -Pixastic.Worker = function() { - var me = this; - function processMessage(data) { - var queue = data.queue, - inData = data.inData, - outData = data.outData, - width = data.width, - height = data.height, - tmpData; - - for (var i=0;i 0) { - tmpData = inData; - inData = outData; - outData = tmpData; - } - - Pixastic.Effects[e](inData.data, outData.data, width, height, options); - - me.onmessage({ - data : { - event : "progress", - data : (i+1) / queue.length - } - }); - } - - me.onmessage({ - data : { - event : "done", - data : outData - } - }); - } - - this.postMessage = function(data) { - setTimeout(function() { - processMessage(data) - }, 0); - } - - this.onmessage = function() {}; - -} - -CBRJS.Book = (function($) { - - 'use strict'; - - /** - * Merge two arrays. Any properties in b will replace the same properties in - * a. New properties from b will be added to a. - * - * @param a {Object} - * @param b {Object} - */ - function merge(a, b) { - - var prop; - - if (typeof b === 'undefined') { - b = {}; - } - - for (prop in a) { - if (a.hasOwnProperty(prop)) { - if (prop in b) { - continue; - } - b[prop] = a[prop]; - } - } - - return b; - } - - /** - * Exception class. Always throw an instance of this when throwing exceptions. - * - * @param {String} type - * @param {Object} object - * @returns {ComicBookException} - */ - var ComicBookException = { - INVALID_ACTION: 'invalid action', - INVALID_PAGE: 'invalid page', - INVALID_PAGE_TYPE: 'invalid page type', - UNDEFINED_CONTROL: 'undefined control', - INVALID_ZOOM_MODE: 'invalid zoom mode', - INVALID_NAVIGATION_EVENT: 'invalid navigation event' - }; - - function ComicBook(id, srcs, opts) { - - var self = this; - var canvas_id = id; // canvas element id - this.srcs = srcs; // array of image srcs for pages - - var defaults = { - displayMode: 'double', // single / double - zoomMode: 'fitWindow', // manual / fitWidth / fitWindow - manga: false, // true / false - enhance: {}, - keyboard: { - next: 78, - previous: 80, - toolbar: 84, - toggleLayout: 76 - }, - vendorPath: 'vendor/', - forward_buffer: 3 - }; - - this.isMobile = false; - - // mobile enhancements - if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(navigator.userAgent)) { - this.isMobile = true; - document.body.classList.add('mobile'); - defaults.displayMode = 'single'; - - window.addEventListener('load', function() { - setTimeout(function() { - window.scrollTo(0, 1); - }, 0); - }); - } - - var options = merge(defaults, opts); // options array for internal use - - var no_pages = srcs.length; - var pages = []; // array of preloaded Image objects - var canvas; // the HTML5 canvas object - var context; // the 2d drawing context - var loaded = []; // the images that have been loaded so far - var scale = 1; // page zoom scale, 1 = 100% - var is_double_page_spread = false; - var controlsRendered = false; // have the user controls been inserted into the dom yet? - var page_requested = false; // used to request non preloaded pages - var shiv = false; - - /** - * Gets the window.innerWidth - scrollbars - */ - function windowWidth() { - - var height = window.innerHeight + 1; - - if (shiv === false) { - shiv = $(document.createElement('div')) - .attr('id', 'cb-width-shiv') - .css({ - width: '100%', - position: 'absolute', - top: 0, - zIndex: '-1000' - }); - - $('body').append(shiv); - } - - shiv.height(height); - - return shiv.innerWidth(); - } - - /** - * enables the back button - */ - function checkHash() { - - var hash = getHash(); - - if (hash !== pointer && loaded.indexOf(hash) > -1) { - pointer = hash; - self.draw(); - } - } - - function getHash() { - var hash = parseInt(location.hash.substring(1), 10) - 1 || 0; - if (hash < 0) { - setHash(0); - hash = 0; - } - return hash; - } - - function setHash(pageNo) { - location.hash = pageNo; - } - - // page hash on first load - var hash = getHash(); - - // the current page, can pass a default as a url hash - var pointer = (hash < srcs.length) ? hash : 0; - - /** - * Setup the canvas element for use throughout the class. - * - * @see #ComicBook.prototype.draw - * @see #ComicBook.prototype.enhance - */ - function init() { - - // setup canvas - canvas = document.getElementById(canvas_id); - context = canvas.getContext('2d'); - - // render user controls - if (controlsRendered === false) { - self.renderControls(); - controlsRendered = true; - } - - // add page controls - window.addEventListener('keydown', self.navigation, false); - window.addEventListener('hashchange', checkHash, false); - } - - window.addEventListener('touchstart', function(e) { - var $el = $(e.target); - if ($el.attr('id') === 'comic') { - self.toggleToolbar(); - } - if ($el.data('toggle') === 'dropdown') { - $el.siblings('.dropdown').toggle(); - } - }, false); - - return this; - }: -})(jQuery); - -/** - * bind controls to events. - */ -CBRJS.Book.prototype.renderControls = function() { - - var controls = {}, - $toolbar; - - var static_controls = $.find('.control'); - - $('.control').each(function() { - - controls[$(this).attr('name')] = $(this); - - // add event listeners to controls that specify callbacks - $(this).find('*').andSelf().filter('[data-action][data-trigger]').each(function() { - - var $this = $(this); - var trigger = $this.data('trigger'); - var action = $this.data('action'); - - // trigger a direct method if exists - if (typeof self[$this.data('action')] === 'function') { - $this.on(trigger, self[action]); - } - - // throw an event to be caught outside if the app code - $this.on(trigger, function(e) { - $(self).trigger(trigger, e); - }); - }); - }); - - this.controls = controls; - - $toolbar = this.getControl('toolbar'); - $toolbar - .find('.manga-' + options.manga).show().end() - .find('.manga-' + !options.manga).hide().end() - .find('.layout').hide().end().find('.layout-' + options.displayMode).show(); - -}; - -CBRJS.Book.prototype.getControl = function(control) { - if (typeof this.controls[control] !== 'object') { - throw ComicBookException.UNDEFINED_CONTROL + ' ' + control; - } - return this.controls[control]; -}; - -CBRJS.Book.prototype.showControl = function(control) { - this.getControl(control).show().addClass('open'); -}; - -CBRJS.Book.prototype.hideControl = function(control) { - this.getControl(control).removeClass('open').hide(); -}; - -CBRJS.Book.prototype.toggleControl = function(control) { - this.getControl(control).toggle().toggleClass('open'); -}; - -CBRJS.Book.prototype.toggleLayout = function() { - - var $toolbar = self.getControl('toolbar'); - var displayMode = (options.displayMode === 'single') ? 'double' : 'single'; - - options.displayMode = displayMode; - - $toolbar.find('.layout').hide().end().find('.layout-' + options.displayMode).show(); - - self.drawPage(); -}; - -/** - * Get the image for a given page. - * - * @return Image - */ -CBRJS.Book.prototype.getPage = function(i) { - - if (i < 0 || i > srcs.length - 1) { - throw ComicBookException.INVALID_PAGE + ' ' + i; - } - - if (typeof pages[i] === 'object') { - return pages[i]; - } else { - page_requested = i; - this.showControl('loadingOverlay'); - } -}; - -/** - * @see #preload - */ -CBRJS.Book.prototype.draw = function() { - - init(); - - // resize navigation controls - $('.navigate').outerHeight(window.innerHeight); - $('#cb-loading-overlay').outerWidth(windowWidth()).height(window.innerHeight); - - // preload images if needed - if (pages.length !== no_pages) { - this.preload(); - } else { - this.drawPage(); - } -}; - -/** - * Zoom the canvas - * - * @param new_scale {Number} Scale the canvas to this ratio - */ -CBRJS.Book.prototype.zoom = function(new_scale) { - options.zoomMode = 'manual'; - scale = new_scale; - if (typeof this.getPage(pointer) === 'object') { - this.drawPage(); - } -}; - -CBRJS.Book.prototype.zoomIn = function() { - self.zoom(scale + 0.1); -}; - -CBRJS.Book.prototype.zoomOut = function() { - self.zoom(scale - 0.1); -}; - -ComicBook.prototype.fitWidth = function() { - options.zoomMode = 'fitWidth'; - self.drawPage(); -}; - -CBRJS.Book.prototype.fitWindow = function() { - options.zoomMode = 'fitWindow'; - self.drawPage(); -}; - -/** - * Preload all images, draw the page only after a given number have been loaded. - * - * @see #drawPage - */ -CBRJS.Book.prototype.preload = function() { - - var i = pointer; // the current page counter for this method - var rendered = false; - var queue = []; - - this.showControl('loadingOverlay'); - - function loadImage(i) { - - var page = new Image(); - page.src = srcs[i]; - - page.onload = function() { - - pages[i] = this; - loaded.push(i); - - $('#cb-progress-bar .progressbar-value').css('width', Math.floor((loaded.length / no_pages) * 100) + '%'); - - // double page mode needs an extra page added - var buffer = (options.displayMode === 'double' && pointer < srcs.length - 1) ? 1 : 0; - - // start rendering the comic when the requested page is ready - if ((rendered === false && ($.inArray(pointer + buffer, loaded) !== -1) || - (typeof page_requested === 'number' && $.inArray(page_requested, loaded) !== -1))) { - // if the user is waiting for a page to be loaded, render that one instead of the default pointer - if (typeof page_requested === 'number') { - pointer = page_requested - 1; - page_requested = false; - } - - self.drawPage(); - self.hideControl('loadingOverlay'); - rendered = true; - } - - if (queue.length) { - loadImage(queue[0]); - queue.splice(0, 1); - } else { - $('#cb-status').delay(500).fadeOut(); - } - }; - } - - // loads pages in both directions so you don't have to wait for all pages - // to be loaded before you can scroll backwards - function preload(start, stop) { - - var j = 0; - var count = 1; - var forward = start; - var backward = start - 1; - - while (forward <= stop) { - - if (count > options.forward_buffer && backward > -1) { - queue.push(backward); - backward--; - count = 0; - } else { - queue.push(forward); - forward++; - } - count++; - } - - while (backward > -1) { - queue.push(backward); - backward--; - } - - loadImage(queue[j]); - } - - preload(i, srcs.length - 1); -}; - -CBRJS.Book.prototype.pageLoaded = function(page_no) { - return (typeof loaded[page_no - 1] !== 'undefined'); -}; - -/** - * Draw the current page in the canvas - */ -CBRJS.Book.prototype.drawPage = function(page_no, reset_scroll) { - - var scrollY; - - reset_scroll = (typeof reset_scroll !== 'undefined') ? reset_scroll : true; - scrollY = reset_scroll ? 0 : window.scrollY; - - // if a specific page is given try to render it, if not bail and wait for preload() to render it - if (typeof page_no === 'number' && page_no < srcs.length && page_no > 0) { - pointer = page_no - 1; - if (!this.pageLoaded(page_no)) { - this.showControl('loadingOverlay'); - return; - } - } - - if (pointer < 0) { - pointer = 0; - } - - var zoom_scale; - var offsetW = 0, - offsetH = 0; - - var page = self.getPage(pointer); - var page2 = false; - - if (options.displayMode === 'double' && pointer < srcs.length - 1) { - page2 = self.getPage(pointer + 1); - } - - if (typeof page !== 'object') { - throw ComicBookException.INVALID_PAGE_TYPE + ' ' + typeof page; - } - - var width = page.width, - height = page.height; - - // reset the canvas to stop duplicate pages showing - canvas.width = 0; - canvas.height = 0; - - // show double page spreads on a single page - is_double_page_spread = ( - typeof page2 === 'object' && - (page.width > page.height || page2.width > page2.height) && - options.displayMode === 'double' - ); - if (is_double_page_spread) { - options.displayMode = 'single'; - } - - if (options.displayMode === 'double') { - - // for double page spreads, factor in the width of both pages - if (typeof page2 === 'object') { - width += page2.width; - } - - // if this is the last page and there is no page2, still keep the canvas wide - else { - width += width; - } - } - - // update the page scale if a non manual mode has been chosen - switch (options.zoomMode) { - - case 'manual': - document.body.style.overflowX = 'auto'; - zoom_scale = (options.displayMode === 'double') ? scale * 2 : scale; - break; - - case 'fitWidth': - document.body.style.overflowX = 'hidden'; - - // scale up if the window is wider than the page, scale down if the window - // is narrower than the page - zoom_scale = (windowWidth() > width) ? ((windowWidth() - width) / windowWidth()) + 1 : windowWidth() / width; - - // update the interal scale var so switching zoomModes while zooming will be smooth - scale = zoom_scale; - break; - - case 'fitWindow': - document.body.style.overflowX = 'hidden'; - - var width_scale = (windowWidth() > width) ? - ((windowWidth() - width) / windowWidth()) + 1 // scale up if the window is wider than the page - : - windowWidth() / width; // scale down if the window is narrower than the page - var windowHeight = window.innerHeight; - var height_scale = (windowHeight > height) ? - ((windowHeight - height) / windowHeight) + 1 // scale up if the window is wider than the page - : - windowHeight / height; // scale down if the window is narrower than the page - - zoom_scale = (width_scale > height_scale) ? height_scale : width_scale; - scale = zoom_scale; - break; - - default: - throw ComicBookException.INVALID_ZOOM_MODE + ' ' + options.zoomMode; - } - - var canvas_width = page.width * zoom_scale; - var canvas_height = page.height * zoom_scale; - - var page_width = (options.zoomMode === 'manual') ? page.width * scale : canvas_width; - var page_height = (options.zoomMode === 'manual') ? page.height * scale : canvas_height; - - canvas_height = page_height; - - // make sure the canvas is always at least full screen, even if the page is more narrow than the screen - canvas.width = (canvas_width < windowWidth()) ? windowWidth() : canvas_width; - canvas.height = (canvas_height < window.innerHeight) ? window.innerHeight : canvas_height; - - // always keep pages centered - if (options.zoomMode === 'manual' || options.zoomMode === 'fitWindow') { - - // work out a horizontal position - if (canvas_width < windowWidth()) { - offsetW = (windowWidth() - page_width) / 2; - if (options.displayMode === 'double') { - offsetW = offsetW - page_width / 2; - } - } - - // work out a vertical position - if (canvas_height < window.innerHeight) { - offsetH = (window.innerHeight - page_height) / 2; - } - } - - // in manga double page mode reverse the page(s) - if (options.manga && options.displayMode === 'double' && typeof page2 === 'object') { - var tmpPage = page; - var tmpPage2 = page2; - page = tmpPage2; - page2 = tmpPage; - } - - // draw the page(s) - context.drawImage(page, offsetW, offsetH, page_width, page_height); - if (options.displayMode === 'double' && typeof page2 === 'object') { - context.drawImage(page2, page_width + offsetW, offsetH, page_width, page_height); - } - - this.pixastic = new Pixastic(context, options.vendorPath + 'pixastic/'); - - // apply any image enhancements previously defined - $.each(options.enhance, function(action, options) { - self.enhance[action](options); - }); - - var current_page = - (options.displayMode === 'double' && - pointer + 2 <= srcs.length) ? (pointer + 1) + '-' + (pointer + 2) : pointer + 1; - - this.getControl('toolbar') - .find('#current-page').text(current_page) - .end() - .find('#page-count').text(srcs.length); - - // revert page mode back to double if it was auto switched for a double page spread - if (is_double_page_spread) { - options.displayMode = 'double'; - } - - // disable the fit width button if needed - $('button.cb-fit-width').attr('disabled', (options.zoomMode === 'fitWidth')); - $('button.cb-fit-window').attr('disabled', (options.zoomMode === 'fitWindow')); - - // disable prev/next buttons if not needed - $('.navigate').show(); - if (pointer === 0) { - if (options.manga) { - $('.navigate-left').show(); - $('.navigate-right').hide(); - } else { - $('.navigate-left').hide(); - $('.navigate-right').show(); - } - } - - if (pointer === srcs.length - 1 || (typeof page2 === 'object' && pointer === srcs.length - 2)) { - if (options.manga) { - $('.navigate-left').hide(); - $('.navigate-right').show(); - } else { - $('.navigate-left').show(); - $('.navigate-right').hide(); - } - } - - if (pointer !== getHash()) { - $(this).trigger('navigate'); - } - - // update hash location - if (getHash() !== pointer) { - setHash(pointer + 1); - } -}; - -/** - * Increment the counter and draw the page in the canvas - * - * @see #drawPage - */ -CBRJS.Book.prototype.drawNextPage = function() { - - var page; - - try { - page = self.getPage(pointer + 1); - } catch (e) {} - - if (!page) { - return false; - } - - if (pointer + 1 < pages.length) { - pointer += (options.displayMode === 'single' || is_double_page_spread) ? 1 : 2; - try { - self.drawPage(); - } catch (e) {} - } - - // make sure the top of the page is in view - window.scroll(0, 0); -}; - -/** - * Decrement the counter and draw the page in the canvas - * - * @see #drawPage - */ -CBRJS.Book.prototype.drawPrevPage = function() { - - var page; - - try { - page = self.getPage(pointer - 1); - } catch (e) {} - - if (!page) { - return false; - } - - is_double_page_spread = (page.width > page.height); // need to run double page check again here as we are going backwards - - if (pointer > 0) { - pointer -= (options.displayMode === 'single' || is_double_page_spread) ? 1 : 2; - self.drawPage(); - } - - // make sure the top of the page is in view - window.scroll(0, 0); -}; - -CBRJS.Book.prototype.brightness = function() { - self.enhance.brightness({ - brightness: $(this).val() - }); -}; - -CBRJS.Book.prototype.contrast = function() { - self.enhance.brightness({ - contrast: $(this).val() - }); -}; - -CBRJS.Book.prototype.sharpen = function() { - self.enhance.sharpen({ - strength: $(this).val() - }); -}; - -CBRJS.Book.prototype.desaturate = function() { - if ($(this).is(':checked')) { - self.enhance.desaturate(); - } else { - self.enhance.resaturate(); - } -}; - -CBRJS.Book.prototype.resetEnhancements = function() { - self.enhance.reset(); -}; - -/** - * Apply image enhancements to the canvas. - * - * Powered by the awesome Pixastic: http://www.pixastic.com/ - * - * TODO: reset & apply all image enhancements each time before applying new one - * TODO: abstract this into an 'Enhance' object, separate from ComicBook? - */ -CBRJS.Book.prototype.enhance = { - - /** - * Reset enhancements. - * This can reset a specific enhancement if the method name is passed, or - * it will reset all. - * - * @param method {string} the specific enhancement to reset - */ - reset: function(method) { - if (!method) { - options.enhance = {}; - } else { - delete options.enhance[method]; - } - self.drawPage(null, false); - }, - - /** - * Pixastic progress callback - * @param {float} progress - */ - // progress: function (progress) { - progress: function() { - // console.info(Math.floor(progress * 100)); - }, - - /** - * Pixastic on complete callback - */ - done: function() { - - }, - - /** - * Adjust brightness / contrast - * - * params - * brightness (int) -150 to 150 - * contrast: (float) -1 to infinity - * - * @param {Object} params Brightness & contrast levels - * @param {Boolean} reset Reset before applying more enhancements? - */ - brightness: function(params, reset) { - - if (reset !== false) { - this.reset('brightness'); - } - - // merge user options with defaults - var opts = merge({ - brightness: 0, - contrast: 0 - }, params); - - // remember options for later - options.enhance.brightness = opts; - - // run the enhancement - self.pixastic.brightness({ - brightness: opts.brightness, - contrast: opts.contrast - }).done(this.done, this.progress); - }, - - /** - * Force black and white - */ - desaturate: function() { - options.enhance.desaturate = {}; - self.pixastic.desaturate().done(this.done, this.progress); - }, - - /** - * Undo desaturate - */ - resaturate: function() { - delete options.enhance.desaturate; - self.drawPage(null, false); - }, - - /** - * Sharpen - * - * options: - * strength: number (-1 to infinity) - * - * @param {Object} options - */ - sharpen: function(params) { - - this.desharpen(); - - var opts = merge({ - strength: 0 - }, params); - - options.enhance.sharpen = opts; - - self.pixastic.sharpen3x3({ - strength: opts.strength - }).done(this.done, this.progress); - }, - - desharpen: function() { - delete options.enhance.sharpen; - self.drawPage(null, false); - } -}; - -CBRJS.Book.prototype.navigation = function(e) { - - // disable navigation when the overlay is showing - if ($('#cb-loading-overlay').is(':visible')) { - return false; - } - - var side = false; - - switch (e.type) { - - case 'click': - side = e.currentTarget.getAttribute('data-navigate-side'); - break; - - case 'keydown': - - // navigation - if (e.keyCode === options.keyboard.previous) { - side = 'left'; - } - if (e.keyCode === options.keyboard.next) { - side = 'right'; - } - - // display controls - if (e.keyCode === options.keyboard.toolbar) { - self.toggleToolbar(); - } - if (e.keyCode === options.keyboard.toggleLayout) { - self.toggleLayout(); - } - break; - - default: - throw ComicBookException.INVALID_NAVIGATION_EVENT + ' ' + e.type; - } - - if (side) { - - e.stopPropagation(); - - // western style (left to right) - if (!options.manga) { - if (side === 'left') { - self.drawPrevPage(); - } - if (side === 'right') { - self.drawNextPage(); - } - } - // manga style (right to left) - else { - if (side === 'left') { - self.drawNextPage(); - } - if (side === 'right') { - self.drawPrevPage(); - } - } - - return false; - } -}; - -CBRJS.Book.prototype.toggleReadingMode = function() { - options.manga = !options.manga; - self.getControl('toolbar') - .find('.manga-' + options.manga).show().end() - .find('.manga-' + !options.manga).hide(); -}; - -CBRJS.Book.prototype.toggleToolbar = function() { - self.toggleControl('toolbar'); -}; - -/* CBRJS.Book.prototype.close = function() { - self.destroy(); -} */ - -CBRJS.Book.prototype.destroy = function() { - - $.each(this.controls, function(name, $control) { - $control.remove(); - }); - - canvas.width = 0; - canvas.height = 0; - - window.removeEventListener('keydown', this.navigation, false); - window.removeEventListener('hashchange', checkHash, false); - - setHash(''); - - // $(this).trigger('destroy'); -}; - - -(function(root, $) { - - var previousReader = root.cbReader || {}; - - var cbReader = root.cbReader = function(path, options) { - return new CBRJS.Reader(path, options); - }; - - //exports to multiple environments - if (typeof define === 'function' && define.amd) { - //AMD - define(function(){ return Reader; }); - } else if (typeof module != "undefined" && module.exports) { - //Node - module.exports = cbReader; - } - -})(window, jQuery); - - diff --git a/reader/vendor/cbrjs/cbr.js.OK b/reader/vendor/cbrjs/cbr.js.OK deleted file mode 100644 index c843325..0000000 --- a/reader/vendor/cbrjs/cbr.js.OK +++ /dev/null @@ -1,2894 +0,0 @@ -var CBRJS = {}; -CBRJS.VERSION = "0.0.1"; - -CBRJS.Render = {}; -CBRJS.reader = {}; - -CBRJS.Reader = function(bookPath, _options) { - - var $progressbar = $('.bar'); - - function extractImages(url, opts) { - - var images = []; - var xhr = new XMLHttpRequest(); - var re_file_ext = new RegExp(/\.([a-z]+)$/); - var filename = decodeURIComponent(url.split('/').pop()); - var archive_class = ({ cbz: 'Unzipper', cbr: 'Unrarrer' })[filename.toLowerCase().match(re_file_ext)[1]]; - var options = $.extend({ - start: function () {}, - extract: function (page_url) {}, - progress: function (percent_complete) {}, - finish: function (images) {}, - }, opts); - - if (!archive_class) { - alert('invalid file type, only cbz and cbr are supported.'); - return false; - } - - xhr.responseType = "arraybuffer"; - - xhr.open('GET',url, true); - - options.start(filename); - console.log("filename: " + filename); - - xhr.onprogress = function (e) { - if (e.lengthComputable) { - $progressbar.css('width', Math.floor((e.loaded / e.total) * 100) + '%'); - } - } - - xhr.onloadstart = function (e) { - $progressbar.css('width', '0%'); - } - - xhr.onload = function () { - if ((this.status === 200) && this.response) { - var done = false; - var ua = new bitjs.archive[archive_class](this.response, 'vendor/bitjs/'); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.START, function (e) { - $progressbar.css('width', '0%'); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.EXTRACT, function (e) { - - var mimetype, blob, url; - var file_extension = e.unarchivedFile.filename.toLowerCase().match(re_file_ext)[1]; - - switch (file_extension) { - case 'jpg': - case 'jpeg': - mimetype = 'image/jpeg'; - break; - case 'png': - mimetype = 'image/png'; - break; - case 'gif': - mimetype = 'image/gif'; - break; - default: - return false; - } - - blob = new Blob([e.unarchivedFile.fileData], { type: mimetype }); - url = window.URL.createObjectURL(blob); - - images.push(url); - - options.extract(url, blob); - console.log(url, file_extension); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.PROGRESS, function (e) { - options.progress(Math.floor(e.currentBytesUnarchived / e.totalUncompressedBytesInArchive * 100)); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.FINISH, function (e) { - options.finish(images); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.ERROR, function (e) { - $('#message').text('Failed to extract images from archive, file corrupted?'); - - }); - } - - ua.start(); - }; - - xhr.send(); - } - - function openComicArchive(url) { - - console.log("openComicArchive " + url); - - var title, page = 0; - - extractImages(url, { - start: function (filename) { - this.filename = filename; - $('#message').text('Opening ' + filename); - $('#progressbar').show(); - }, - extract: function (url, blob) { - // $('body').append($('').attr('src', url).css('width', '10px')); - console.log(url, Math.floor(blob.size / 1024)); - $('#message').text('extracting page #' + ++page); - }, - progress: function (percent_complete) { - $progressbar.css('width', percent_complete + '%'); - }, - finish: function (pages) { - - var name = this.filename.replace(/\.[a-z]+$/, ''); - var id = encodeURIComponent(name.toLowerCase()); - var book = new ComicBook('cbreader', pages, {vendorPath: 'vendor/'}); - - document.title = name; - - $('#progressbar').hide(); - $('#cbreader').show(); - - book.draw(); - - $(window).on('resize', function () { - book.draw(); - }); - } - }); - } - - openComicArchive(bookPath); - - return this; -}; - - -/*! - * Pixastic - JavaScript Image Processing - * http://pixastic.com/ - * Copyright 2012, Jacob Seidelin - * - * Dual licensed under the MPL 1.1 or GPLv3 licenses. - * http://pixastic.com/license-mpl.txt - * http://pixastic.com/license-gpl-3.0.txt - * - */ - - var Pixastic = (function() { - - var worker; - - function createImageData(ctx, width, height) { - if (ctx.createImageData) { - return ctx.createImageData(width, height); - } else { - return ctx.getImageData(0, 0, width, height); - } - } - - function Pixastic(ctx, workerControlPath) { - - var P = {}, - width = ctx.canvas.width, - height = ctx.canvas.height, - queue = [], - workerControlPath = workerControlPath || "vendor/pixastic/"; - - if (!worker) { - if (typeof window.Worker != "undefined") { - try { - worker = new window.Worker(workerControlPath + "pixastic.worker.control.js"); - } catch(e) { - if (location.protocol == "file:") { - Pixastic.log("Could not create native worker, running from file://") - } else { - Pixastic.log("Could not create native worker.") - } - } - } - if (!worker) { - worker = new Pixastic.Worker(); - } - } - - for (var e in Pixastic.Effects) { - if (Pixastic.Effects.hasOwnProperty(e)) { - (function(e) { - P[e] = function(options) { - queue.push({ - effect : e, - options : options - }); - return P; - } - - P.done = function(callback, progress) { - var inData, outData; - - try { - inData = ctx.getImageData(0, 0, width, height); - } catch(e) { - if (location.protocol == "file:") { - throw new Error("Could not access image data, running from file://"); - } else { - throw new Error("Could not access image data, is canvas tainted by cross-origin data?"); - } - } - - outData = createImageData(ctx, width, height); - - worker.postMessage({ - queue : queue, - inData : inData, - outData : outData, - width : width, - height : height - }); - - worker.onmessage = function(message) { - var d = message.data; - switch (d.event) { - case "done" : - ctx.putImageData(d.data, 0, 0); - if (callback) { - callback(); - } - if (progress) { - progress(1); - } - break; - case "progress" : - if (progress) { - progress(d.data); - } - break; - case "error" : - break; - } - } - - if (progress) { - progress(0); - } - } - })(e); - } - } - return P; - } - - - Pixastic.Worker = function() { - var me = this; - function processMessage(data) { - var queue = data.queue, - inData = data.inData, - outData = data.outData, - width = data.width, - height = data.height, - tmpData; - - for (var i=0;i 0) { - tmpData = inData; - inData = outData; - outData = tmpData; - } - - if (typeof importScripts == "function") { - progressCallback = function(p) { - me.onmessage({ - data : { - event : "progress", - data : (i + p) / queue.length - } - }); - return p; - } - } - - Pixastic.Effects[e](inData.data, outData.data, width, height, options, progressCallback); - - me.onmessage({ - data : { - event : "progress", - data : (i+1) / queue.length - } - }); - } - - me.onmessage({ - data : { - event : "done", - data : outData - } - }); - } - - this.postMessage = function(data) { - setTimeout(function() { - processMessage(data) - }, 0); - }; - - this.onmessage = function() {}; - - } - - - - Pixastic.log = function(str) { - if (typeof console != "undefined" && console.log) { - console.log("Pixastic: " + str); - } - }; - - function toCanvas(o) { - var canvas; - if (typeof o == "object") { - if (typeof o.tagName == "string") { - if (o.tagName.toLowerCase() == "canvas" || o.tagName.toLowerCase() == "img") { - canvas = document.createElement("canvas"); - canvas.width = o.width; - canvas.height = o.height; - canvas.getContext("2d").drawImage(o, 0,0); - } - } else if ((window.ImageData && o instanceof window.ImageData) - || (typeof o.width == "number" && typeof o.height == "number" && typeof o.data == "object")) { - canvas = document.createElement("canvas"); - canvas.width = o.width; - canvas.height = o.height; - canvas.getContext("2d").putImageData(o, 0, 0); - } - } - return canvas; - }; - - function toImage(o) { - var canvas = toCanvas(o), - image = new Image(); - image.width = canvas.width; - image.height = canvas.height; - image.src = canvas.toDataURL(); - return image; - }; - - function toImageData(o) { - var canvas = toCanvas(o), - ctx = canvas.getContext("2d"); - return ctx.getImageData(0, 0, canvas.width, canvas.height); - }; - - function histogram(imageData) { - var values = [], - i, p, - data = imageData.data, - round = Math.round, - maxValue, - n = imageData.width * imageData.height; - - for (i=0;i<256;i++) { - values[i] = 0; - } - - for (i=0;i maxValue) { - maxValue = values[i]; - } - } - - return { - maxValue : maxValue, - values : values - }; - } - - Pixastic.toCanvas = toCanvas; - Pixastic.toImage = toImage; - Pixastic.toImageData = toImageData; - Pixastic.histogram = histogram; - - Pixastic.Color = { - rgb2hsl : function(r, g, b) { - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - if (r > 255) r = 0; - if (g > 255) g = 0; - if (b > 255) b = 0; - }, - - rgb2hsv : function(r, g, b) { - }, - - rgb2hex : function(r, g, b) { - }, - - hsl2rgb : function(h, s, l) { - }, - - hsv2rgb : function(h, s, v) { - } - - } - - return Pixastic; - -})(); - - -Pixastic.Effects = (function() { - - function defaultOptions(options, defaults) { - var O = {}; - for (var opt in defaults) { - if (typeof options[opt] == "undefined") { - O[opt] = defaults[opt]; - } else { - O[opt] = options[opt]; - } - } - return O; - } - - function clamp(val, min, max) { - return Math.min(max, Math.max(min, val)); - } - - function convolve3x3(inData, outData, width, height, kernel, progress, alpha, invert, mono) { - var idx, r, g, b, a, - pyc, pyp, pyn, - pxc, pxp, pxn, - x, y, - - prog, lastProg = 0, - n = width * height * 4, - - k00 = kernel[0][0], k01 = kernel[0][1], k02 = kernel[0][2], - k10 = kernel[1][0], k11 = kernel[1][1], k12 = kernel[1][2], - k20 = kernel[2][0], k21 = kernel[2][1], k22 = kernel[2][2], - - p00, p01, p02, - p10, p11, p12, - p20, p21, p22; - - for (y=0;y= width-1) pyn = pyc; - - for (x=0;x= width-1) pxn = pxc; - - p00 = pyp + pxp; p01 = pyp + pxc; p02 = pyp + pxn; - p10 = pyc + pxp; p11 = pyc + pxc; p12 = pyc + pxn; - p20 = pyn + pxp; p21 = pyn + pxc; p22 = pyn + pxn; - - r = inData[p00] * k00 + inData[p01] * k01 + inData[p02] * k02 - + inData[p10] * k10 + inData[p11] * k11 + inData[p12] * k12 - + inData[p20] * k20 + inData[p21] * k21 + inData[p22] * k22; - - g = inData[p00 + 1] * k00 + inData[p01 + 1] * k01 + inData[p02 + 1] * k02 - + inData[p10 + 1] * k10 + inData[p11 + 1] * k11 + inData[p12 + 1] * k12 - + inData[p20 + 1] * k20 + inData[p21 + 1] * k21 + inData[p22 + 1] * k22; - - b = inData[p00 + 2] * k00 + inData[p01 + 2] * k01 + inData[p02 + 2] * k02 - + inData[p10 + 2] * k10 + inData[p11 + 2] * k11 + inData[p12 + 2] * k12 - + inData[p20 + 2] * k20 + inData[p21 + 2] * k21 + inData[p22 + 2] * k22; - - if (alpha) { - a = inData[p00 + 3] * k00 + inData[p01 + 3] * k01 + inData[p02 + 3] * k02 - + inData[p10 + 3] * k10 + inData[p11 + 3] * k11 + inData[p12 + 3] * k12 - + inData[p20 + 3] * k20 + inData[p21 + 3] * k21 + inData[p22 + 3] * k22; - } else { - a = inData[idx+3]; - } - - if (mono) { - r = g = b = (r + g + b) / 3; - } - if (invert) { - r = 255 - r; - g = 255 - g; - b = 255 - b; - } - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = a; - - if (progress) { - prog = (idx/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - } - - function convolve5x5(inData, outData, width, height, kernel, progress, alpha, invert, mono) { - var idx, r, g, b, a, - pyc, pyp, pyn, pypp, pynn, - pxc, pxp, pxn, pxpp, pxnn, - x, y, - - prog, lastProg = 0, - n = width * height * 4, - - k00 = kernel[0][0], k01 = kernel[0][1], k02 = kernel[0][2], k03 = kernel[0][3], k04 = kernel[0][4], - k10 = kernel[1][0], k11 = kernel[1][1], k12 = kernel[1][2], k13 = kernel[1][3], k14 = kernel[1][4], - k20 = kernel[2][0], k21 = kernel[2][1], k22 = kernel[2][2], k23 = kernel[2][3], k24 = kernel[2][4], - k30 = kernel[3][0], k31 = kernel[3][1], k32 = kernel[3][2], k33 = kernel[3][3], k34 = kernel[3][4], - k40 = kernel[4][0], k41 = kernel[4][1], k42 = kernel[4][2], k43 = kernel[4][3], k44 = kernel[4][4], - - p00, p01, p02, p03, p04, - p10, p11, p12, p13, p14, - p20, p21, p22, p23, p24, - p30, p31, p32, p33, p34, - p40, p41, p42, p43, p44; - - for (y=0;y= width-1) pyn = pyc; - if (y < 2) pypp = pyp; - if (y >= width-2) pynn = pyn; - - for (x=0;x= width-1) pxn = pxc; - if (x < 2) pxpp = pxp; - if (x >= width-2) pxnn = pxn; - - p00 = pypp + pxpp; p01 = pypp + pxp; p02 = pypp + pxc; p03 = pypp + pxn; p04 = pypp + pxnn; - p10 = pyp + pxpp; p11 = pyp + pxp; p12 = pyp + pxc; p13 = pyp + pxn; p14 = pyp + pxnn; - p20 = pyc + pxpp; p21 = pyc + pxp; p22 = pyc + pxc; p23 = pyc + pxn; p24 = pyc + pxnn; - p30 = pyn + pxpp; p31 = pyn + pxp; p32 = pyn + pxc; p33 = pyn + pxn; p34 = pyn + pxnn; - p40 = pynn + pxpp; p41 = pynn + pxp; p42 = pynn + pxc; p43 = pynn + pxn; p44 = pynn + pxnn; - - r = inData[p00] * k00 + inData[p01] * k01 + inData[p02] * k02 + inData[p03] * k04 + inData[p02] * k04 - + inData[p10] * k10 + inData[p11] * k11 + inData[p12] * k12 + inData[p13] * k14 + inData[p12] * k14 - + inData[p20] * k20 + inData[p21] * k21 + inData[p22] * k22 + inData[p23] * k24 + inData[p22] * k24 - + inData[p30] * k30 + inData[p31] * k31 + inData[p32] * k32 + inData[p33] * k34 + inData[p32] * k34 - + inData[p40] * k40 + inData[p41] * k41 + inData[p42] * k42 + inData[p43] * k44 + inData[p42] * k44; - - g = inData[p00+1] * k00 + inData[p01+1] * k01 + inData[p02+1] * k02 + inData[p03+1] * k04 + inData[p02+1] * k04 - + inData[p10+1] * k10 + inData[p11+1] * k11 + inData[p12+1] * k12 + inData[p13+1] * k14 + inData[p12+1] * k14 - + inData[p20+1] * k20 + inData[p21+1] * k21 + inData[p22+1] * k22 + inData[p23+1] * k24 + inData[p22+1] * k24 - + inData[p30+1] * k30 + inData[p31+1] * k31 + inData[p32+1] * k32 + inData[p33+1] * k34 + inData[p32+1] * k34 - + inData[p40+1] * k40 + inData[p41+1] * k41 + inData[p42+1] * k42 + inData[p43+1] * k44 + inData[p42+1] * k44; - - b = inData[p00+2] * k00 + inData[p01+2] * k01 + inData[p02+2] * k02 + inData[p03+2] * k04 + inData[p02+2] * k04 - + inData[p10+2] * k10 + inData[p11+2] * k11 + inData[p12+2] * k12 + inData[p13+2] * k14 + inData[p12+2] * k14 - + inData[p20+2] * k20 + inData[p21+2] * k21 + inData[p22+2] * k22 + inData[p23+2] * k24 + inData[p22+2] * k24 - + inData[p30+2] * k30 + inData[p31+2] * k31 + inData[p32+2] * k32 + inData[p33+2] * k34 + inData[p32+2] * k34 - + inData[p40+2] * k40 + inData[p41+2] * k41 + inData[p42+2] * k42 + inData[p43+2] * k44 + inData[p42+2] * k44; - - if (alpha) { - a = inData[p00+3] * k00 + inData[p01+3] * k01 + inData[p02+3] * k02 + inData[p03+3] * k04 + inData[p02+3] * k04 - + inData[p10+3] * k10 + inData[p11+3] * k11 + inData[p12+3] * k12 + inData[p13+3] * k14 + inData[p12+3] * k14 - + inData[p20+3] * k20 + inData[p21+3] * k21 + inData[p22+3] * k22 + inData[p23+3] * k24 + inData[p22+3] * k24 - + inData[p30+3] * k30 + inData[p31+3] * k31 + inData[p32+3] * k32 + inData[p33+3] * k34 + inData[p32+3] * k34 - + inData[p40+3] * k40 + inData[p41+3] * k41 + inData[p42+3] * k42 + inData[p43+3] * k44 + inData[p42+3] * k44; - } else { - a = inData[idx+3]; - } - - if (mono) { - r = g = b = (r + g + b) / 3; - } - - if (invert) { - r = 255 - r; - g = 255 - g; - b = 255 - b; - } - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = a; - - if (progress) { - prog = (idx/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - } - - function gaussian(inData, outData, width, height, kernelSize, progress) { - var r, g, b, a, idx, - n = width * height * 4, - x, y, i, j, - inx, iny, w, - tmpData = [], - maxKernelSize = 13, - kernelSize = clamp(kernelSize, 3, maxKernelSize), - k1 = -kernelSize / 2 + (kernelSize % 2 ? 0.5 : 0), - k2 = kernelSize + k1, - weights, - kernels = [[1]], - prog, lastProg = 0; - - - for (i=1;i= width) { - inx = width - 1; - } - - idx = (iny * width + inx) * 4; - - r += inData[idx] * w; - g += inData[idx + 1] * w; - b += inData[idx + 2] * w; - a += inData[idx + 3] * w; - - } - - idx = (y * width + x) * 4; - - tmpData[idx] = r; - tmpData[idx+1] = g; - tmpData[idx+2] = b; - tmpData[idx+3] = a; - - if (progress) { - prog = (idx/n*50 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - - lastProg = 0; - - // pass 2 - for (y=0;y= height) { - iny = height - 1; - } - - idx = (iny * width + inx) * 4; - - r += tmpData[idx] * w; - g += tmpData[idx + 1] * w; - b += tmpData[idx + 2] * w; - a += tmpData[idx + 3] * w; - } - - idx = (y * width + x) * 4; - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = a; - - if (progress) { - prog = 0.5 + (idx/n*50 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - } - - - return { - - invert : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0; - - for (i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - sepia : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - r, g, b; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - solarize : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - r, g, b; - - for (i=0;i 127 ? 255 - r : r; - outData[i+1] = g > 127 ? 255 - g : g; - outData[i+2] = b > 127 ? 255 - b : b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - brightness : function(inData, outData, width, height, options, progress) { - options = defaultOptions(options, { - brightness : 0, - contrast : 0 - }); - - var contrast = clamp(options.contrast, -1, 1) / 2, - brightness = 1 + clamp(options.brightness, -1, 1), - prog, lastProg = 0, - r, g, b, - n = width * height * 4; - - var brightMul = brightness < 0 ? - brightness : brightness; - var brightAdd = brightness < 0 ? 0 : brightness; - - contrast = 0.5 * Math.tan((contrast + 1) * Math.PI/4); - contrastAdd = - (contrast - 0.5) * 255; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - desaturate : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - level; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - lighten : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - mul = 1 + clamp(options.amount, 0, 1); - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - noise : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - prog, lastProg = 0, - amount = clamp(options.amount, 0, 1), - strength = clamp(options.strength, 0, 1), - mono = !!options.mono, - random = Math.random, - rnd, r, g, b; - - for (var i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - flipv : function(inData, outData, width, height, options, progress) { - var inPix, outPix, - n = width * height * 4, - prog, lastProg = 0, - x, y; - for (y=0;y> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }, - - fliph : function(inData, outData, width, height, options, progress) { - var inPix, outPix, - n = width * height * 4, - prog, lastProg = 0, - x, y; - for (y=0;y> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }, - - blur : function(inData, outData, width, height, options, progress) { - gaussian(inData, outData, width, height, options.kernelSize, progress); - }, - - glow : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - i, r, g, b, - amount = options.amount, - tmpData = [], - gaussProgress, - prog, lastProg = 0; - - if (progress) { - gaussProgress = function(p) { - progress(p * 0.8); - return p; - } - } - - gaussian(inData, tmpData, width, height, options.kernelSize, gaussProgress); - - for (i=0;i 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - outData[i] = r; - outData[i+1] = g; - outData[i+2] = b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = 0.8 + (i/n*100 >> 0) / 100 * 0.2; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - convolve3x3 : function(inData, outData, width, height, options, progress) { - convolve3x3(inData, outData, width, height, options.kernel, progress); - }, - - convolve5x5 : function(inData, outData, width, height, options, progress) { - convolve5x5(inData, outData, width, height, options.kernel, progress); - }, - - // A 3x3 high-pass filter - sharpen3x3 : function(inData, outData, width, height, options, progress) { - var a = - clamp(options.strength, 0, 1); - convolve3x3( - inData, outData, width, height, - [[a, a, a], - [a, 1-a*8, a], - [a, a, a]], - progress - ); - }, - - // A 5x5 high-pass filter - sharpen5x5 : function(inData, outData, width, height, options, progress) { - var a = - clamp(options.strength, 0, 1); - convolve5x5( - inData, outData, width, height, - [[a, a, a, a, a], - [a, a, a, a, a], - [a, a, 1-a*24, a, a], - [a, a, a, a, a], - [a, a, a, a, a]], - progress - ); - }, - - // A 3x3 low-pass mean filter - soften3x3 : function(inData, outData, width, height, options, progress) { - var c = 1/9; - convolve3x3( - inData, outData, width, height, - [[c, c, c], - [c, c, c], - [c, c, c]], - progress - ); - }, - - // A 5x5 low-pass mean filter - soften5x5 : function(inData, outData, width, height, options, progress) { - var c = 1/25; - convolve5x5( - inData, outData, width, height, - [[c, c, c, c, c], - [c, c, c, c, c], - [c, c, c, c, c], - [c, c, c, c, c], - [c, c, c, c, c]], - progress - ); - }, - - // A 3x3 Cross edge-detect - crossedges : function(inData, outData, width, height, options, progress) { - var a = clamp(options.strength, 0, 1) * 5 - convolve3x3( - inData, outData, width, height, - [[ 0, -a, 0], - [-a, 0, a], - [ 0, a, 0]], - progress, - false, true - ); - }, - - // 3x3 directional emboss - emboss : function(inData, outData, width, height, options, progress) { - var amount = options.amount, - angle = options.angle, - x = Math.cos(-angle) * amount, - y = Math.sin(-angle) * amount, - n = width * height * 4, - - a00 = -x - y, - a10 = -x, - a20 = y - x, - a01 = -y, - a21 = y, - a02 = -y + x, - a12 = x, - a22 = y + x, - - tmpData = [], - - prog, lastProg = 0, - convProgress; - - if (progress) { - convProgress = function(p) { - progress(p * 0.5) - return p; - }; - } - - convolve3x3( - inData, tmpData, width, height, - [[a00, a01, a02], - [a10, 0, a12], - [a20, a21, a22]] - ); - - for (var i=0;i> 0) / 100 * 0.5; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - - // A 3x3 Sobel edge detect (similar to Photoshop's) - findedges : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - i, - data1 = [], - data2 = [], - gr1, gr2, gg1, gg2, gb1, gb2, - prog, lastProg = 0, - convProgress1, convProgress2; - - if (progress) { - convProgress1 = function(p) { - progress(p * 0.4); - return p; - }; - convProgress2 = function(p) { - progress(0.4 + p * 0.4); - return p; - }; - } - - convolve3x3(inData, data1, width, height, - [[-1, 0, 1], - [-2, 0, 2], - [-1, 0, 1]] - ); - convolve3x3(inData, data2, width, height, - [[-1, -2, -1], - [ 0, 0, 0], - [ 1, 2, 1]] - ); - - for (i=0;i> 0) / 100 * 0.2; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - // A 3x3 edge enhance - edgeenhance3x3 : function(inData, outData, width, height, options, progress) { - convolve3x3( - inData, outData, width, height, - [[-1/9, -1/9, -1/9], - [-1/9, 17/9, -1/9], - [-1/9, -1/9, -1/9]], - progress - ); - }, - - // A 5x5 edge enhance - edgeenhance5x5 : function(inData, outData, width, height, options, progress) { - convolve5x5( - inData, outData, width, height, - [[-1/25, -1/25, -1/25, -1/25, -1/25], - [-1/25, -1/25, -1/25, -1/25, -1/25], - [-1/25, -1/25, 49/25, -1/25, -1/25], - [-1/25, -1/25, -1/25, -1/25, -1/25], - [-1/25, -1/25, -1/25, -1/25, -1/25]], - progress - ); - }, - - // A 3x3 Laplacian edge-detect - laplace3x3 : function(inData, outData, width, height, options, progress) { - convolve3x3( - inData, outData, width, height, - [[-1, -1, -1], - [-1, 8, -1], - [-1, -1, -1]], - progress, - false, true, true - ); - }, - - // A 5x5 Laplacian edge-detect - laplace5x5 : function(inData, outData, width, height, options, progress) { - convolve5x5( - inData, outData, width, height, - [[-1, -1, -1, -1, -1], - [-1, -1, -1, -1, -1], - [-1, -1, 24, -1, -1], - [-1, -1, -1, -1, -1], - [-1, -1, -1, -1, -1]], - progress, - false, true, true - ); - }, - - coloradjust : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - r, g, b, - prog, lastProg = 0, - ar = clamp(options.r, -1, 1) * 255, - ag = clamp(options.g, -1, 1) * 255, - ab = clamp(options.b, -1, 1) * 255; - - for (var i=0;i 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - outData[i] = r; - outData[i+1] = g; - outData[i+2] = b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - colorfilter : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - i, r, g, b, - luminosity = !!options.luminosity, - prog, lastProg = 0, - min, max, h, l, h1, chroma, tmp, m, - ar = clamp(options.r, 0, 1), - ag = clamp(options.g, 0, 1), - ab = clamp(options.b, 0, 1); - - for (i=0;i max) max = g; - if (b > max) max = b; - if (g < min) min = g; - if (b < min) min = b; - chroma = (max - min); - - if (r == max) { - h = ((g - b) / chroma) % 6; - } else if (g == max) { - h = ((b - r) / chroma) + 2; - } else { - h = ((r - g) / chroma) + 4; - } - - h1 = h >> 0; - tmp = chroma * (h - h1); - r = g = b = l - (r * 0.3 + g * 0.59 + b * 0.11); - - if (h1 == 0) { - r += chroma; - g += tmp; - } else if (h1 == 1) { - r += chroma - tmp; - g += chroma; - } else if (h1 == 2) { - g += chroma; - b += tmp; - } else if (h1 == 3) { - g += chroma - tmp; - b += chroma; - } else if (h1 == 4) { - r += tmp; - b += chroma; - } else if (h1 == 5) { - r += chroma; - b += chroma - tmp; - } - } - - outData[i] = r * 255; - outData[i+1] = g * 255; - outData[i+2] = b * 255; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - hsl : function(inData, outData, width, height, options, progress) { - var n = width * height * 4, - hue = clamp(options.hue, -1, 1), - saturation = clamp(options.saturation, -1, 1), - lightness = clamp(options.lightness, -1, 1), - satMul = 1 + saturation * (saturation < 0 ? 1 : 2), - lightMul = lightness < 0 ? 1 + lightness : 1 - lightness, - lightAdd = lightness < 0 ? 0 : lightness * 255, - vs, ms, vm, h, s, l, v, m, vmh, sextant, - prog, lastProg = 0; - - hue = (hue * 6) % 6; - - for (var i=0;i vs) vs = g; - if (b > vs) vs = b; - ms = r; - if (g < ms) ms = g; - if (b < ms) ms = b; - vm = (vs-ms); - l = (ms+vs)/510; - - if (l > 0 && vm > 0) { - if (l <= 0.5) { - s = vm / (vs+ms) * satMul; - if (s > 1) s = 1; - v = (l * (1+s)); - } else { - s = vm / (510-vs-ms) * satMul; - if (s > 1) s = 1; - v = (l+s - l*s); - } - if (r == vs) { - if (g == ms) { - h = 5 + ((vs-b)/vm) + hue; - } else { - h = 1 - ((vs-g)/vm) + hue; - } - } else if (g == vs) { - if (b == ms) { - h = 1 + ((vs-r)/vm) + hue; - } else { - h = 3 - ((vs-b)/vm) + hue; - } - } else { - if (r == ms) { - h = 3 + ((vs-g)/vm) + hue; - } else { - h = 5 - ((vs-r)/vm) + hue; - } - } - if (h < 0) h += 6; - if (h >= 6) h -= 6; - m = (l + l - v); - sextant = h >> 0; - vmh = (v - m) * (h - sextant); - if (sextant == 0) { - r = v; - g = m + vmh; - b = m; - } else if (sextant == 1) { - r = v - vmh; - g = v; - b = m; - } else if (sextant == 2) { - r = m; - g = v; - b = m + vmh; - } else if (sextant == 3) { - r = m; - g = v - vmh; - b = v; - } else if (sextant == 4) { - r = m + vmh; - g = m; - b = v; - } else if (sextant == 5) { - r = v; - g = m; - b = v - vmh; - } - - r *= 255; - g *= 255; - b *= 255; - } - } - - r = r * lightMul + lightAdd; - g = g * lightMul + lightAdd; - b = b * lightMul + lightAdd; - - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - - outData[i] = r; - outData[i+1] = g; - outData[i+2] = b; - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - }, - - posterize : function(inData, outData, width, height, options, progress) { - var numLevels = clamp(options.levels, 2, 256), - numAreas = 256 / numLevels, - numValues = 256 / (numLevels-1), - r, g, b, - n = width * height * 4, - prog, lastProg = 0; - - for (i=0;i>0); - outData[i+1] = numValues * ((inData[i+1] / numAreas)>>0); - outData[i+2] = numValues * ((inData[i+2] / numAreas)>>0); - - outData[i+3] = inData[i+3]; - - if (progress) { - prog = (i/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - - }, - - removenoise : function(inData, outData, width, height, options, progress) { - var r, g, b, c, y, x, idx, - pyc, pyp, pyn, - pxc, pxp, pxn, - minR, minG, minB, maxR, maxG, maxB, - n, prog, lastProg = 0; - - n = width * height * 4; - - for (y=0;y= width-1) pyn = pyc; - - for (x=0;x= width-1) pxn = pxc; - - minR = maxR = inData[pyc + pxp]; - c = inData[pyc + pxn]; - if (c < minR) minR = c; - if (c > maxR) maxR = c; - c = inData[pyp + pxc]; - if (c < minR) minR = c; - if (c > maxR) maxR = c; - c = inData[pyn + pxc]; - if (c < minR) minR = c; - if (c > maxR) maxR = c; - - minG = inData[pyc + pxp + 1]; - c = inData[pyc + pxn + 1]; - if (c < minG) minG = c; - c = inData[pyp + pxc + 1]; - if (c < minG) minG = c; - c = inData[pyn + pxc + 1]; - if (c < minG) minG = c; - - minB = inData[pyc + pxp + 2]; - c = inData[pyc + pxn + 2]; - if (c < minB) minB = c; - c = inData[pyp + pxc + 2]; - if (c < minB) minB = c; - c = inData[pyn + pxc + 2]; - if (c < minB) minB = c; - - r = inData[idx] - g = inData[idx + 1] - b = inData[idx + 2] - - if (r < minR) r = minR; - if (r > maxR) r = maxR; - if (g < minG) g = minG; - if (g > maxG) g = maxG; - if (b < minB) b = minB; - if (b > maxB) b = maxB; - - outData[idx] = r; - outData[idx+1] = g; - outData[idx+2] = b; - outData[idx+3] = inData[idx+3]; - - if (progress) { - prog = (idx/n*100 >> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }, - - mosaic : function(inData, outData, width, height, options, progress) { - - var blockSize = clamp(options.blockSize, 1, Math.max(width, height)), - yBlocks = Math.ceil(height / blockSize), - xBlocks = Math.ceil(width / blockSize), - y0, y1, x0, x1, idx, pidx, - n = yBlocks * xBlocks, - prog, lastProg = 0; - - for (i=0, y0=0, bidx=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - y0 = y1; - } - }, - - equalize : function(inData, outData, width, height, options, progress) { - var n = width * height, p, i, level, ratio, - prog, lastProg; - var round = Math.round; - // build histogram - var pdf = new Array(256); - for (i=0;i<256;i++) { - pdf[i] = 0; - } - - for (i=0;i> 0) / 100; - if (prog > lastProg) { - lastProg = progress(prog); - } - } - } - } - }; - -})(); - - -Pixastic.Worker = function() { - var me = this; - function processMessage(data) { - var queue = data.queue, - inData = data.inData, - outData = data.outData, - width = data.width, - height = data.height, - tmpData; - - for (var i=0;i 0) { - tmpData = inData; - inData = outData; - outData = tmpData; - } - - Pixastic.Effects[e](inData.data, outData.data, width, height, options); - - me.onmessage({ - data : { - event : "progress", - data : (i+1) / queue.length - } - }); - } - - me.onmessage({ - data : { - event : "done", - data : outData - } - }); - } - - this.postMessage = function(data) { - setTimeout(function() { - processMessage(data) - }, 0); - } - - this.onmessage = function() {}; - -} - -var ComicBook = (function($) { - - 'use strict'; - - /** - * Merge two arrays. Any properties in b will replace the same properties in - * a. New properties from b will be added to a. - * - * @param a {Object} - * @param b {Object} - */ - function merge(a, b) { - - var prop; - - if (typeof b === 'undefined') { - b = {}; - } - - for (prop in a) { - if (a.hasOwnProperty(prop)) { - if (prop in b) { - continue; - } - b[prop] = a[prop]; - } - } - - return b; - } - - /** - * Exception class. Always throw an instance of this when throwing exceptions. - * - * @param {String} type - * @param {Object} object - * @returns {ComicBookException} - */ - var ComicBookException = { - INVALID_ACTION: 'invalid action', - INVALID_PAGE: 'invalid page', - INVALID_PAGE_TYPE: 'invalid page type', - UNDEFINED_CONTROL: 'undefined control', - INVALID_ZOOM_MODE: 'invalid zoom mode', - INVALID_NAVIGATION_EVENT: 'invalid navigation event' - }; - - function ComicBook(id, srcs, opts) { - - var self = this; - var canvas_id = id; // canvas element id - this.srcs = srcs; // array of image srcs for pages - - var defaults = { - displayMode: 'double', // single / double - zoomMode: 'fitWindow', // manual / fitWidth / fitWindow - manga: false, // true / false - enhance: {}, - keyboard: { - next: 78, - previous: 80, - toolbar: 84, - toggleLayout: 76 - }, - vendorPath: 'vendor/', - forward_buffer: 3 - }; - - this.isMobile = false; - - // mobile enhancements - if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(navigator.userAgent)) { - this.isMobile = true; - document.body.classList.add('mobile'); - defaults.displayMode = 'single'; - - window.addEventListener('load', function() { - setTimeout(function() { - window.scrollTo(0, 1); - }, 0); - }); - } - - var options = merge(defaults, opts); // options array for internal use - - var no_pages = srcs.length; - var pages = []; // array of preloaded Image objects - var canvas; // the HTML5 canvas object - var context; // the 2d drawing context - var loaded = []; // the images that have been loaded so far - var scale = 1; // page zoom scale, 1 = 100% - var is_double_page_spread = false; - var controlsRendered = false; // have the user controls been inserted into the dom yet? - var page_requested = false; // used to request non preloaded pages - var shiv = false; - - /** - * Gets the window.innerWidth - scrollbars - */ - function windowWidth() { - - var height = window.innerHeight + 1; - - if (shiv === false) { - shiv = $(document.createElement('div')) - .attr('id', 'cb-width-shiv') - .css({ - width: '100%', - position: 'absolute', - top: 0, - zIndex: '-1000' - }); - - $('body').append(shiv); - } - - shiv.height(height); - - return shiv.innerWidth(); - } - - /** - * enables the back button - */ - function checkHash() { - - var hash = getHash(); - - if (hash !== pointer && loaded.indexOf(hash) > -1) { - pointer = hash; - self.draw(); - } - } - - function getHash() { - var hash = parseInt(location.hash.substring(1), 10) - 1 || 0; - if (hash < 0) { - setHash(0); - hash = 0; - } - return hash; - } - - function setHash(pageNo) { - location.hash = pageNo; - } - - // page hash on first load - var hash = getHash(); - - // the current page, can pass a default as a url hash - var pointer = (hash < srcs.length) ? hash : 0; - - /** - * Setup the canvas element for use throughout the class. - * - * @see #ComicBook.prototype.draw - * @see #ComicBook.prototype.enhance - */ - function init() { - - // setup canvas - canvas = document.getElementById(canvas_id); - context = canvas.getContext('2d'); - - // render user controls - if (controlsRendered === false) { - self.renderControls(); - controlsRendered = true; - } - - // add page controls - window.addEventListener('keydown', self.navigation, false); - window.addEventListener('hashchange', checkHash, false); - } - - window.addEventListener('touchstart', function(e) { - var $el = $(e.target); - if ($el.attr('id') === 'comic') { - self.toggleToolbar(); - } - if ($el.data('toggle') === 'dropdown') { - $el.siblings('.dropdown').toggle(); - } - }, false); - - /** - * Render Handlebars templates. Templates with data-trigger & data-action will - * have the specified events bound. - */ - ComicBook.prototype.renderControls = function() { - - var controls = {}, - $toolbar; - - $.each(Handlebars.templates, function(name, template) { - - var $template = $(template().trim()); - controls[name] = $template; - - // add event listeners to controls that specify callbacks - $template.find('*').andSelf().filter('[data-action][data-trigger]').each(function() { - - var $this = $(this); - var trigger = $this.data('trigger'); - var action = $this.data('action'); - - // trigger a direct method if exists - if (typeof self[$this.data('action')] === 'function') { - $this.on(trigger, self[action]); - } - - // throw an event to be caught outside if the app code - $this.on(trigger, function(e) { - $(self).trigger(trigger, e); - }); - }); - - $(canvas).before($template); - }); - - this.controls = controls; - - $toolbar = this.getControl('toolbar'); - $toolbar - .find('.manga-' + options.manga).show().end() - .find('.manga-' + !options.manga).hide().end() - .find('.layout').hide().end().find('.layout-' + options.displayMode).show(); - - }; - - ComicBook.prototype.getControl = function(control) { - if (typeof this.controls[control] !== 'object') { - throw ComicBookException.UNDEFINED_CONTROL + ' ' + control; - } - return this.controls[control]; - }; - - ComicBook.prototype.showControl = function(control) { - this.getControl(control).show().addClass('open'); - }; - - ComicBook.prototype.hideControl = function(control) { - this.getControl(control).removeClass('open').hide(); - }; - - ComicBook.prototype.toggleControl = function(control) { - this.getControl(control).toggle().toggleClass('open'); - }; - - ComicBook.prototype.toggleLayout = function() { - - var $toolbar = self.getControl('toolbar'); - var displayMode = (options.displayMode === 'single') ? 'double' : 'single'; - - options.displayMode = displayMode; - - $toolbar.find('.layout').hide().end().find('.layout-' + options.displayMode).show(); - - self.drawPage(); - }; - - /** - * Get the image for a given page. - * - * @return Image - */ - ComicBook.prototype.getPage = function(i) { - - if (i < 0 || i > srcs.length - 1) { - throw ComicBookException.INVALID_PAGE + ' ' + i; - } - - if (typeof pages[i] === 'object') { - return pages[i]; - } else { - page_requested = i; - this.showControl('loadingOverlay'); - } - }; - - /** - * @see #preload - */ - ComicBook.prototype.draw = function() { - - init(); - - // resize navigation controls - $('.navigate').outerHeight(window.innerHeight); - $('#cb-loading-overlay').outerWidth(windowWidth()).height(window.innerHeight); - - // preload images if needed - if (pages.length !== no_pages) { - this.preload(); - } else { - this.drawPage(); - } - }; - - /** - * Zoom the canvas - * - * @param new_scale {Number} Scale the canvas to this ratio - */ - ComicBook.prototype.zoom = function(new_scale) { - options.zoomMode = 'manual'; - scale = new_scale; - if (typeof this.getPage(pointer) === 'object') { - this.drawPage(); - } - }; - - ComicBook.prototype.zoomIn = function() { - self.zoom(scale + 0.1); - }; - - ComicBook.prototype.zoomOut = function() { - self.zoom(scale - 0.1); - }; - - ComicBook.prototype.fitWidth = function() { - options.zoomMode = 'fitWidth'; - self.drawPage(); - }; - - ComicBook.prototype.fitWindow = function() { - options.zoomMode = 'fitWindow'; - self.drawPage(); - }; - - /** - * Preload all images, draw the page only after a given number have been loaded. - * - * @see #drawPage - */ - ComicBook.prototype.preload = function() { - - var i = pointer; // the current page counter for this method - var rendered = false; - var queue = []; - - this.showControl('loadingOverlay'); - - function loadImage(i) { - - var page = new Image(); - page.src = srcs[i]; - - page.onload = function() { - - pages[i] = this; - loaded.push(i); - - $('#cb-progress-bar .progressbar-value').css('width', Math.floor((loaded.length / no_pages) * 100) + '%'); - - // double page mode needs an extra page added - var buffer = (options.displayMode === 'double' && pointer < srcs.length - 1) ? 1 : 0; - - // start rendering the comic when the requested page is ready - if ((rendered === false && ($.inArray(pointer + buffer, loaded) !== -1) || - (typeof page_requested === 'number' && $.inArray(page_requested, loaded) !== -1))) { - // if the user is waiting for a page to be loaded, render that one instead of the default pointer - if (typeof page_requested === 'number') { - pointer = page_requested - 1; - page_requested = false; - } - - self.drawPage(); - self.hideControl('loadingOverlay'); - rendered = true; - } - - if (queue.length) { - loadImage(queue[0]); - queue.splice(0, 1); - } else { - $('#cb-status').delay(500).fadeOut(); - } - }; - } - - // loads pages in both directions so you don't have to wait for all pages - // to be loaded before you can scroll backwards - function preload(start, stop) { - - var j = 0; - var count = 1; - var forward = start; - var backward = start - 1; - - while (forward <= stop) { - - if (count > options.forward_buffer && backward > -1) { - queue.push(backward); - backward--; - count = 0; - } else { - queue.push(forward); - forward++; - } - count++; - } - - while (backward > -1) { - queue.push(backward); - backward--; - } - - loadImage(queue[j]); - } - - preload(i, srcs.length - 1); - }; - - ComicBook.prototype.pageLoaded = function(page_no) { - return (typeof loaded[page_no - 1] !== 'undefined'); - }; - - /** - * Draw the current page in the canvas - */ - ComicBook.prototype.drawPage = function(page_no, reset_scroll) { - - var scrollY; - - reset_scroll = (typeof reset_scroll !== 'undefined') ? reset_scroll : true; - scrollY = reset_scroll ? 0 : window.scrollY; - - // if a specific page is given try to render it, if not bail and wait for preload() to render it - if (typeof page_no === 'number' && page_no < srcs.length && page_no > 0) { - pointer = page_no - 1; - if (!this.pageLoaded(page_no)) { - this.showControl('loadingOverlay'); - return; - } - } - - if (pointer < 0) { - pointer = 0; - } - - var zoom_scale; - var offsetW = 0, - offsetH = 0; - - var page = self.getPage(pointer); - var page2 = false; - - if (options.displayMode === 'double' && pointer < srcs.length - 1) { - page2 = self.getPage(pointer + 1); - } - - if (typeof page !== 'object') { - throw ComicBookException.INVALID_PAGE_TYPE + ' ' + typeof page; - } - - var width = page.width, - height = page.height; - - // reset the canvas to stop duplicate pages showing - canvas.width = 0; - canvas.height = 0; - - // show double page spreads on a single page - is_double_page_spread = ( - typeof page2 === 'object' && - (page.width > page.height || page2.width > page2.height) && - options.displayMode === 'double' - ); - if (is_double_page_spread) { - options.displayMode = 'single'; - } - - if (options.displayMode === 'double') { - - // for double page spreads, factor in the width of both pages - if (typeof page2 === 'object') { - width += page2.width; - } - - // if this is the last page and there is no page2, still keep the canvas wide - else { - width += width; - } - } - - // update the page scale if a non manual mode has been chosen - switch (options.zoomMode) { - - case 'manual': - document.body.style.overflowX = 'auto'; - zoom_scale = (options.displayMode === 'double') ? scale * 2 : scale; - break; - - case 'fitWidth': - document.body.style.overflowX = 'hidden'; - - // scale up if the window is wider than the page, scale down if the window - // is narrower than the page - zoom_scale = (windowWidth() > width) ? ((windowWidth() - width) / windowWidth()) + 1 : windowWidth() / width; - - // update the interal scale var so switching zoomModes while zooming will be smooth - scale = zoom_scale; - break; - - case 'fitWindow': - document.body.style.overflowX = 'hidden'; - - var width_scale = (windowWidth() > width) ? - ((windowWidth() - width) / windowWidth()) + 1 // scale up if the window is wider than the page - : - windowWidth() / width; // scale down if the window is narrower than the page - var windowHeight = window.innerHeight; - var height_scale = (windowHeight > height) ? - ((windowHeight - height) / windowHeight) + 1 // scale up if the window is wider than the page - : - windowHeight / height; // scale down if the window is narrower than the page - - zoom_scale = (width_scale > height_scale) ? height_scale : width_scale; - scale = zoom_scale; - break; - - default: - throw ComicBookException.INVALID_ZOOM_MODE + ' ' + options.zoomMode; - } - - var canvas_width = page.width * zoom_scale; - var canvas_height = page.height * zoom_scale; - - var page_width = (options.zoomMode === 'manual') ? page.width * scale : canvas_width; - var page_height = (options.zoomMode === 'manual') ? page.height * scale : canvas_height; - - canvas_height = page_height; - - // make sure the canvas is always at least full screen, even if the page is more narrow than the screen - canvas.width = (canvas_width < windowWidth()) ? windowWidth() : canvas_width; - canvas.height = (canvas_height < window.innerHeight) ? window.innerHeight : canvas_height; - - // always keep pages centered - if (options.zoomMode === 'manual' || options.zoomMode === 'fitWindow') { - - // work out a horizontal position - if (canvas_width < windowWidth()) { - offsetW = (windowWidth() - page_width) / 2; - if (options.displayMode === 'double') { - offsetW = offsetW - page_width / 2; - } - } - - // work out a vertical position - if (canvas_height < window.innerHeight) { - offsetH = (window.innerHeight - page_height) / 2; - } - } - - // in manga double page mode reverse the page(s) - if (options.manga && options.displayMode === 'double' && typeof page2 === 'object') { - var tmpPage = page; - var tmpPage2 = page2; - page = tmpPage2; - page2 = tmpPage; - } - - // draw the page(s) - context.drawImage(page, offsetW, offsetH, page_width, page_height); - if (options.displayMode === 'double' && typeof page2 === 'object') { - context.drawImage(page2, page_width + offsetW, offsetH, page_width, page_height); - } - - this.pixastic = new Pixastic(context, options.vendorPath + 'pixastic/'); - - // apply any image enhancements previously defined - $.each(options.enhance, function(action, options) { - self.enhance[action](options); - }); - - var current_page = - (options.displayMode === 'double' && - pointer + 2 <= srcs.length) ? (pointer + 1) + '-' + (pointer + 2) : pointer + 1; - - this.getControl('toolbar') - .find('#current-page').text(current_page) - .end() - .find('#page-count').text(srcs.length); - - // revert page mode back to double if it was auto switched for a double page spread - if (is_double_page_spread) { - options.displayMode = 'double'; - } - - // disable the fit width button if needed - $('button.cb-fit-width').attr('disabled', (options.zoomMode === 'fitWidth')); - $('button.cb-fit-window').attr('disabled', (options.zoomMode === 'fitWindow')); - - // disable prev/next buttons if not needed - $('.navigate').show(); - if (pointer === 0) { - if (options.manga) { - $('.navigate-left').show(); - $('.navigate-right').hide(); - } else { - $('.navigate-left').hide(); - $('.navigate-right').show(); - } - } - - if (pointer === srcs.length - 1 || (typeof page2 === 'object' && pointer === srcs.length - 2)) { - if (options.manga) { - $('.navigate-left').hide(); - $('.navigate-right').show(); - } else { - $('.navigate-left').show(); - $('.navigate-right').hide(); - } - } - - if (pointer !== getHash()) { - $(this).trigger('navigate'); - } - - // update hash location - if (getHash() !== pointer) { - setHash(pointer + 1); - } - }; - - /** - * Increment the counter and draw the page in the canvas - * - * @see #drawPage - */ - ComicBook.prototype.drawNextPage = function() { - - var page; - - try { - page = self.getPage(pointer + 1); - } catch (e) {} - - if (!page) { - return false; - } - - if (pointer + 1 < pages.length) { - pointer += (options.displayMode === 'single' || is_double_page_spread) ? 1 : 2; - try { - self.drawPage(); - } catch (e) {} - } - - // make sure the top of the page is in view - window.scroll(0, 0); - }; - - /** - * Decrement the counter and draw the page in the canvas - * - * @see #drawPage - */ - ComicBook.prototype.drawPrevPage = function() { - - var page; - - try { - page = self.getPage(pointer - 1); - } catch (e) {} - - if (!page) { - return false; - } - - is_double_page_spread = (page.width > page.height); // need to run double page check again here as we are going backwards - - if (pointer > 0) { - pointer -= (options.displayMode === 'single' || is_double_page_spread) ? 1 : 2; - self.drawPage(); - } - - // make sure the top of the page is in view - window.scroll(0, 0); - }; - - ComicBook.prototype.brightness = function() { - self.enhance.brightness({ - brightness: $(this).val() - }); - }; - - ComicBook.prototype.contrast = function() { - self.enhance.brightness({ - contrast: $(this).val() - }); - }; - - ComicBook.prototype.sharpen = function() { - self.enhance.sharpen({ - strength: $(this).val() - }); - }; - - ComicBook.prototype.desaturate = function() { - if ($(this).is(':checked')) { - self.enhance.desaturate(); - } else { - self.enhance.resaturate(); - } - }; - - ComicBook.prototype.resetEnhancements = function() { - self.enhance.reset(); - }; - - /** - * Apply image enhancements to the canvas. - * - * Powered by the awesome Pixastic: http://www.pixastic.com/ - * - * TODO: reset & apply all image enhancements each time before applying new one - * TODO: abstract this into an 'Enhance' object, separate from ComicBook? - */ - ComicBook.prototype.enhance = { - - /** - * Reset enhancements. - * This can reset a specific enhancement if the method name is passed, or - * it will reset all. - * - * @param method {string} the specific enhancement to reset - */ - reset: function(method) { - if (!method) { - options.enhance = {}; - } else { - delete options.enhance[method]; - } - self.drawPage(null, false); - }, - - /** - * Pixastic progress callback - * @param {float} progress - */ - // progress: function (progress) { - progress: function() { - // console.info(Math.floor(progress * 100)); - }, - - /** - * Pixastic on complete callback - */ - done: function() { - - }, - - /** - * Adjust brightness / contrast - * - * params - * brightness (int) -150 to 150 - * contrast: (float) -1 to infinity - * - * @param {Object} params Brightness & contrast levels - * @param {Boolean} reset Reset before applying more enhancements? - */ - brightness: function(params, reset) { - - if (reset !== false) { - this.reset('brightness'); - } - - // merge user options with defaults - var opts = merge({ - brightness: 0, - contrast: 0 - }, params); - - // remember options for later - options.enhance.brightness = opts; - - // run the enhancement - self.pixastic.brightness({ - brightness: opts.brightness, - contrast: opts.contrast - }).done(this.done, this.progress); - }, - - /** - * Force black and white - */ - desaturate: function() { - options.enhance.desaturate = {}; - self.pixastic.desaturate().done(this.done, this.progress); - }, - - /** - * Undo desaturate - */ - resaturate: function() { - delete options.enhance.desaturate; - self.drawPage(null, false); - }, - - /** - * Sharpen - * - * options: - * strength: number (-1 to infinity) - * - * @param {Object} options - */ - sharpen: function(params) { - - this.desharpen(); - - var opts = merge({ - strength: 0 - }, params); - - options.enhance.sharpen = opts; - - self.pixastic.sharpen3x3({ - strength: opts.strength - }).done(this.done, this.progress); - }, - - desharpen: function() { - delete options.enhance.sharpen; - self.drawPage(null, false); - } - }; - - ComicBook.prototype.navigation = function(e) { - - // disable navigation when the overlay is showing - if ($('#cb-loading-overlay').is(':visible')) { - return false; - } - - var side = false; - - switch (e.type) { - - case 'click': - side = e.currentTarget.getAttribute('data-navigate-side'); - break; - - case 'keydown': - - // navigation - if (e.keyCode === options.keyboard.previous) { - side = 'left'; - } - if (e.keyCode === options.keyboard.next) { - side = 'right'; - } - - // display controls - if (e.keyCode === options.keyboard.toolbar) { - self.toggleToolbar(); - } - if (e.keyCode === options.keyboard.toggleLayout) { - self.toggleLayout(); - } - break; - - default: - throw ComicBookException.INVALID_NAVIGATION_EVENT + ' ' + e.type; - } - - if (side) { - - e.stopPropagation(); - - // western style (left to right) - if (!options.manga) { - if (side === 'left') { - self.drawPrevPage(); - } - if (side === 'right') { - self.drawNextPage(); - } - } - // manga style (right to left) - else { - if (side === 'left') { - self.drawNextPage(); - } - if (side === 'right') { - self.drawPrevPage(); - } - } - - return false; - } - }; - - ComicBook.prototype.toggleReadingMode = function() { - options.manga = !options.manga; - self.getControl('toolbar') - .find('.manga-' + options.manga).show().end() - .find('.manga-' + !options.manga).hide(); - }; - - ComicBook.prototype.toggleToolbar = function() { - self.toggleControl('toolbar'); - }; - - ComicBook.prototype.destroy = function() { - - $.each(this.controls, function(name, $control) { - $control.remove(); - }); - - canvas.width = 0; - canvas.height = 0; - - window.removeEventListener('keydown', this.navigation, false); - window.removeEventListener('hashchange', checkHash, false); - - setHash(''); - - // $(this).trigger('destroy'); - }; - - } - - return ComicBook; - -})(jQuery); - -// lib/handlebars/base.js -/*jshint eqnull:true*/ -this.Handlebars = {}, - function(e) { - e.VERSION = "1.0.rc.1", e.helpers = {}, e.partials = {}, e.registerHelper = function(e, t, n) { - n && (t.not = n), this.helpers[e] = t - }, e.registerPartial = function(e, t) { - this.partials[e] = t - }, e.registerHelper("helperMissing", function(e) { - if (arguments.length === 2) return undefined; - throw new Error("Could not find property '" + e + "'") - }); - var t = Object.prototype.toString, - n = "[object Function]"; - e.registerHelper("blockHelperMissing", function(r, i) { - var s = i.inverse || function() {}, - o = i.fn, - u = "", - a = t.call(r); - return a === n && (r = r.call(this)), r === !0 ? o(this) : r === !1 || r == null ? s(this) : a === "[object Array]" ? r.length > 0 ? e.helpers.each(r, i) : s(this) : o(r) - }), e.K = function() {}, e.createFrame = Object.create || function(t) { - e.K.prototype = t; - var n = new e.K; - return e.K.prototype = null, n - }, e.registerHelper("each", function(t, n) { - var r = n.fn, - i = n.inverse, - s = 0, - o = "", - u; - n.data && (u = e.createFrame(n.data)); - if (t && typeof t == "object") - if (t instanceof Array) - for (var a = t.length; s < a; s++) u && (u.index = s), o += r(t[s], { - data: u - }); - else - for (var f in t) t.hasOwnProperty(f) && (u && (u.key = f), o += r(t[f], { - data: u - }), s++); - return s === 0 && (o = i(this)), o - }), e.registerHelper("if", function(r, i) { - var s = t.call(r); - return s === n && (r = r.call(this)), !r || e.Utils.isEmpty(r) ? i.inverse(this) : i.fn(this) - }), e.registerHelper("unless", function(t, n) { - var r = n.fn, - i = n.inverse; - return n.fn = i, n.inverse = r, e.helpers["if"].call(this, t, n) - }), e.registerHelper("with", function(e, t) { - return t.fn(e) - }), e.registerHelper("log", function(t) { - e.log(t) - }) - }(this.Handlebars); -var errorProps = ["description", "fileName", "lineNumber", "message", "name", "number", "stack"]; -Handlebars.Exception = function(e) { - var t = Error.prototype.constructor.apply(this, arguments); - for (var n = 0; n < errorProps.length; n++) this[errorProps[n]] = t[errorProps[n]] - }, Handlebars.Exception.prototype = new Error, Handlebars.SafeString = function(e) { - this.string = e - }, Handlebars.SafeString.prototype.toString = function() { - return this.string.toString() - }, - function() { - var e = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`" - }, - t = /[&<>"'`]/g, - n = /[&<>"'`]/, - r = function(t) { - return e[t] || "&" - }; - Handlebars.Utils = { - escapeExpression: function(e) { - return e instanceof Handlebars.SafeString ? e.toString() : e == null || e === !1 ? "" : n.test(e) ? e.replace(t, r) : e - }, - isEmpty: function(e) { - return typeof e == "undefined" ? !0 : e === null ? !0 : e === !1 ? !0 : Object.prototype.toString.call(e) === "[object Array]" && e.length === 0 ? !0 : !1 - } - } - }(), Handlebars.VM = { - template: function(e) { - var t = { - escapeExpression: Handlebars.Utils.escapeExpression, - invokePartial: Handlebars.VM.invokePartial, - programs: [], - program: function(e, t, n) { - var r = this.programs[e]; - return n ? Handlebars.VM.program(t, n) : r ? r : (r = this.programs[e] = Handlebars.VM.program(t), r) - }, - programWithDepth: Handlebars.VM.programWithDepth, - noop: Handlebars.VM.noop - }; - return function(n, r) { - return r = r || {}, e.call(t, Handlebars, n, r.helpers, r.partials, r.data) - } - }, - programWithDepth: function(e, t, n) { - var r = Array.prototype.slice.call(arguments, 2); - return function(n, i) { - return i = i || {}, e.apply(this, [n, i.data || t].concat(r)) - } - }, - program: function(e, t) { - return function(n, r) { - return r = r || {}, e(n, r.data || t) - } - }, - noop: function() { - return "" - }, - invokePartial: function(e, t, n, r, i, s) { - var o = { - helpers: r, - partials: i, - data: s - }; - if (e === undefined) throw new Handlebars.Exception("The partial " + t + " could not be found"); - if (e instanceof Function) return e(n, o); - if (!Handlebars.compile) throw new Handlebars.Exception("The partial " + t + " could not be compiled when running in runtime-only mode"); - return i[t] = Handlebars.compile(e, { - data: s !== undefined - }), i[t](n, o) - } - }, Handlebars.template = Handlebars.VM.template; - - - -(function() { - var template = Handlebars.template, - templates = Handlebars.templates = Handlebars.templates || {}; - templates['loadingOverlay'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n"; - }); - templates['navigateLeft'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n \n
\n"; - }); - templates['navigateRight'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n \n
\n"; - }); - templates['progressbar'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "
\n
\n
\n
\n
\n"; - }); - templates['toolbar'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n\n
    \n
  • \n \n
  • \n
  • \n
  • \n \n
    \n
    \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n
    \n \n \n
    \n
    \n \n
    \n
    \n
    \n
  • \n
  • \n \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n \n
  • \n
\n\n
    \n
  • /
  • \n
\n\n
\n"; - }); -})(); /* exported ComicBook */ - -(function(root, $) { - - var previousReader = root.cbReader || {}; - - var cbReader = root.cbReader = function(path, options) { - return new CBRJS.Reader(path, options); - }; - - //exports to multiple environments - if (typeof define === 'function' && define.amd) { - //AMD - define(function(){ return Reader; }); - } else if (typeof module != "undefined" && module.exports) { - //Node - module.exports = cbReader; - } - -})(window, jQuery); - - diff --git a/reader/vendor/cbrjs/cbr2.js b/reader/vendor/cbrjs/cbr2.js deleted file mode 100644 index 80f7e72..0000000 --- a/reader/vendor/cbrjs/cbr2.js +++ /dev/null @@ -1,1460 +0,0 @@ -var Pixastic = function() { - function t(e, t, n) { - return e.createImageData ? e.createImageData(t, n) : e.getImageData(0, 0, t, n) - } - function n(r, i) { - var s = {} - , o = r.canvas.width - , u = r.canvas.height - , a = [] - , i = i || ""; - if (!e) { - if (typeof window.Worker != "undefined") - try { - e = new window.Worker(i + "pixastic.worker.control.js") - } catch (f) { - location.protocol == "file:" ? n.log("Could not create real worker, running from file://") : n.log("Could not create real worker.") - } - e || (e = new n.Worker) - } - for (var f in n.Effects) - n.Effects.hasOwnProperty(f) && function(n) { - s[n] = function(e) { - return a.push({ - effect: n, - options: e - }), - s - } - , - s.done = function(n, i) { - var s, f; - try { - s = r.getImageData(0, 0, o, u) - } catch (l) { - throw location.protocol == "file:" ? new Error("Could not access image data, running from file://") : new Error("Could not access image data, is canvas tainted by cross-origin data?") - } - f = t(r, o, u), - e.postMessage({ - queue: a, - inData: s, - outData: f, - width: o, - height: u - }), - e.onmessage = function(e) { - var t = e.data; - switch (t.event) { - case "done": - r.putImageData(t.data, 0, 0), - n && n(), - i && i(1); - break; - case "progress": - i && i(t.data); - break; - case "error": - } - } - , - i && i(0) - } - }(f); - return s - } - function r(e) { - var t; - if (typeof e == "object") - if (typeof e.tagName == "string") { - if (e.tagName.toLowerCase() == "canvas" || e.tagName.toLowerCase() == "img") - t = document.createElement("canvas"), - t.width = e.width, - t.height = e.height, - t.getContext("2d").drawImage(e, 0, 0) - } else if (window.ImageData && e instanceof window.ImageData || typeof e.width == "number" && typeof e.height == "number" && typeof e.data == "object") - t = document.createElement("canvas"), - t.width = e.width, - t.height = e.height, - t.getContext("2d").putImageData(e, 0, 0); - return t - } - function i(e) { - var t = r(e) - , n = new Image; - return n.width = t.width, - n.height = t.height, - n.src = t.toDataURL(), - n - } - function s(e) { - var t = r(e) - , n = t.getContext("2d"); - return n.getImageData(0, 0, t.width, t.height) - } - function o(e) { - var t = [], n, r, i = e.data, s = Math.round, o, u = e.width * e.height; - for (n = 0; n < 256; n++) - t[n] = 0; - for (n = 0; n < u; n++) - r = n * 4, - t[s((i[r] + i[r + 1] + i[r + 2]) / 3)]++; - o = 0; - for (n = 0; n < 256; n++) - t[n] > o && (o = t[n]); - return { - maxValue: o, - values: t - } - } - var e; - return n.Worker = function() { - function t(t) { - var r = t.queue, i = t.inData, s = t.outData, o = t.width, u = t.height, a; - for (var f = 0; f < r.length; f++) { - var l = r[f].effect, c = r[f].options, h; - f > 0 && (a = i, - i = s, - s = a), - typeof importScripts == "function" && (h = function(t) { - return e.onmessage({ - data: { - event: "progress", - data: (f + t) / r.length - } - }), - t - } - ), - n.Effects[l](i.data, s.data, o, u, c, h), - e.onmessage({ - data: { - event: "progress", - data: (f + 1) / r.length - } - }) - } - e.onmessage({ - data: { - event: "done", - data: s - } - }) - } - var e = this; - this.postMessage = function(e) { - setTimeout(function() { - t(e) - }, 0) - } - , - this.onmessage = function() {} - } - , - n.log = function(e) { - typeof console != "undefined" && console.log && console.log("Pixastic: " + e) - } - , - n.toCanvas = r, - n.toImage = i, - n.toImageData = s, - n.histogram = o, - n.Color = { - rgb2hsl: function(e, t, n) { - e < 0 && (e = 0), - t < 0 && (t = 0), - n < 0 && (n = 0), - e > 255 && (e = 0), - t > 255 && (t = 0), - n > 255 && (n = 0) - }, - rgb2hsv: function(e, t, n) {}, - rgb2hex: function(e, t, n) {}, - hsl2rgb: function(e, t, n) {}, - hsv2rgb: function(e, t, n) {} - }, - n -}(); -Pixastic.Effects = function() { - function e(e, t) { - var n = {}; - for (var r in t) - typeof e[r] == "undefined" ? n[r] = t[r] : n[r] = e[r]; - return n - } - function t(e, t, n) { - return Math.min(n, Math.max(t, e)) - } - function n(e, t, n, r, i, s, o, u, a) { - var f, l, c, h, p, d, v, m, g, y, b, w, E, S, x = 0, T = n * r * 4, N = i[0][0], C = i[0][1], k = i[0][2], L = i[1][0], A = i[1][1], O = i[1][2], M = i[2][0], _ = i[2][1], D = i[2][2], P, H, B, j, F, I, q, R, U; - for (E = 0; E < r; ++E) { - d = E * n * 4, - v = d - n * 4, - m = d + n * 4, - E < 1 && (v = d), - E >= n - 1 && (m = d); - for (w = 0; w < n; ++w) - f = (E * n + w) * 4, - g = w * 4, - y = g - 4, - b = g + 4, - w < 1 && (y = g), - w >= n - 1 && (b = g), - P = v + y, - H = v + g, - B = v + b, - j = d + y, - F = d + g, - I = d + b, - q = m + y, - R = m + g, - U = m + b, - l = e[P] * N + e[H] * C + e[B] * k + e[j] * L + e[F] * A + e[I] * O + e[q] * M + e[R] * _ + e[U] * D, - c = e[P + 1] * N + e[H + 1] * C + e[B + 1] * k + e[j + 1] * L + e[F + 1] * A + e[I + 1] * O + e[q + 1] * M + e[R + 1] * _ + e[U + 1] * D, - h = e[P + 2] * N + e[H + 2] * C + e[B + 2] * k + e[j + 2] * L + e[F + 2] * A + e[I + 2] * O + e[q + 2] * M + e[R + 2] * _ + e[U + 2] * D, - o ? p = e[P + 3] * N + e[H + 3] * C + e[B + 3] * k + e[j + 3] * L + e[F + 3] * A + e[I + 3] * O + e[q + 3] * M + e[R + 3] * _ + e[U + 3] * D : p = e[f + 3], - a && (l = c = h = (l + c + h) / 3), - u && (l = 255 - l, - c = 255 - c, - h = 255 - h), - t[f] = l, - t[f + 1] = c, - t[f + 2] = h, - t[f + 3] = p, - s && (S = (f / T * 100 >> 0) / 100, - S > x && (x = s(S))) - } - } - function s(e, t, n, r, i, s, o, u, a) { - var f, l, c, h, p, d, v, m, g, y, b, w, E, S, x, T, N, C, k = 0, L = n * r * 4, A = i[0][0], O = i[0][1], M = i[0][2], _ = i[0][3], D = i[0][4], P = i[1][0], H = i[1][1], B = i[1][2], j = i[1][3], F = i[1][4], I = i[2][0], q = i[2][1], R = i[2][2], U = i[2][3], z = i[2][4], W = i[3][0], X = i[3][1], V = i[3][2], $ = i[3][3], J = i[3][4], K = i[4][0], Q = i[4][1], G = i[4][2], Y = i[4][3], Z = i[4][4], et, tt, nt, rt, it, st, ot, ut, at, ft, lt, ct, ht, pt, dt, vt, mt, gt, yt, bt, wt, Et, St, xt, Tt; - for (N = 0; N < r; ++N) { - d = N * n * 4, - v = d - n * 4, - g = d - n * 4 * 2, - m = d + n * 4, - y = d + n * 4 * 2, - N < 1 && (v = d), - N >= n - 1 && (m = d), - N < 2 && (g = v), - N >= n - 2 && (y = m); - for (T = 0; T < n; ++T) - f = (N * n + T) * 4, - b = T * 4, - w = b - 4, - E = b + 4, - S = b - 8, - x = b + 8, - T < 1 && (w = b), - T >= n - 1 && (E = b), - T < 2 && (S = w), - T >= n - 2 && (x = E), - et = g + S, - tt = g + w, - nt = g + b, - rt = g + E, - it = g + x, - st = v + S, - ot = v + w, - ut = v + b, - at = v + E, - ft = v + x, - lt = d + S, - ct = d + w, - ht = d + b, - pt = d + E, - dt = d + x, - vt = m + S, - mt = m + w, - gt = m + b, - yt = m + E, - bt = m + x, - wt = y + S, - Et = y + w, - St = y + b, - xt = y + E, - Tt = y + x, - l = e[et] * A + e[tt] * O + e[nt] * M + e[rt] * D + e[nt] * D + e[st] * P + e[ot] * H + e[ut] * B + e[at] * F + e[ut] * F + e[lt] * I + e[ct] * q + e[ht] * R + e[pt] * z + e[ht] * z + e[vt] * W + e[mt] * X + e[gt] * V + e[yt] * J + e[gt] * J + e[wt] * K + e[Et] * Q + e[St] * G + e[xt] * Z + e[St] * Z, - c = e[et + 1] * A + e[tt + 1] * O + e[nt + 1] * M + e[rt + 1] * D + e[nt + 1] * D + e[st + 1] * P + e[ot + 1] * H + e[ut + 1] * B + e[at + 1] * F + e[ut + 1] * F + e[lt + 1] * I + e[ct + 1] * q + e[ht + 1] * R + e[pt + 1] * z + e[ht + 1] * z + e[vt + 1] * W + e[mt + 1] * X + e[gt + 1] * V + e[yt + 1] * J + e[gt + 1] * J + e[wt + 1] * K + e[Et + 1] * Q + e[St + 1] * G + e[xt + 1] * Z + e[St + 1] * Z, - h = e[et + 2] * A + e[tt + 2] * O + e[nt + 2] * M + e[rt + 2] * D + e[nt + 2] * D + e[st + 2] * P + e[ot + 2] * H + e[ut + 2] * B + e[at + 2] * F + e[ut + 2] * F + e[lt + 2] * I + e[ct + 2] * q + e[ht + 2] * R + e[pt + 2] * z + e[ht + 2] * z + e[vt + 2] * W + e[mt + 2] * X + e[gt + 2] * V + e[yt + 2] * J + e[gt + 2] * J + e[wt + 2] * K + e[Et + 2] * Q + e[St + 2] * G + e[xt + 2] * Z + e[St + 2] * Z, - o ? p = e[et + 3] * A + e[tt + 3] * O + e[nt + 3] * M + e[rt + 3] * D + e[nt + 3] * D + e[st + 3] * P + e[ot + 3] * H + e[ut + 3] * B + e[at + 3] * F + e[ut + 3] * F + e[lt + 3] * I + e[ct + 3] * q + e[ht + 3] * R + e[pt + 3] * z + e[ht + 3] * z + e[vt + 3] * W + e[mt + 3] * X + e[gt + 3] * V + e[yt + 3] * J + e[gt + 3] * J + e[wt + 3] * K + e[Et + 3] * Q + e[St + 3] * G + e[xt + 3] * Z + e[St + 3] * Z : p = e[f + 3], - a && (l = c = h = (l + c + h) / 3), - u && (l = 255 - l, - c = 255 - c, - h = 255 - h), - t[f] = l, - t[f + 1] = c, - t[f + 2] = h, - t[f + 3] = p, - s && (C = (f / L * 100 >> 0) / 100, - C > k && (k = s(C))) - } - } - function o(e, n, r, i, s, o) { - var u, a, f, l, c, h = r * i * 4, p, d, v, m, g, y, b, w = [], E = 13, s = t(s, 3, E), S = -s / 2 + (s % 2 ? .5 : 0), x = s + S, T, N = [[1]], C, k = 0; - for (v = 1; v < E; ++v) - N[0][v] = 0; - for (v = 1; v < E; ++v) { - N[v] = [1]; - for (m = 1; m < E; ++m) - N[v][m] = N[v - 1][m] + N[v - 1][m - 1] - } - T = N[s - 1]; - for (v = 0, - b = 0; v < s; ++v) - b += T[v]; - for (v = 0; v < s; ++v) - T[v] /= b; - for (d = 0; d < i; ++d) - for (p = 0; p < r; ++p) { - u = a = f = l = 0; - for (v = S; v < x; ++v) - g = p + v, - y = d, - b = T[v - S], - g < 0 && (g = 0), - g >= r && (g = r - 1), - c = (y * r + g) * 4, - u += e[c] * b, - a += e[c + 1] * b, - f += e[c + 2] * b, - l += e[c + 3] * b; - c = (d * r + p) * 4, - w[c] = u, - w[c + 1] = a, - w[c + 2] = f, - w[c + 3] = l, - o && (C = (c / h * 50 >> 0) / 100, - C > k && (k = o(C))) - } - k = 0; - for (d = 0; d < i; ++d) - for (p = 0; p < r; ++p) { - u = a = f = l = 0; - for (v = S; v < x; ++v) - g = p, - y = d + v, - b = T[v - S], - y < 0 && (y = 0), - y >= i && (y = i - 1), - c = (y * r + g) * 4, - u += w[c] * b, - a += w[c + 1] * b, - f += w[c + 2] * b, - l += w[c + 3] * b; - c = (d * r + p) * 4, - n[c] = u, - n[c + 1] = a, - n[c + 2] = f, - n[c + 3] = l, - o && (C = .5 + (c / h * 50 >> 0) / 100, - C > k && (k = o(C))) - } - } - return { - invert: function(e, t, n, r, s, o) { - var u = n * r * 4, a, f = 0; - for (i = 0; i < u; i += 4) - t[i] = 255 - e[i], - t[i + 1] = 255 - e[i + 1], - t[i + 2] = 255 - e[i + 2], - t[i + 3] = e[i + 3], - o && (a = (i / u * 100 >> 0) / 100, - a > f && (f = o(a))) - }, - sepia: function(e, t, n, r, i, s) { - var o = n * r * 4, u, a = 0, f, l, c; - for (var h = 0; h < o; h += 4) - f = e[h], - l = e[h + 1], - c = e[h + 2], - t[h] = f * .393 + l * .769 + c * .189, - t[h + 1] = f * .349 + l * .686 + c * .168, - t[h + 2] = f * .272 + l * .534 + c * .131, - t[h + 3] = e[h + 3], - s && (u = (h / o * 100 >> 0) / 100, - u > a && (a = s(u))) - }, - solarize: function(e, t, n, r, s, o) { - var u = n * r * 4, a, f = 0, l, c, h; - for (i = 0; i < u; i += 4) - l = e[i], - c = e[i + 1], - h = e[i + 2], - t[i] = l > 127 ? 255 - l : l, - t[i + 1] = c > 127 ? 255 - c : c, - t[i + 2] = h > 127 ? 255 - h : h, - t[i + 3] = e[i + 3], - o && (a = (i / u * 100 >> 0) / 100, - a > f && (f = o(a))) - }, - brightness: function(n, r, i, s, o, u) { - o = e(o, { - brightness: 0, - contrast: 0 - }); - var a = t(o.contrast, -1, 1) / 2, f = 1 + t(o.brightness, -1, 1), l, c = 0, h, p, d, v = i * s * 4, m = f < 0 ? -f : f, g = f < 0 ? 0 : f; - a = .5 * Math.tan((a + 1) * Math.PI / 4), - contrastAdd = -(a - .5) * 255; - for (var y = 0; y < v; y += 4) - h = n[y], - p = n[y + 1], - d = n[y + 2], - h = (h + h * m + g) * a + contrastAdd, - p = (p + p * m + g) * a + contrastAdd, - d = (d + d * m + g) * a + contrastAdd, - r[y] = h, - r[y + 1] = p, - r[y + 2] = d, - r[y + 3] = n[y + 3], - u && (l = (y / v * 100 >> 0) / 100, - l > c && (c = u(l))) - }, - desaturate: function(e, t, n, r, i, s) { - var o = n * r * 4, u, a = 0, f; - for (var l = 0; l < o; l += 4) - f = e[l] * .3 + e[l + 1] * .59 + e[l + 2] * .11, - t[l] = f, - t[l + 1] = f, - t[l + 2] = f, - t[l + 3] = e[l + 3], - s && (u = (l / o * 100 >> 0) / 100, - u > a && (a = s(u))) - }, - lighten: function(e, n, r, i, s, o) { - var u = r * i * 4, a, f = 0, l = 1 + t(s.amount, 0, 1); - for (var c = 0; c < u; c += 4) - n[c] = e[c] * l, - n[c + 1] = e[c + 1] * l, - n[c + 2] = e[c + 2] * l, - n[c + 3] = e[c + 3], - o && (a = (c / u * 100 >> 0) / 100, - a > f && (f = o(a))) - }, - noise: function(e, n, r, i, s, o) { - var u = r * i * 4, a, f = 0, l = t(s.amount, 0, 1), c = t(s.strength, 0, 1), h = !!s.mono, p = Math.random, d, v, m, g; - for (var y = 0; y < u; y += 4) - v = e[y], - m = e[y + 1], - g = e[y + 2], - d = p(), - d < l && (h ? (d = c * (d / l * 2 - 1) * 255, - v += d, - m += d, - g += d) : (v += c * p() * 255, - m += c * p() * 255, - g += c * p() * 255)), - n[y] = v, - n[y + 1] = m, - n[y + 2] = g, - n[y + 3] = e[y + 3], - o && (a = (y / u * 100 >> 0) / 100, - a > f && (f = o(a))) - }, - flipv: function(e, t, n, r, i, s) { - var o, u, a = n * r * 4, f, l = 0, c, h; - for (h = 0; h < r; ++h) - for (c = 0; c < n; ++c) - o = (h * n + c) * 4, - u = (h * n + (n - c - 1)) * 4, - t[u] = e[o], - t[u + 1] = e[o + 1], - t[u + 2] = e[o + 2], - t[u + 3] = e[o + 3], - s && (f = (o / a * 100 >> 0) / 100, - f > l && (l = s(f))) - }, - fliph: function(e, t, n, r, i, s) { - var o, u, a = n * r * 4, f, l = 0, c, h; - for (h = 0; h < r; ++h) - for (c = 0; c < n; ++c) - o = (h * n + c) * 4, - u = ((r - h - 1) * n + c) * 4, - t[u] = e[o], - t[u + 1] = e[o + 1], - t[u + 2] = e[o + 2], - t[u + 3] = e[o + 3], - s && (f = (o / a * 100 >> 0) / 100, - f > l && (l = s(f))) - }, - blur: function(e, t, n, r, i, s) { - o(e, t, n, r, i.kernelSize, s) - }, - glow: function(e, t, n, r, i, s) { - var u = n * r * 4, a, f, l, c, h = i.amount, p = [], d, v, m = 0; - s && (d = function(e) { - return s(e * .8), - e - } - ), - o(e, p, n, r, i.kernelSize, d); - for (a = 0; a < u; a += 4) - f = e[a] + p[a] * h, - l = e[a + 1] + p[a + 1] * h, - c = e[a + 2] + p[a + 2] * h, - f > 255 && (f = 255), - l > 255 && (l = 255), - c > 255 && (c = 255), - t[a] = f, - t[a + 1] = l, - t[a + 2] = c, - t[a + 3] = e[a + 3], - s && (v = .8 + (a / u * 100 >> 0) / 100 * .2, - v > m && (m = s(v))) - }, - convolve3x3: function(e, t, r, i, s, o) { - n(e, t, r, i, s.kernel, o) - }, - convolve5x5: function(e, t, r, i, s, o) { - n(e, t, r, i, s.kernel, o) - }, - sharpen3x3: function(e, r, i, s, o, u) { - var a = -t(o.strength, 0, 1); - n(e, r, i, s, [[a, a, a], [a, 1 - a * 8, a], [a, a, a]], u) - }, - sharpen5x5: function(e, n, r, i, o, u) { - var a = -t(o.strength, 0, 1); - s(e, n, r, i, [[a, a, a, a, a], [a, a, a, a, a], [a, a, 1 - a * 24, a, a], [a, a, a, a, a], [a, a, a, a, a]], u) - }, - soften3x3: function(e, t, r, i, s, o) { - var u = 1 / 9; - n(e, t, r, i, [[u, u, u], [u, u, u], [u, u, u]], o) - }, - soften5x5: function(e, t, n, r, i, o) { - var u = .04; - s(e, t, n, r, [[u, u, u, u, u], [u, u, u, u, u], [u, u, u, u, u], [u, u, u, u, u], [u, u, u, u, u]], o) - }, - crossedges: function(e, r, i, s, o, u) { - var a = t(o.strength, 0, 1) * 5; - n(e, r, i, s, [[0, -a, 0], [-a, 0, a], [0, a, 0]], u, !1, !0) - }, - emboss: function(e, t, r, i, s, o) { - var u = s.amount, a = s.angle, f = Math.cos(-a) * u, l = Math.sin(-a) * u, c = r * i * 4, h = -f - l, p = -f, d = l - f, v = -l, m = l, g = -l + f, y = f, b = l + f, w = [], E, S = 0, x; - o && (x = function(e) { - return o(e * .5), - e - } - ), - n(e, w, r, i, [[h, v, g], [p, 0, y], [d, m, b]]); - for (var T = 0; T < c; T += 4) - t[T] = 128 + w[T], - t[T + 1] = 128 + w[T + 1], - t[T + 2] = 128 + w[T + 2], - t[T + 3] = e[T + 3], - o && (E = .5 + (T / c * 100 >> 0) / 100 * .5, - E > S && (S = o(E))) - }, - findedges: function(e, t, r, i, s, o) { - var u = r * i * 4, a, f = [], l = [], c, h, p, d, v, m, g, y = 0, b, w; - o && (b = function(e) { - return o(e * .4), - e - } - , - w = function(e) { - return o(.4 + e * .4), - e - } - ), - n(e, f, r, i, [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]), - n(e, l, r, i, [[-1, -2, -1], [0, 0, 0], [1, 2, 1]]); - for (a = 0; a < u; a += 4) - c = f[a], - h = l[a], - p = f[a + 1], - d = l[a + 1], - v = f[a + 2], - m = l[a + 2], - c < 0 && (c = -c), - h < 0 && (h = -h), - p < 0 && (p = -p), - d < 0 && (d = -d), - v < 0 && (v = -v), - m < 0 && (m = -m), - t[a] = 255 - (c + h) * .8, - t[a + 1] = 255 - (p + d) * .8, - t[a + 2] = 255 - (v + m) * .8, - t[a + 3] = e[a + 3], - o && (g = .8 + (a / u * 100 >> 0) / 100 * .2, - g > y && (y = o(g))) - }, - edgeenhance3x3: function(e, t, r, i, s, o) { - n(e, t, r, i, [[-1 / 9, -1 / 9, -1 / 9], [-1 / 9, 17 / 9, -1 / 9], [-1 / 9, -1 / 9, -1 / 9]], o) - }, - edgeenhance5x5: function(e, t, n, r, i, o) { - s(e, t, n, r, [[-0.04, -0.04, -0.04, -0.04, -0.04], [-0.04, -0.04, -0.04, -0.04, -0.04], [-0.04, -0.04, 1.96, -0.04, -0.04], [-0.04, -0.04, -0.04, -0.04, -0.04], [-0.04, -0.04, -0.04, -0.04, -0.04]], o) - }, - laplace3x3: function(e, t, r, i, s, o) { - n(e, t, r, i, [[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], o, !1, !0, !0) - }, - laplace5x5: function(e, t, n, r, i, o) { - s(e, t, n, r, [[-1, -1, -1, -1, -1], [-1, -1, -1, -1, -1], [-1, -1, 24, -1, -1], [-1, -1, -1, -1, -1], [-1, -1, -1, -1, -1]], o, !1, !0, !0) - }, - coloradjust: function(e, n, r, i, s, o) { - var u = r * i * 4, a, f, l, c, h = 0, p = t(s.r, -1, 1) * 255, d = t(s.g, -1, 1) * 255, v = t(s.b, -1, 1) * 255; - for (var m = 0; m < u; m += 4) - a = e[m] + p, - f = e[m + 1] + d, - l = e[m + 2] + v, - a < 0 && (a = 0), - f < 0 && (f = 0), - l < 0 && (l = 0), - a > 255 && (a = 255), - f > 255 && (f = 255), - l > 255 && (l = 255), - n[m] = a, - n[m + 1] = f, - n[m + 2] = l, - n[m + 3] = e[m + 3], - o && (c = (m / u * 100 >> 0) / 100, - c > h && (h = o(c))) - }, - colorfilter: function(e, n, r, i, s, o) { - var u = r * i * 4, a, f, l, c, h = !!s.luminosity, p, d = 0, v, m, g, y, b, w, E, S, x = t(s.r, 0, 1), T = t(s.g, 0, 1), N = t(s.b, 0, 1); - for (a = 0; a < u; a += 4) - f = e[a] / 255, - l = e[a + 1] / 255, - c = e[a + 2] / 255, - y = f * .3 + l * .59 + c * .11, - f = (f + f * x) / 2, - l = (l + l * T) / 2, - c = (c + c * N) / 2, - h && (v = m = f, - l > m && (m = l), - c > m && (m = c), - l < v && (v = l), - c < v && (v = c), - w = m - v, - f == m ? g = (l - c) / w % 6 : l == m ? g = (c - f) / w + 2 : g = (f - l) / w + 4, - b = g >> 0, - E = w * (g - b), - f = l = c = y - (f * .3 + l * .59 + c * .11), - b == 0 ? (f += w, - l += E) : b == 1 ? (f += w - E, - l += w) : b == 2 ? (l += w, - c += E) : b == 3 ? (l += w - E, - c += w) : b == 4 ? (f += E, - c += w) : b == 5 && (f += w, - c += w - E)), - n[a] = f * 255, - n[a + 1] = l * 255, - n[a + 2] = c * 255, - n[a + 3] = e[a + 3], - o && (p = (a / u * 100 >> 0) / 100, - p > d && (d = o(p))) - }, - hsl: function(e, n, i, s, o, u) { - var a = i * s * 4, f = t(o.hue, -1, 1), l = t(o.saturation, -1, 1), c = t(o.lightness, -1, 1), h = 1 + l * (l < 0 ? 1 : 2), p = c < 0 ? 1 + c : 1 - c, d = c < 0 ? 0 : c * 255, v, m, y, w, E, S, x, T, N, C, k, L = 0; - f = f * 6 % 6; - for (var A = 0; A < a; A += 4) { - r = e[A], - g = e[A + 1], - b = e[A + 2]; - if (f != 0 || l != 0) - v = r, - g > v && (v = g), - b > v && (v = b), - m = r, - g < m && (m = g), - b < m && (m = b), - y = v - m, - S = (m + v) / 510, - S > 0 && y > 0 && (S <= .5 ? (E = y / (v + m) * h, - E > 1 && (E = 1), - x = S * (1 + E)) : (E = y / (510 - v - m) * h, - E > 1 && (E = 1), - x = S + E - S * E), - r == v ? g == m ? w = 5 + (v - b) / y + f : w = 1 - (v - g) / y + f : g == v ? b == m ? w = 1 + (v - r) / y + f : w = 3 - (v - b) / y + f : r == m ? w = 3 + (v - g) / y + f : w = 5 - (v - r) / y + f, - w < 0 && (w += 6), - w >= 6 && (w -= 6), - T = S + S - x, - C = w >> 0, - N = (x - T) * (w - C), - C == 0 ? (r = x, - g = T + N, - b = T) : C == 1 ? (r = x - N, - g = x, - b = T) : C == 2 ? (r = T, - g = x, - b = T + N) : C == 3 ? (r = T, - g = x - N, - b = x) : C == 4 ? (r = T + N, - g = T, - b = x) : C == 5 && (r = x, - g = T, - b = x - N), - r *= 255, - g *= 255, - b *= 255); - r = r * p + d, - g = g * p + d, - b = b * p + d, - r < 0 && (r = 0), - g < 0 && (g = 0), - b < 0 && (b = 0), - r > 255 && (r = 255), - g > 255 && (g = 255), - b > 255 && (b = 255), - n[A] = r, - n[A + 1] = g, - n[A + 2] = b, - n[A + 3] = e[A + 3], - u && (k = (A / a * 100 >> 0) / 100, - k > L && (L = u(k))) - } - }, - posterize: function(e, n, r, s, o, u) { - var a = t(o.levels, 2, 256), f = 256 / a, l = 256 / (a - 1), c, h, p, d = r * s * 4, v, m = 0; - for (i = 0; i < d; i += 4) - n[i] = l * (e[i] / f >> 0), - n[i + 1] = l * (e[i + 1] / f >> 0), - n[i + 2] = l * (e[i + 2] / f >> 0), - n[i + 3] = e[i + 3], - u && (v = (i / d * 100 >> 0) / 100, - v > m && (m = u(v))) - }, - removenoise: function(e, t, n, r, i, s) { - var o, u, a, f, l, c, h, p, d, v, m, g, y, b, w, E, S, x, T, N, C, k = 0; - N = n * r * 4; - for (l = 0; l < r; ++l) { - p = l * n * 4, - d = p - n * 4, - v = p + n * 4, - l < 1 && (d = p), - l >= n - 1 && (v = p); - for (c = 0; c < n; ++c) - h = (l * n + c) * 4, - m = c * 4, - g = m - 4, - y = m + 4, - c < 1 && (g = m), - c >= n - 1 && (y = m), - b = S = e[p + g], - f = e[p + y], - f < b && (b = f), - f > S && (S = f), - f = e[d + m], - f < b && (b = f), - f > S && (S = f), - f = e[v + m], - f < b && (b = f), - f > S && (S = f), - w = e[p + g + 1], - f = e[p + y + 1], - f < w && (w = f), - f = e[d + m + 1], - f < w && (w = f), - f = e[v + m + 1], - f < w && (w = f), - E = e[p + g + 2], - f = e[p + y + 2], - f < E && (E = f), - f = e[d + m + 2], - f < E && (E = f), - f = e[v + m + 2], - f < E && (E = f), - o = e[h], - u = e[h + 1], - a = e[h + 2], - o < b && (o = b), - o > S && (o = S), - u < w && (u = w), - u > x && (u = x), - a < E && (a = E), - a > T && (a = T), - t[h] = o, - t[h + 1] = u, - t[h + 2] = a, - t[h + 3] = e[h + 3], - s && (C = (h / N * 100 >> 0) / 100, - C > k && (k = s(C))) - } - } - } -}(), -Pixastic.Worker = function() { - function t(t) { - var n = t.queue, r = t.inData, i = t.outData, s = t.width, o = t.height, u; - for (var a = 0; a < n.length; a++) { - var f = n[a].effect - , l = n[a].options; - a > 0 && (u = r, - r = i, - i = u), - Pixastic.Effects[f](r.data, i.data, s, o, l), - e.onmessage({ - data: { - event: "progress", - data: (a + 1) / n.length - } - }) - } - e.onmessage({ - data: { - event: "done", - data: i - } - }) - } - var e = this; - this.postMessage = function(e) { - setTimeout(function() { - t(e) - }, 0) - } - , - this.onmessage = function() {} -} -, -this.Handlebars = {}, -function(e) { - e.VERSION = "1.0.rc.1", - e.helpers = {}, - e.partials = {}, - e.registerHelper = function(e, t, n) { - n && (t.not = n), - this.helpers[e] = t - } - , - e.registerPartial = function(e, t) { - this.partials[e] = t - } - , - e.registerHelper("helperMissing", function(e) { - if (arguments.length === 2) - return undefined; - throw new Error("Could not find property '" + e + "'") - }); - var t = Object.prototype.toString - , n = "[object Function]"; - e.registerHelper("blockHelperMissing", function(r, i) { - var s = i.inverse || function() {} - , o = i.fn - , u = "" - , a = t.call(r); - return a === n && (r = r.call(this)), - r === !0 ? o(this) : r === !1 || r == null ? s(this) : a === "[object Array]" ? r.length > 0 ? e.helpers.each(r, i) : s(this) : o(r) - }), - e.K = function() {} - , - e.createFrame = Object.create || function(t) { - e.K.prototype = t; - var n = new e.K; - return e.K.prototype = null, - n - } - , - e.registerHelper("each", function(t, n) { - var r = n.fn, i = n.inverse, s = 0, o = "", u; - n.data && (u = e.createFrame(n.data)); - if (t && typeof t == "object") - if (t instanceof Array) - for (var a = t.length; s < a; s++) - u && (u.index = s), - o += r(t[s], { - data: u - }); - else - for (var f in t) - t.hasOwnProperty(f) && (u && (u.key = f), - o += r(t[f], { - data: u - }), - s++); - return s === 0 && (o = i(this)), - o - }), - e.registerHelper("if", function(r, i) { - var s = t.call(r); - return s === n && (r = r.call(this)), - !r || e.Utils.isEmpty(r) ? i.inverse(this) : i.fn(this) - }), - e.registerHelper("unless", function(t, n) { - var r = n.fn - , i = n.inverse; - return n.fn = i, - n.inverse = r, - e.helpers["if"].call(this, t, n) - }), - e.registerHelper("with", function(e, t) { - return t.fn(e) - }), - e.registerHelper("log", function(t) { - e.log(t) - }) -}(this.Handlebars); -var errorProps = ["description", "fileName", "lineNumber", "message", "name", "number", "stack"]; -Handlebars.Exception = function(e) { - var t = Error.prototype.constructor.apply(this, arguments); - for (var n = 0; n < errorProps.length; n++) - this[errorProps[n]] = t[errorProps[n]] -} -, -Handlebars.Exception.prototype = new Error, -Handlebars.SafeString = function(e) { - this.string = e -} -, -Handlebars.SafeString.prototype.toString = function() { - return this.string.toString() -} -, -function() { - var e = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`" - } - , t = /[&<>"'`]/g - , n = /[&<>"'`]/ - , r = function(t) { - return e[t] || "&" - }; - Handlebars.Utils = { - escapeExpression: function(e) { - return e instanceof Handlebars.SafeString ? e.toString() : e == null || e === !1 ? "" : n.test(e) ? e.replace(t, r) : e - }, - isEmpty: function(e) { - return typeof e == "undefined" ? !0 : e === null ? !0 : e === !1 ? !0 : Object.prototype.toString.call(e) === "[object Array]" && e.length === 0 ? !0 : !1 - } - } -}(), -Handlebars.VM = { - template: function(e) { - var t = { - escapeExpression: Handlebars.Utils.escapeExpression, - invokePartial: Handlebars.VM.invokePartial, - programs: [], - program: function(e, t, n) { - var r = this.programs[e]; - return n ? Handlebars.VM.program(t, n) : r ? r : (r = this.programs[e] = Handlebars.VM.program(t), - r) - }, - programWithDepth: Handlebars.VM.programWithDepth, - noop: Handlebars.VM.noop - }; - return function(n, r) { - return r = r || {}, - e.call(t, Handlebars, n, r.helpers, r.partials, r.data) - } - }, - programWithDepth: function(e, t, n) { - var r = Array.prototype.slice.call(arguments, 2); - return function(n, i) { - return i = i || {}, - e.apply(this, [n, i.data || t].concat(r)) - } - }, - program: function(e, t) { - return function(n, r) { - return r = r || {}, - e(n, r.data || t) - } - }, - noop: function() { - return "" - }, - invokePartial: function(e, t, n, r, i, s) { - var o = { - helpers: r, - partials: i, - data: s - }; - if (e === undefined) - throw new Handlebars.Exception("The partial " + t + " could not be found"); - if (e instanceof Function) - return e(n, o); - if (!Handlebars.compile) - throw new Handlebars.Exception("The partial " + t + " could not be compiled when running in runtime-only mode"); - return i[t] = Handlebars.compile(e, { - data: s !== undefined - }), - i[t](n, o) - } -}, -Handlebars.template = Handlebars.VM.template, -function() { - var e = Handlebars.template - , t = Handlebars.templates = Handlebars.templates || {}; - t.loadingOverlay = e(function(e, t, n, r, i) { - return this.compilerInfo = [2, ">= 1.0.0-rc.3"], - n = n || e.helpers, - i = i || {}, - '\n
\n' - }), - t.navigateLeft = e(function(e, t, n, r, i) { - return this.compilerInfo = [2, ">= 1.0.0-rc.3"], - n = n || e.helpers, - i = i || {}, - '\n\n' - }), - t.navigateRight = e(function(e, t, n, r, i) { - return this.compilerInfo = [2, ">= 1.0.0-rc.3"], - n = n || e.helpers, - i = i || {}, - '\n\n' - }), - t.progressbar = e(function(e, t, n, r, i) { - return this.compilerInfo = [2, ">= 1.0.0-rc.3"], - n = n || e.helpers, - i = i || {}, - '
\n
\n
\n
\n
\n' - }), - t.toolbar = e(function(e, t, n, r, i) { - return this.compilerInfo = [2, ">= 1.0.0-rc.3"], - n = n || e.helpers, - i = i || {}, - '\n
\n\n
    \n
  • \n \n
  • \n
  • \n
  • \n \n \n
  • \n
  • \n \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n \n
  • \n
\n\n
    \n
  • /
  • \n
\n\n
\n' - }) -}(); -var ComicBook = function(e) { - "use strict"; - function t(e, t) { - var n; - typeof t == "undefined" && (t = {}); - for (n in e) - if (e.hasOwnProperty(n)) { - if (n in t) - continue; - t[n] = e[n] - } - return t - } - function r(i, s, o) { - function E() { - var t = window.innerHeight + 1; - return w === !1 && (w = e(document.createElement("div")).attr("id", "cb-width-shiv").css({ - width: "100%", - position: "absolute", - top: 0, - zIndex: "-1000" - }), - e("body").append(w)), - w.height(t), - w.innerWidth() - } - function S() { - var e = x(); - e !== C && v.indexOf(e) > -1 && (C = e, - u.draw()) - } - function x() { - var e = parseInt(location.hash.substring(1), 10) - 1 || 0; - return e < 0 && (T(0), - e = 0), - e - } - function T(e) { - location.hash = e - } - function k() { - p = document.getElementById(a), - d = p.getContext("2d"), - y === !1 && (u.renderControls(), - y = !0), - window.addEventListener("keydown", u.navigation, !1), - window.addEventListener("hashchange", S, !1) - } - var u = this - , a = i; - this.srcs = s; - var f = { - displayMode: "double", - zoomMode: "fitWindow", - manga: !1, - enhance: {}, - keyboard: { - next: 78, - previous: 80, - toolbar: 84, - toggleLayout: 76 - }, - vendorPath: "vendor/", - forward_buffer: 3 - }; - this.isMobile = !1, - /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(navigator.userAgent) && (this.isMobile = !0, - document.body.classList.add("mobile"), - f.displayMode = "single", - window.addEventListener("load", function() { - setTimeout(function() { - window.scrollTo(0, 1) - }, 0) - })); - var l = t(f, o), c = s.length, h = [], p, d, v = [], m = 1, g = !1, y = !1, b = !1, w = !1, N = x(), C = N < s.length ? N : 0; - window.addEventListener("touchstart", function(t) { - var n = e(t.target); - n.attr("id") === "comic" && u.toggleToolbar(), - n.data("toggle") === "dropdown" && n.siblings(".dropdown").toggle() - }, !1), - r.prototype.renderControls = function() { - var t = {}, n; - e.each(Handlebars.templates, function(n, r) { - var i = e(r().trim()); - t[n] = i, - i.find("*").andSelf().filter("[data-action][data-trigger]").each(function() { - var t = e(this) - , n = t.data("trigger") - , r = t.data("action"); - typeof u[t.data("action")] == "function" && t.on(n, u[r]), - t.on(n, function(t) { - e(u).trigger(n, t) - }) - }), - e(p).before(i) - }), - this.controls = t, - n = this.getControl("toolbar"), - n.find(".manga-" + l.manga).show().end().find(".manga-" + !l.manga).hide().end().find(".layout").hide().end().find(".layout-" + l.displayMode).show() - } - , - r.prototype.getControl = function(e) { - if (typeof this.controls[e] != "object") - throw n.UNDEFINED_CONTROL + " " + e; - return this.controls[e] - } - , - r.prototype.showControl = function(e) { - this.getControl(e).show().addClass("open") - } - , - r.prototype.hideControl = function(e) { - this.getControl(e).removeClass("open").hide() - } - , - r.prototype.toggleControl = function(e) { - this.getControl(e).toggle().toggleClass("open") - } - , - r.prototype.toggleLayout = function() { - var e = u.getControl("toolbar") - , t = l.displayMode === "single" ? "double" : "single"; - l.displayMode = t, - e.find(".layout").hide().end().find(".layout-" + l.displayMode).show(), - u.drawPage() - } - , - r.prototype.getPage = function(e) { - if (e < 0 || e > s.length - 1) - throw n.INVALID_PAGE + " " + e; - if (typeof h[e] == "object") - return h[e]; - b = e, - this.showControl("loadingOverlay") - } - , - r.prototype.draw = function() { - k(), - e(".navigate").outerHeight(window.innerHeight), - e("#cb-loading-overlay").outerWidth(E()).height(window.innerHeight), - h.length !== c ? this.preload() : this.drawPage() - } - , - r.prototype.zoom = function(e) { - l.zoomMode = "manual", - m = e, - typeof this.getPage(C) == "object" && this.drawPage() - } - , - r.prototype.zoomIn = function() { - u.zoom(m + .1) - } - , - r.prototype.zoomOut = function() { - u.zoom(m - .1) - } - , - r.prototype.fitWidth = function() { - l.zoomMode = "fitWidth", - u.drawPage() - } - , - r.prototype.fitWindow = function() { - l.zoomMode = "fitWindow", - u.drawPage() - } - , - r.prototype.preload = function() { - function i(t) { - var o = new Image; - o.src = s[t], - o.onload = function() { - h[t] = this, - v.push(t), - e("#cb-progress-bar .progressbar-value").css("width", Math.floor(v.length / c * 100) + "%"); - var o = l.displayMode === "double" && C < s.length - 1 ? 1 : 0; - if (n === !1 && e.inArray(C + o, v) !== -1 || typeof b == "number" && e.inArray(b, v) !== -1) - typeof b == "number" && (C = b - 1, - b = !1), - u.drawPage(), - u.hideControl("loadingOverlay"), - n = !0; - r.length ? (i(r[0]), - r.splice(0, 1)) : e("#cb-status").delay(500).fadeOut() - } - } - function o(e, t) { - var n = 0 - , s = 1 - , o = e - , u = e - 1; - while (o <= t) - s > l.forward_buffer && u > -1 ? (r.push(u), - u--, - s = 0) : (r.push(o), - o++), - s++; - while (u > -1) - r.push(u), - u--; - i(r[n]) - } - var t = C - , n = !1 - , r = []; - this.showControl("loadingOverlay"), - o(t, s.length - 1) - } - , - r.prototype.pageLoaded = function(e) { - return typeof v[e - 1] != "undefined" - } - , - r.prototype.drawPage = function(t, r) { - var i; - r = typeof r != "undefined" ? r : !0, - i = r ? 0 : window.scrollY; - if (typeof t == "number" && t < s.length && t > 0) { - C = t - 1; - if (!this.pageLoaded(t)) { - this.showControl("loadingOverlay"); - return - } - } - C < 0 && (C = 0); - var o, a = 0, f = 0, c = u.getPage(C), h = !1; - l.displayMode === "double" && C < s.length - 1 && (h = u.getPage(C + 1)); - if (typeof c != "object") - throw n.INVALID_PAGE_TYPE + " " + typeof c; - var v = c.width - , y = c.height; - p.width = 0, - p.height = 0, - g = typeof h == "object" && (c.width > c.height || h.width > h.height) && l.displayMode === "double", - g && (l.displayMode = "single"), - l.displayMode === "double" && (typeof h == "object" ? v += h.width : v += v); - switch (l.zoomMode) { - case "manual": - document.body.style.overflowX = "auto", - o = l.displayMode === "double" ? m * 2 : m; - break; - case "fitWidth": - document.body.style.overflowX = "hidden", - o = E() > v ? (E() - v) / E() + 1 : E() / v, - m = o; - break; - case "fitWindow": - document.body.style.overflowX = "hidden"; - var b = E() > v ? (E() - v) / E() + 1 : E() / v - , w = window.innerHeight - , S = w > y ? (w - y) / w + 1 : w / y; - o = b > S ? S : b, - m = o; - break; - default: - throw n.INVALID_ZOOM_MODE + " " + l.zoomMode - } - var N = c.width * o - , k = c.height * o - , L = l.zoomMode === "manual" ? c.width * m : N - , A = l.zoomMode === "manual" ? c.height * m : k; - k = A, - p.width = N < E() ? E() : N, - p.height = k < window.innerHeight ? window.innerHeight : k; - if (l.zoomMode === "manual" || l.zoomMode === "fitWindow") - N < E() && (a = (E() - L) / 2, - l.displayMode === "double" && (a -= L / 2)), - k < window.innerHeight && (f = (window.innerHeight - A) / 2); - if (l.manga && l.displayMode === "double" && typeof h == "object") { - var O = c - , M = h; - c = M, - h = O - } - d.drawImage(c, a, f, L, A), - l.displayMode === "double" && typeof h == "object" && d.drawImage(h, L + a, f, L, A), - this.pixastic = new Pixastic(d,l.vendorPath + "pixastic/"), - e.each(l.enhance, function(e, t) { - u.enhance[e](t) - }); - var _ = l.displayMode === "double" && C + 2 <= s.length ? C + 1 + "-" + (C + 2) : C + 1; - this.getControl("toolbar").find("#current-page").text(_).end().find("#page-count").text(s.length), - g && (l.displayMode = "double"), - e("button.cb-fit-width").attr("disabled", l.zoomMode === "fitWidth"), - e("button.cb-fit-window").attr("disabled", l.zoomMode === "fitWindow"), - e(".navigate").show(), - C === 0 && (l.manga ? (e(".navigate-left").show(), - e(".navigate-right").hide()) : (e(".navigate-left").hide(), - e(".navigate-right").show())); - if (C === s.length - 1 || typeof h == "object" && C === s.length - 2) - l.manga ? (e(".navigate-left").hide(), - e(".navigate-right").show()) : (e(".navigate-left").show(), - e(".navigate-right").hide()); - C !== x() && e(this).trigger("navigate"), - x() !== C && T(C + 1) - } - , - r.prototype.drawNextPage = function() { - var e; - try { - e = u.getPage(C + 1) - } catch (t) {} - if (!e) - return !1; - if (C + 1 < h.length) { - C += l.displayMode === "single" || g ? 1 : 2; - try { - u.drawPage() - } catch (t) {} - } - window.scroll(0, 0) - } - , - r.prototype.drawPrevPage = function() { - var e; - try { - e = u.getPage(C - 1) - } catch (t) {} - if (!e) - return !1; - g = e.width > e.height, - C > 0 && (C -= l.displayMode === "single" || g ? 1 : 2, - u.drawPage()), - window.scroll(0, 0) - } - , - r.prototype.brightness = function() { - u.enhance.brightness({ - brightness: e(this).val() - }) - } - , - r.prototype.contrast = function() { - u.enhance.brightness({ - contrast: e(this).val() - }) - } - , - r.prototype.sharpen = function() { - u.enhance.sharpen({ - strength: e(this).val() - }) - } - , - r.prototype.desaturate = function() { - e(this).is(":checked") ? u.enhance.desaturate() : u.enhance.resaturate() - } - , - r.prototype.resetEnhancements = function() { - u.enhance.reset() - } - , - r.prototype.enhance = { - reset: function(e) { - e ? delete l.enhance[e] : l.enhance = {}, - u.drawPage(null, !1) - }, - progress: function() {}, - done: function() {}, - brightness: function(e, n) { - n !== !1 && this.reset("brightness"); - var r = t({ - brightness: 0, - contrast: 0 - }, e); - l.enhance.brightness = r, - u.pixastic.brightness({ - brightness: r.brightness, - contrast: r.contrast - }).done(this.done, this.progress) - }, - desaturate: function() { - l.enhance.desaturate = {}, - u.pixastic.desaturate().done(this.done, this.progress) - }, - resaturate: function() { - delete l.enhance.desaturate, - u.drawPage(null, !1) - }, - sharpen: function(e) { - this.desharpen(); - var n = t({ - strength: 0 - }, e); - l.enhance.sharpen = n, - u.pixastic.sharpen3x3({ - strength: n.strength - }).done(this.done, this.progress) - }, - desharpen: function() { - delete l.enhance.sharpen, - u.drawPage(null, !1) - } - }, - r.prototype.navigation = function(t) { - if (e("#cb-loading-overlay").is(":visible")) - return !1; - var r = !1; - switch (t.type) { - case "click": - r = t.currentTarget.getAttribute("data-navigate-side"); - break; - case "keydown": - t.keyCode === l.keyboard.previous && (r = "left"), - t.keyCode === l.keyboard.next && (r = "right"), - t.keyCode === l.keyboard.toolbar && u.toggleToolbar(), - t.keyCode === l.keyboard.toggleLayout && u.toggleLayout(); - break; - default: - throw n.INVALID_NAVIGATION_EVENT + " " + t.type - } - if (r) - return t.stopPropagation(), - l.manga ? (r === "left" && u.drawNextPage(), - r === "right" && u.drawPrevPage()) : (r === "left" && u.drawPrevPage(), - r === "right" && u.drawNextPage()), - !1 - } - , - r.prototype.toggleReadingMode = function() { - l.manga = !l.manga, - u.getControl("toolbar").find(".manga-" + l.manga).show().end().find(".manga-" + !l.manga).hide() - } - , - r.prototype.toggleToolbar = function() { - u.toggleControl("toolbar") - } - , - r.prototype.destroy = function() { - e.each(this.controls, function(e, t) { - t.remove() - }), - p.width = 0, - p.height = 0, - window.removeEventListener("keydown", this.navigation, !1), - window.removeEventListener("hashchange", S, !1), - T("") - } - } - var n = { - INVALID_ACTION: "invalid action", - INVALID_PAGE: "invalid page", - INVALID_PAGE_TYPE: "invalid page type", - UNDEFINED_CONTROL: "undefined control", - INVALID_ZOOM_MODE: "invalid zoom mode", - INVALID_NAVIGATION_EVENT: "invalid navigation event" - }; - return r -}(jQuery); - diff --git a/reader/vendor/cbrjs/fonts.org/license.txt b/reader/vendor/cbrjs/fonts.org/license.txt deleted file mode 100644 index a2dc52a..0000000 --- a/reader/vendor/cbrjs/fonts.org/license.txt +++ /dev/null @@ -1,11 +0,0 @@ -Icon Set: IcoMoon - Free -- http://keyamoon.com/icomoon/ -License: CC BY 3.0 -- http://creativecommons.org/licenses/by/3.0/Set: Font Awesome -- http://fortawesome.github.com/Font-Awesome/ -License: CC BY 3.0 -- http://creativecommons.org/licenses/by/3.0/ - - -Icon Set: IcoMoon - Free -- http://keyamoon.com/icomoon/ -License: CC BY 3.0 -- http://creativecommons.org/licenses/by/3.0/ - - -Icon Set: Iconic -- http://somerandomdude.com/work/iconic/ -License: CC BY-SA 3.0 -- http://creativecommons.org/licenses/by-sa/3.0/us/ \ No newline at end of file diff --git a/reader/vendor/cbrjs/fonts.org/toolbar.dev.svg b/reader/vendor/cbrjs/fonts.org/toolbar.dev.svg deleted file mode 100644 index 20962b3..0000000 --- a/reader/vendor/cbrjs/fonts.org/toolbar.dev.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - -This is a custom SVG font generated by IcoMoon. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/reader/vendor/cbrjs/fonts.org/toolbar.eot b/reader/vendor/cbrjs/fonts.org/toolbar.eot deleted file mode 100644 index be978c4..0000000 Binary files a/reader/vendor/cbrjs/fonts.org/toolbar.eot and /dev/null differ diff --git a/reader/vendor/cbrjs/fonts.org/toolbar.svg b/reader/vendor/cbrjs/fonts.org/toolbar.svg deleted file mode 100644 index 9fafa5c..0000000 --- a/reader/vendor/cbrjs/fonts.org/toolbar.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - -This is a custom SVG font generated by IcoMoon. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/reader/vendor/cbrjs/fonts.org/toolbar.ttf b/reader/vendor/cbrjs/fonts.org/toolbar.ttf deleted file mode 100644 index 6bf7291..0000000 Binary files a/reader/vendor/cbrjs/fonts.org/toolbar.ttf and /dev/null differ diff --git a/reader/vendor/cbrjs/fonts.org/toolbar.woff b/reader/vendor/cbrjs/fonts.org/toolbar.woff deleted file mode 100644 index 2722452..0000000 Binary files a/reader/vendor/cbrjs/fonts.org/toolbar.woff and /dev/null differ diff --git a/reader/vendor/cbrjs/js/cbr.js.OK b/reader/vendor/cbrjs/js/cbr.js.OK deleted file mode 100644 index cb0c8ed..0000000 --- a/reader/vendor/cbrjs/js/cbr.js.OK +++ /dev/null @@ -1,1263 +0,0 @@ -var CBRJS = {}; -CBRJS.VERSION = "0.0.1"; - -CBRJS.Render = {}; -CBRJS.reader = {}; - -CBRJS.Reader = function(bookPath, _options) { - - var $progressbar = $('.bar'); - - function extractImages(url, opts) { - - var images = []; - var xhr = new XMLHttpRequest(); - var re_file_ext = new RegExp(/\.([a-z]+)$/); - var filename = url.split('/').pop(); - var archive_class = ({ cbz: 'Unzipper', cbr: 'Unrarrer' })[filename.toLowerCase().match(re_file_ext)[1]]; - var options = $.extend({ - start: function () {}, - extract: function (page_url) {}, - progress: function (percent_complete) {}, - finish: function (images) {}, - }, opts); - - if (!archive_class) { - alert('invalid file type, only cbz and cbr are supported.'); - return false; - } - - xhr.responseType = "arraybuffer"; - - xhr.open('GET',url, true); - - options.start(filename); - console.log("filename: " + filename); - - xhr.onload = function () { - if ((this.status === 200) && this.response) { - var done = false; - var ua = new bitjs.archive[archive_class](this.response, 'vendor/bitjs/'); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.EXTRACT, function (e) { - - var mimetype, blob, url; - var file_extension = e.unarchivedFile.filename.toLowerCase().match(re_file_ext)[1]; - - switch (file_extension) { - case 'jpg': - case 'jpeg': - mimetype = 'image/jpeg'; - break; - case 'png': - mimetype = 'image/png'; - break; - case 'gif': - mimetype = 'image/gif'; - break; - default: - return false; - } - - blob = new Blob([e.unarchivedFile.fileData], { type: mimetype }); - url = window.URL.createObjectURL(blob); - - images.push(url); - - options.extract(url, blob); - console.log(url, file_extension); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.PROGRESS, function (e) { - options.progress(Math.floor(e.currentBytesUnarchived / e.totalUncompressedBytesInArchive * 100)); - }); - - ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.FINISH, function (e) { - options.finish(images); - }); - } - - ua.start(); - }; - - xhr.send(); - } - - function openComicArchive(url) { - - console.log("openComicArchive " + url); - - var title; - - extractImages(url, { - start: function (filename) { - this.filename = filename; - $('#filename').text(filename); - $('#progressbar').show(); - }, - extract: function (url, blob) { - // $('body').append($('').attr('src', url).css('width', '10px')); - console.log(url, Math.floor(blob.size / 1024)); - }, - progress: function (percent_complete) { - $progressbar.css('width', percent_complete + '%'); - }, - finish: function (pages) { - - var name = this.filename.replace(/\.[a-z]+$/, ''); - var id = encodeURIComponent(name.toLowerCase()); - var book = new ComicBook('cbreader', pages, {vendorPath: 'vendor/'}); - - document.title = name; - - $('#progressbar').hide(); - $('#cbreader').show(); - - book.draw(); - - $(window).on('resize', function () { - book.draw(); - }); - } - }); - } - - openComicArchive(bookPath); - - return this; -}; - -var ComicBook = (function($) { - - 'use strict'; - - /** - * Merge two arrays. Any properties in b will replace the same properties in - * a. New properties from b will be added to a. - * - * @param a {Object} - * @param b {Object} - */ - function merge(a, b) { - - var prop; - - if (typeof b === 'undefined') { - b = {}; - } - - for (prop in a) { - if (a.hasOwnProperty(prop)) { - if (prop in b) { - continue; - } - b[prop] = a[prop]; - } - } - - return b; - } - - /** - * Exception class. Always throw an instance of this when throwing exceptions. - * - * @param {String} type - * @param {Object} object - * @returns {ComicBookException} - */ - var ComicBookException = { - INVALID_ACTION: 'invalid action', - INVALID_PAGE: 'invalid page', - INVALID_PAGE_TYPE: 'invalid page type', - UNDEFINED_CONTROL: 'undefined control', - INVALID_ZOOM_MODE: 'invalid zoom mode', - INVALID_NAVIGATION_EVENT: 'invalid navigation event' - }; - - function ComicBook(id, srcs, opts) { - - var self = this; - var canvas_id = id; // canvas element id - this.srcs = srcs; // array of image srcs for pages - - var defaults = { - displayMode: 'double', // single / double - zoomMode: 'fitWindow', // manual / fitWidth / fitWindow - manga: false, // true / false - enhance: {}, - keyboard: { - next: 78, - previous: 80, - toolbar: 84, - toggleLayout: 76 - }, - libPath: '/lib/', - forward_buffer: 3 - }; - - this.isMobile = false; - - // mobile enhancements - if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(navigator.userAgent)) { - this.isMobile = true; - document.body.classList.add('mobile'); - defaults.displayMode = 'single'; - - window.addEventListener('load', function() { - setTimeout(function() { - window.scrollTo(0, 1); - }, 0); - }); - } - - var options = merge(defaults, opts); // options array for internal use - - var no_pages = srcs.length; - var pages = []; // array of preloaded Image objects - var canvas; // the HTML5 canvas object - var context; // the 2d drawing context - var loaded = []; // the images that have been loaded so far - var scale = 1; // page zoom scale, 1 = 100% - var is_double_page_spread = false; - var controlsRendered = false; // have the user controls been inserted into the dom yet? - var page_requested = false; // used to request non preloaded pages - var shiv = false; - - /** - * Gets the window.innerWidth - scrollbars - */ - function windowWidth() { - - var height = window.innerHeight + 1; - - if (shiv === false) { - shiv = $(document.createElement('div')) - .attr('id', 'cb-width-shiv') - .css({ - width: '100%', - position: 'absolute', - top: 0, - zIndex: '-1000' - }); - - $('body').append(shiv); - } - - shiv.height(height); - - return shiv.innerWidth(); - } - - /** - * enables the back button - */ - function checkHash() { - - var hash = getHash(); - - if (hash !== pointer && loaded.indexOf(hash) > -1) { - pointer = hash; - self.draw(); - } - } - - function getHash() { - var hash = parseInt(location.hash.substring(1), 10) - 1 || 0; - if (hash < 0) { - setHash(0); - hash = 0; - } - return hash; - } - - function setHash(pageNo) { - location.hash = pageNo; - } - - // page hash on first load - var hash = getHash(); - - // the current page, can pass a default as a url hash - var pointer = (hash < srcs.length) ? hash : 0; - - /** - * Setup the canvas element for use throughout the class. - * - * @see #ComicBook.prototype.draw - * @see #ComicBook.prototype.enhance - */ - function init() { - - // setup canvas - canvas = document.getElementById(canvas_id); - context = canvas.getContext('2d'); - - // render user controls - if (controlsRendered === false) { - self.renderControls(); - controlsRendered = true; - } - - // add page controls - window.addEventListener('keydown', self.navigation, false); - window.addEventListener('hashchange', checkHash, false); - } - - window.addEventListener('touchstart', function(e) { - var $el = $(e.target); - if ($el.attr('id') === 'comic') { - self.toggleToolbar(); - } - if ($el.data('toggle') === 'dropdown') { - $el.siblings('.dropdown').toggle(); - } - }, false); - - /** - * Render Handlebars templates. Templates with data-trigger & data-action will - * have the specified events bound. - */ - ComicBook.prototype.renderControls = function() { - - var controls = {}, - $toolbar; - - $.each(Handlebars.templates, function(name, template) { - - var $template = $(template().trim()); - controls[name] = $template; - - // add event listeners to controls that specify callbacks - $template.find('*').andSelf().filter('[data-action][data-trigger]').each(function() { - - var $this = $(this); - var trigger = $this.data('trigger'); - var action = $this.data('action'); - - // trigger a direct method if exists - if (typeof self[$this.data('action')] === 'function') { - $this.on(trigger, self[action]); - } - - // throw an event to be caught outside if the app code - $this.on(trigger, function(e) { - $(self).trigger(trigger, e); - }); - }); - - $(canvas).before($template); - }); - - this.controls = controls; - - $toolbar = this.getControl('toolbar'); - $toolbar - .find('.manga-' + options.manga).show().end() - .find('.manga-' + !options.manga).hide().end() - .find('.layout').hide().end().find('.layout-' + options.displayMode).show(); - - }; - - ComicBook.prototype.getControl = function(control) { - if (typeof this.controls[control] !== 'object') { - throw ComicBookException.UNDEFINED_CONTROL + ' ' + control; - } - return this.controls[control]; - }; - - ComicBook.prototype.showControl = function(control) { - this.getControl(control).show().addClass('open'); - }; - - ComicBook.prototype.hideControl = function(control) { - this.getControl(control).removeClass('open').hide(); - }; - - ComicBook.prototype.toggleControl = function(control) { - this.getControl(control).toggle().toggleClass('open'); - }; - - ComicBook.prototype.toggleLayout = function() { - - var $toolbar = self.getControl('toolbar'); - var displayMode = (options.displayMode === 'single') ? 'double' : 'single'; - - options.displayMode = displayMode; - - $toolbar.find('.layout').hide().end().find('.layout-' + options.displayMode).show(); - - self.drawPage(); - }; - - /** - * Get the image for a given page. - * - * @return Image - */ - ComicBook.prototype.getPage = function(i) { - - if (i < 0 || i > srcs.length - 1) { - throw ComicBookException.INVALID_PAGE + ' ' + i; - } - - if (typeof pages[i] === 'object') { - return pages[i]; - } else { - page_requested = i; - this.showControl('loadingOverlay'); - } - }; - - /** - * @see #preload - */ - ComicBook.prototype.draw = function() { - - init(); - - // resize navigation controls - $('.navigate').outerHeight(window.innerHeight); - $('#cb-loading-overlay').outerWidth(windowWidth()).height(window.innerHeight); - - // preload images if needed - if (pages.length !== no_pages) { - this.preload(); - } else { - this.drawPage(); - } - }; - - /** - * Zoom the canvas - * - * @param new_scale {Number} Scale the canvas to this ratio - */ - ComicBook.prototype.zoom = function(new_scale) { - options.zoomMode = 'manual'; - scale = new_scale; - if (typeof this.getPage(pointer) === 'object') { - this.drawPage(); - } - }; - - ComicBook.prototype.zoomIn = function() { - self.zoom(scale + 0.1); - }; - - ComicBook.prototype.zoomOut = function() { - self.zoom(scale - 0.1); - }; - - ComicBook.prototype.fitWidth = function() { - options.zoomMode = 'fitWidth'; - self.drawPage(); - }; - - ComicBook.prototype.fitWindow = function() { - options.zoomMode = 'fitWindow'; - self.drawPage(); - }; - - /** - * Preload all images, draw the page only after a given number have been loaded. - * - * @see #drawPage - */ - ComicBook.prototype.preload = function() { - - var i = pointer; // the current page counter for this method - var rendered = false; - var queue = []; - - this.showControl('loadingOverlay'); - - function loadImage(i) { - - var page = new Image(); - page.src = srcs[i]; - - page.onload = function() { - - pages[i] = this; - loaded.push(i); - - $('#cb-progress-bar .progressbar-value').css('width', Math.floor((loaded.length / no_pages) * 100) + '%'); - - // double page mode needs an extra page added - var buffer = (options.displayMode === 'double' && pointer < srcs.length - 1) ? 1 : 0; - - // start rendering the comic when the requested page is ready - if ((rendered === false && ($.inArray(pointer + buffer, loaded) !== -1) || - (typeof page_requested === 'number' && $.inArray(page_requested, loaded) !== -1))) { - // if the user is waiting for a page to be loaded, render that one instead of the default pointer - if (typeof page_requested === 'number') { - pointer = page_requested - 1; - page_requested = false; - } - - self.drawPage(); - self.hideControl('loadingOverlay'); - rendered = true; - } - - if (queue.length) { - loadImage(queue[0]); - queue.splice(0, 1); - } else { - $('#cb-status').delay(500).fadeOut(); - } - }; - } - - // loads pages in both directions so you don't have to wait for all pages - // to be loaded before you can scroll backwards - function preload(start, stop) { - - var j = 0; - var count = 1; - var forward = start; - var backward = start - 1; - - while (forward <= stop) { - - if (count > options.forward_buffer && backward > -1) { - queue.push(backward); - backward--; - count = 0; - } else { - queue.push(forward); - forward++; - } - count++; - } - - while (backward > -1) { - queue.push(backward); - backward--; - } - - loadImage(queue[j]); - } - - preload(i, srcs.length - 1); - }; - - ComicBook.prototype.pageLoaded = function(page_no) { - return (typeof loaded[page_no - 1] !== 'undefined'); - }; - - /** - * Draw the current page in the canvas - */ - ComicBook.prototype.drawPage = function(page_no, reset_scroll) { - - var scrollY; - - reset_scroll = (typeof reset_scroll !== 'undefined') ? reset_scroll : true; - scrollY = reset_scroll ? 0 : window.scrollY; - - // if a specific page is given try to render it, if not bail and wait for preload() to render it - if (typeof page_no === 'number' && page_no < srcs.length && page_no > 0) { - pointer = page_no - 1; - if (!this.pageLoaded(page_no)) { - this.showControl('loadingOverlay'); - return; - } - } - - if (pointer < 0) { - pointer = 0; - } - - var zoom_scale; - var offsetW = 0, - offsetH = 0; - - var page = self.getPage(pointer); - var page2 = false; - - if (options.displayMode === 'double' && pointer < srcs.length - 1) { - page2 = self.getPage(pointer + 1); - } - - if (typeof page !== 'object') { - throw ComicBookException.INVALID_PAGE_TYPE + ' ' + typeof page; - } - - var width = page.width, - height = page.height; - - // reset the canvas to stop duplicate pages showing - canvas.width = 0; - canvas.height = 0; - - // show double page spreads on a single page - is_double_page_spread = ( - typeof page2 === 'object' && - (page.width > page.height || page2.width > page2.height) && - options.displayMode === 'double' - ); - if (is_double_page_spread) { - options.displayMode = 'single'; - } - - if (options.displayMode === 'double') { - - // for double page spreads, factor in the width of both pages - if (typeof page2 === 'object') { - width += page2.width; - } - - // if this is the last page and there is no page2, still keep the canvas wide - else { - width += width; - } - } - - // update the page scale if a non manual mode has been chosen - switch (options.zoomMode) { - - case 'manual': - document.body.style.overflowX = 'auto'; - zoom_scale = (options.displayMode === 'double') ? scale * 2 : scale; - break; - - case 'fitWidth': - document.body.style.overflowX = 'hidden'; - - // scale up if the window is wider than the page, scale down if the window - // is narrower than the page - zoom_scale = (windowWidth() > width) ? ((windowWidth() - width) / windowWidth()) + 1 : windowWidth() / width; - - // update the interal scale var so switching zoomModes while zooming will be smooth - scale = zoom_scale; - break; - - case 'fitWindow': - document.body.style.overflowX = 'hidden'; - - var width_scale = (windowWidth() > width) ? - ((windowWidth() - width) / windowWidth()) + 1 // scale up if the window is wider than the page - : - windowWidth() / width; // scale down if the window is narrower than the page - var windowHeight = window.innerHeight; - var height_scale = (windowHeight > height) ? - ((windowHeight - height) / windowHeight) + 1 // scale up if the window is wider than the page - : - windowHeight / height; // scale down if the window is narrower than the page - - zoom_scale = (width_scale > height_scale) ? height_scale : width_scale; - scale = zoom_scale; - break; - - default: - throw ComicBookException.INVALID_ZOOM_MODE + ' ' + options.zoomMode; - } - - var canvas_width = page.width * zoom_scale; - var canvas_height = page.height * zoom_scale; - - var page_width = (options.zoomMode === 'manual') ? page.width * scale : canvas_width; - var page_height = (options.zoomMode === 'manual') ? page.height * scale : canvas_height; - - canvas_height = page_height; - - // make sure the canvas is always at least full screen, even if the page is more narrow than the screen - canvas.width = (canvas_width < windowWidth()) ? windowWidth() : canvas_width; - canvas.height = (canvas_height < window.innerHeight) ? window.innerHeight : canvas_height; - - // always keep pages centered - if (options.zoomMode === 'manual' || options.zoomMode === 'fitWindow') { - - // work out a horizontal position - if (canvas_width < windowWidth()) { - offsetW = (windowWidth() - page_width) / 2; - if (options.displayMode === 'double') { - offsetW = offsetW - page_width / 2; - } - } - - // work out a vertical position - if (canvas_height < window.innerHeight) { - offsetH = (window.innerHeight - page_height) / 2; - } - } - - // in manga double page mode reverse the page(s) - if (options.manga && options.displayMode === 'double' && typeof page2 === 'object') { - var tmpPage = page; - var tmpPage2 = page2; - page = tmpPage2; - page2 = tmpPage; - } - - // draw the page(s) - context.drawImage(page, offsetW, offsetH, page_width, page_height); - if (options.displayMode === 'double' && typeof page2 === 'object') { - context.drawImage(page2, page_width + offsetW, offsetH, page_width, page_height); - } - - this.pixastic = new Pixastic(context, options.libPath + 'pixastic/'); - - // apply any image enhancements previously defined - $.each(options.enhance, function(action, options) { - self.enhance[action](options); - }); - - var current_page = - (options.displayMode === 'double' && - pointer + 2 <= srcs.length) ? (pointer + 1) + '-' + (pointer + 2) : pointer + 1; - - this.getControl('toolbar') - .find('#current-page').text(current_page) - .end() - .find('#page-count').text(srcs.length); - - // revert page mode back to double if it was auto switched for a double page spread - if (is_double_page_spread) { - options.displayMode = 'double'; - } - - // disable the fit width button if needed - $('button.cb-fit-width').attr('disabled', (options.zoomMode === 'fitWidth')); - $('button.cb-fit-window').attr('disabled', (options.zoomMode === 'fitWindow')); - - // disable prev/next buttons if not needed - $('.navigate').show(); - if (pointer === 0) { - if (options.manga) { - $('.navigate-left').show(); - $('.navigate-right').hide(); - } else { - $('.navigate-left').hide(); - $('.navigate-right').show(); - } - } - - if (pointer === srcs.length - 1 || (typeof page2 === 'object' && pointer === srcs.length - 2)) { - if (options.manga) { - $('.navigate-left').hide(); - $('.navigate-right').show(); - } else { - $('.navigate-left').show(); - $('.navigate-right').hide(); - } - } - - if (pointer !== getHash()) { - $(this).trigger('navigate'); - } - - // update hash location - if (getHash() !== pointer) { - setHash(pointer + 1); - } - }; - - /** - * Increment the counter and draw the page in the canvas - * - * @see #drawPage - */ - ComicBook.prototype.drawNextPage = function() { - - var page; - - try { - page = self.getPage(pointer + 1); - } catch (e) {} - - if (!page) { - return false; - } - - if (pointer + 1 < pages.length) { - pointer += (options.displayMode === 'single' || is_double_page_spread) ? 1 : 2; - try { - self.drawPage(); - } catch (e) {} - } - - // make sure the top of the page is in view - window.scroll(0, 0); - }; - - /** - * Decrement the counter and draw the page in the canvas - * - * @see #drawPage - */ - ComicBook.prototype.drawPrevPage = function() { - - var page; - - try { - page = self.getPage(pointer - 1); - } catch (e) {} - - if (!page) { - return false; - } - - is_double_page_spread = (page.width > page.height); // need to run double page check again here as we are going backwards - - if (pointer > 0) { - pointer -= (options.displayMode === 'single' || is_double_page_spread) ? 1 : 2; - self.drawPage(); - } - - // make sure the top of the page is in view - window.scroll(0, 0); - }; - - ComicBook.prototype.brightness = function() { - self.enhance.brightness({ - brightness: $(this).val() - }); - }; - - ComicBook.prototype.contrast = function() { - self.enhance.brightness({ - contrast: $(this).val() - }); - }; - - ComicBook.prototype.sharpen = function() { - self.enhance.sharpen({ - strength: $(this).val() - }); - }; - - ComicBook.prototype.desaturate = function() { - if ($(this).is(':checked')) { - self.enhance.desaturate(); - } else { - self.enhance.resaturate(); - } - }; - - ComicBook.prototype.resetEnhancements = function() { - self.enhance.reset(); - }; - - /** - * Apply image enhancements to the canvas. - * - * Powered by the awesome Pixastic: http://www.pixastic.com/ - * - * TODO: reset & apply all image enhancements each time before applying new one - * TODO: abstract this into an 'Enhance' object, separate from ComicBook? - */ - ComicBook.prototype.enhance = { - - /** - * Reset enhancements. - * This can reset a specific enhancement if the method name is passed, or - * it will reset all. - * - * @param method {string} the specific enhancement to reset - */ - reset: function(method) { - if (!method) { - options.enhance = {}; - } else { - delete options.enhance[method]; - } - self.drawPage(null, false); - }, - - /** - * Pixastic progress callback - * @param {float} progress - */ - // progress: function (progress) { - progress: function() { - // console.info(Math.floor(progress * 100)); - }, - - /** - * Pixastic on complete callback - */ - done: function() { - - }, - - /** - * Adjust brightness / contrast - * - * params - * brightness (int) -150 to 150 - * contrast: (float) -1 to infinity - * - * @param {Object} params Brightness & contrast levels - * @param {Boolean} reset Reset before applying more enhancements? - */ - brightness: function(params, reset) { - - if (reset !== false) { - this.reset('brightness'); - } - - // merge user options with defaults - var opts = merge({ - brightness: 0, - contrast: 0 - }, params); - - // remember options for later - options.enhance.brightness = opts; - - // run the enhancement - self.pixastic.brightness({ - brightness: opts.brightness, - contrast: opts.contrast - }).done(this.done, this.progress); - }, - - /** - * Force black and white - */ - desaturate: function() { - options.enhance.desaturate = {}; - self.pixastic.desaturate().done(this.done, this.progress); - }, - - /** - * Undo desaturate - */ - resaturate: function() { - delete options.enhance.desaturate; - self.drawPage(null, false); - }, - - /** - * Sharpen - * - * options: - * strength: number (-1 to infinity) - * - * @param {Object} options - */ - sharpen: function(params) { - - this.desharpen(); - - var opts = merge({ - strength: 0 - }, params); - - options.enhance.sharpen = opts; - - self.pixastic.sharpen3x3({ - strength: opts.strength - }).done(this.done, this.progress); - }, - - desharpen: function() { - delete options.enhance.sharpen; - self.drawPage(null, false); - } - }; - - ComicBook.prototype.navigation = function(e) { - - // disable navigation when the overlay is showing - if ($('#cb-loading-overlay').is(':visible')) { - return false; - } - - var side = false; - - switch (e.type) { - - case 'click': - side = e.currentTarget.getAttribute('data-navigate-side'); - break; - - case 'keydown': - - // navigation - if (e.keyCode === options.keyboard.previous) { - side = 'left'; - } - if (e.keyCode === options.keyboard.next) { - side = 'right'; - } - - // display controls - if (e.keyCode === options.keyboard.toolbar) { - self.toggleToolbar(); - } - if (e.keyCode === options.keyboard.toggleLayout) { - self.toggleLayout(); - } - break; - - default: - throw ComicBookException.INVALID_NAVIGATION_EVENT + ' ' + e.type; - } - - if (side) { - - e.stopPropagation(); - - // western style (left to right) - if (!options.manga) { - if (side === 'left') { - self.drawPrevPage(); - } - if (side === 'right') { - self.drawNextPage(); - } - } - // manga style (right to left) - else { - if (side === 'left') { - self.drawNextPage(); - } - if (side === 'right') { - self.drawPrevPage(); - } - } - - return false; - } - }; - - ComicBook.prototype.toggleReadingMode = function() { - options.manga = !options.manga; - self.getControl('toolbar') - .find('.manga-' + options.manga).show().end() - .find('.manga-' + !options.manga).hide(); - }; - - ComicBook.prototype.toggleToolbar = function() { - self.toggleControl('toolbar'); - }; - - ComicBook.prototype.destroy = function() { - - $.each(this.controls, function(name, $control) { - $control.remove(); - }); - - canvas.width = 0; - canvas.height = 0; - - window.removeEventListener('keydown', this.navigation, false); - window.removeEventListener('hashchange', checkHash, false); - - setHash(''); - - // $(this).trigger('destroy'); - }; - - } - - return ComicBook; - -})(jQuery); - -// lib/handlebars/base.js -/*jshint eqnull:true*/ -this.Handlebars = {}, - function(e) { - e.VERSION = "1.0.rc.1", e.helpers = {}, e.partials = {}, e.registerHelper = function(e, t, n) { - n && (t.not = n), this.helpers[e] = t - }, e.registerPartial = function(e, t) { - this.partials[e] = t - }, e.registerHelper("helperMissing", function(e) { - if (arguments.length === 2) return undefined; - throw new Error("Could not find property '" + e + "'") - }); - var t = Object.prototype.toString, - n = "[object Function]"; - e.registerHelper("blockHelperMissing", function(r, i) { - var s = i.inverse || function() {}, - o = i.fn, - u = "", - a = t.call(r); - return a === n && (r = r.call(this)), r === !0 ? o(this) : r === !1 || r == null ? s(this) : a === "[object Array]" ? r.length > 0 ? e.helpers.each(r, i) : s(this) : o(r) - }), e.K = function() {}, e.createFrame = Object.create || function(t) { - e.K.prototype = t; - var n = new e.K; - return e.K.prototype = null, n - }, e.registerHelper("each", function(t, n) { - var r = n.fn, - i = n.inverse, - s = 0, - o = "", - u; - n.data && (u = e.createFrame(n.data)); - if (t && typeof t == "object") - if (t instanceof Array) - for (var a = t.length; s < a; s++) u && (u.index = s), o += r(t[s], { - data: u - }); - else - for (var f in t) t.hasOwnProperty(f) && (u && (u.key = f), o += r(t[f], { - data: u - }), s++); - return s === 0 && (o = i(this)), o - }), e.registerHelper("if", function(r, i) { - var s = t.call(r); - return s === n && (r = r.call(this)), !r || e.Utils.isEmpty(r) ? i.inverse(this) : i.fn(this) - }), e.registerHelper("unless", function(t, n) { - var r = n.fn, - i = n.inverse; - return n.fn = i, n.inverse = r, e.helpers["if"].call(this, t, n) - }), e.registerHelper("with", function(e, t) { - return t.fn(e) - }), e.registerHelper("log", function(t) { - e.log(t) - }) - }(this.Handlebars); -var errorProps = ["description", "fileName", "lineNumber", "message", "name", "number", "stack"]; -Handlebars.Exception = function(e) { - var t = Error.prototype.constructor.apply(this, arguments); - for (var n = 0; n < errorProps.length; n++) this[errorProps[n]] = t[errorProps[n]] - }, Handlebars.Exception.prototype = new Error, Handlebars.SafeString = function(e) { - this.string = e - }, Handlebars.SafeString.prototype.toString = function() { - return this.string.toString() - }, - function() { - var e = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`" - }, - t = /[&<>"'`]/g, - n = /[&<>"'`]/, - r = function(t) { - return e[t] || "&" - }; - Handlebars.Utils = { - escapeExpression: function(e) { - return e instanceof Handlebars.SafeString ? e.toString() : e == null || e === !1 ? "" : n.test(e) ? e.replace(t, r) : e - }, - isEmpty: function(e) { - return typeof e == "undefined" ? !0 : e === null ? !0 : e === !1 ? !0 : Object.prototype.toString.call(e) === "[object Array]" && e.length === 0 ? !0 : !1 - } - } - }(), Handlebars.VM = { - template: function(e) { - var t = { - escapeExpression: Handlebars.Utils.escapeExpression, - invokePartial: Handlebars.VM.invokePartial, - programs: [], - program: function(e, t, n) { - var r = this.programs[e]; - return n ? Handlebars.VM.program(t, n) : r ? r : (r = this.programs[e] = Handlebars.VM.program(t), r) - }, - programWithDepth: Handlebars.VM.programWithDepth, - noop: Handlebars.VM.noop - }; - return function(n, r) { - return r = r || {}, e.call(t, Handlebars, n, r.helpers, r.partials, r.data) - } - }, - programWithDepth: function(e, t, n) { - var r = Array.prototype.slice.call(arguments, 2); - return function(n, i) { - return i = i || {}, e.apply(this, [n, i.data || t].concat(r)) - } - }, - program: function(e, t) { - return function(n, r) { - return r = r || {}, e(n, r.data || t) - } - }, - noop: function() { - return "" - }, - invokePartial: function(e, t, n, r, i, s) { - var o = { - helpers: r, - partials: i, - data: s - }; - if (e === undefined) throw new Handlebars.Exception("The partial " + t + " could not be found"); - if (e instanceof Function) return e(n, o); - if (!Handlebars.compile) throw new Handlebars.Exception("The partial " + t + " could not be compiled when running in runtime-only mode"); - return i[t] = Handlebars.compile(e, { - data: s !== undefined - }), i[t](n, o) - } - }, Handlebars.template = Handlebars.VM.template; - - - -(function() { - var template = Handlebars.template, - templates = Handlebars.templates = Handlebars.templates || {}; - templates['loadingOverlay'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n"; - }); - templates['navigateLeft'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n \n
\n"; - }); - templates['navigateRight'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n \n
\n"; - }); - templates['progressbar'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "
\n
\n
\n
\n
\n"; - }); - templates['toolbar'] = template(function(Handlebars, depth0, helpers, partials, data) { - this.compilerInfo = [2, '>= 1.0.0-rc.3']; - helpers = helpers || Handlebars.helpers; - data = data || {}; - - - - return "\n
\n\n
    \n
  • \n \n
  • \n
  • \n
  • \n \n
    \n
    \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n
    \n \n \n
    \n
    \n \n
    \n
    \n
    \n
  • \n
  • \n \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n
  • \n
  • \n \n \n
  • \n
\n\n
    \n
  • /
  • \n
\n\n
\n"; - }); -})(); /* exported ComicBook */ - -(function(root, $) { - - var previousReader = root.cbReader || {}; - - var cbReader = root.cbReader = function(path, options) { - return new CBRJS.Reader(path, options); - }; - - //exports to multiple environments - if (typeof define === 'function' && define.amd) { - //AMD - define(function(){ return Reader; }); - } else if (typeof module != "undefined" && module.exports) { - //Node - module.exports = cbReader; - } - -})(window, jQuery); - -