[
  {
    "path": "changelog.txt",
    "content": "TURN.JS\n------------------------------------------------------\nGithub: https://github.com/blasten/turn.js\nReference: https://github.com/blasten/turn.js/wiki/Reference\nWebsite: www.turnjs.com \n------------------------------------------------------\nRelease 3 - 2012/03/01\n------------------------------------------------------\n\n- Added 'range'\n- Added 'addPage'\n- Added 'removePage'\n- Added 'hasPage'\n- Added 'pages'\n- Added 'display'\n- Added 'when' to the initial configuration\n- Added 'pages' to the initial configuration\n- Added 'inclination' to the initial configuration\n- Added 'first' event\n- Added 'last' event\n- Added gradients for non-webkit browsers\n\n------------------------------------------------------\nRelease 2 - 2012/02/15\n------------------------------------------------------\n\n- Added 'size'.\n- Bug in Chrome 17-18 Beta about losing background-image was fixed.\n\n------------------------------------------------------\nRelease 1 - 2012/02/05\n------------------------------------------------------\n- First alpha release "
  },
  {
    "path": "demos/bible/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n<script type=\"text/javascript\" src=\"http://code.jquery.com/jquery-1.7.1.min.js\"></script>\n<script type=\"text/javascript\" src=\"../../turn.min.js\"></script>\n\n<style type=\"text/css\">\nbody{\n\tbackground:#ccc;\n}\n#book{\n\twidth:800px;\n\theight:500px;\n}\n\n#book .turn-page{\n\tbackground-color:white;\n}\n\n#book .cover{\n\tbackground:#333;\n}\n\n#book .cover h1{\n\tcolor:white;\n\ttext-align:center;\n\tfont-size:50px;\n\tline-height:500px;\n\tmargin:0px;\n}\n\n#book .loader{\n\tbackground-image:url(loader.gif);\n\twidth:24px;\n\theight:24px;\n\tdisplay:block;\n\tposition:absolute;\n\ttop:238px;\n\tleft:188px;\n}\n\n#book .data{\n\ttext-align:center;\n\tfont-size:40px;\n\tcolor:#999;\n\tline-height:500px;\n}\n\n#controls{\n\twidth:800px;\n\ttext-align:center;\n\tmargin:20px 0px;\n\tfont:30px arial;\n}\n\n#controls input, #controls label{\n\tfont:30px arial;\n}\n\n#book .odd{\n\tbackground-image:-webkit-linear-gradient(left, #FFF 95%, #ddd 100%);\n\tbackground-image:-moz-linear-gradient(left, #FFF 95%, #ddd 100%);\n\tbackground-image:-o-linear-gradient(left, #FFF 95%, #ddd 100%);\n\tbackground-image:-ms-linear-gradient(left, #FFF 95%, #ddd 100%);\n}\n\n#book .even{\n\tbackground-image:-webkit-linear-gradient(right, #FFF 95%, #ddd 100%);\n\tbackground-image:-moz-linear-gradient(right, #FFF 95%, #ddd 100%);\n\tbackground-image:-o-linear-gradient(right, #FFF 95%, #ddd 100%);\n\tbackground-image:-ms-linear-gradient(right, #FFF 95%, #ddd 100%);\n}\n</style>\n</head>\n<body>\n\n<div id=\"book\">\n\t<div class=\"cover\"><h1>The Bible</h1></div>\n</div>\n\n<div id=\"controls\">\n\t<label for=\"page-number\">Page:</label> <input type=\"text\" size=\"3\" id=\"page-number\"> of <span id=\"number-pages\"></span>\n</div>\n\n<script type=\"text/javascript\">\n\n\t// Sample using dynamic pages with turn.js\n\n\tvar numberOfPages = 1000; \n\n\n\t// Adds the pages that the book will need\n\tfunction addPage(page, book) {\n\t\t// \tFirst check if the page is already in the book\n\t\tif (!book.turn('hasPage', page)) {\n\t\t\t// Create an element for this page\n\t\t\tvar element = $('<div />', {'class': 'page '+((page%2==0) ? 'odd' : 'even'), 'id': 'page-'+page}).html('<i class=\"loader\"></i>');\n\t\t\t// If not then add the page\n\t\t\tbook.turn('addPage', element, page);\n\t\t\t// Let's assum that the data is comming from the server and the request takes 1s.\n\t\t\tsetTimeout(function(){\n\t\t\t\t\telement.html('<div class=\"data\">Data for page '+page+'</div>');\n\t\t\t}, 1000);\n\t\t}\n\t}\n\n\t$(window).ready(function(){\n\t\t$('#book').turn({acceleration: true,\n\t\t\t\t\t\t\tpages: numberOfPages,\n\t\t\t\t\t\t\televation: 50,\n\t\t\t\t\t\t\tgradients: !$.isTouch,\n\t\t\t\t\t\t\twhen: {\n\t\t\t\t\t\t\t\tturning: function(e, page, view) {\n\n\t\t\t\t\t\t\t\t\t// Gets the range of pages that the book needs right now\n\t\t\t\t\t\t\t\t\tvar range = $(this).turn('range', page);\n\n\t\t\t\t\t\t\t\t\t// Check if each page is within the book\n\t\t\t\t\t\t\t\t\tfor (page = range[0]; page<=range[1]; page++) \n\t\t\t\t\t\t\t\t\t\taddPage(page, $(this));\n\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\tturned: function(e, page) {\n\t\t\t\t\t\t\t\t\t$('#page-number').val(page);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t$('#number-pages').html(numberOfPages);\n\n\t\t$('#page-number').keydown(function(e){\n\n\t\t\tif (e.keyCode==13)\n\t\t\t\t$('#book').turn('page', $('#page-number').val());\n\t\t\t\t\n\t\t});\n\t});\n\n\t$(window).bind('keydown', function(e){\n\n\t\tif (e.target && e.target.tagName.toLowerCase()!='input')\n\t\t\tif (e.keyCode==37)\n\t\t\t\t$('#book').turn('previous');\n\t\t\telse if (e.keyCode==39)\n\t\t\t\t$('#book').turn('next');\n\n\t});\n\n</script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "demos/magazine/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n<script type=\"text/javascript\" src=\"http://code.jquery.com/jquery-1.7.1.min.js\"></script>\n<script type=\"text/javascript\" src=\"../../turn.min.js\"></script>\n\n<style type=\"text/css\">\nbody{\n\tbackground:#ccc;\n}\n#magazine{\n\twidth:1152px;\n\theight:752px;\n}\n#magazine .turn-page{\n\tbackground-color:#ccc;\n\tbackground-size:100% 100%;\n}\n</style>\n</head>\n<body>\n\n<div id=\"magazine\">\n\t<div style=\"background-image:url(pages/01.jpg);\"></div>\n\t<div style=\"background-image:url(pages/02.jpg);\"></div>\n\t<div style=\"background-image:url(pages/03.jpg);\"></div>\n\t<div style=\"background-image:url(pages/04.jpg);\"></div>\n\t<div style=\"background-image:url(pages/05.jpg);\"></div>\n\t<div style=\"background-image:url(pages/06.jpg);\"></div>\n</div>\n\n\n<script type=\"text/javascript\">\n\n\t$(window).ready(function() {\n\t\t$('#magazine').turn({\n\t\t\t\t\t\t\tdisplay: 'double',\n\t\t\t\t\t\t\tacceleration: true,\n\t\t\t\t\t\t\tgradients: !$.isTouch,\n\t\t\t\t\t\t\televation:50,\n\t\t\t\t\t\t\twhen: {\n\t\t\t\t\t\t\t\tturned: function(e, page) {\n\t\t\t\t\t\t\t\t\t/*console.log('Current view: ', $(this).turn('view'));*/\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t});\n\t\n\t\n\t$(window).bind('keydown', function(e){\n\t\t\n\t\tif (e.keyCode==37)\n\t\t\t$('#magazine').turn('previous');\n\t\telse if (e.keyCode==39)\n\t\t\t$('#magazine').turn('next');\n\t\t\t\n\t});\n\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demos/magazine_single/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n<script type=\"text/javascript\" src=\"http://code.jquery.com/jquery-1.7.1.min.js\"></script>\n<script type=\"text/javascript\" src=\"../../turn.min.js\"></script>\n\n<style type=\"text/css\">\nbody{\n\tbackground:#ccc;\n}\n#magazine{\n\twidth:576px;\n\theight:752px;\n}\n#magazine .turn-page{\n\tbackground-color:#ccc;\n\tbackground-size:100% 100%;\n}\n</style>\n</head>\n<body>\n\n<div id=\"magazine\">\n\t<div style=\"background-image:url(pages/01.jpg);\"></div>\n\t<div style=\"background-image:url(pages/02.jpg);\"></div>\n\t<div style=\"background-image:url(pages/03.jpg);\"></div>\n\t<div style=\"background-image:url(pages/04.jpg);\"></div>\n\t<div style=\"background-image:url(pages/05.jpg);\"></div>\n\t<div style=\"background-image:url(pages/06.jpg);\"></div>\n</div>\n\n\n<script type=\"text/javascript\">\n\n\t$(window).ready(function() {\n\t\t$('#magazine').turn({\n\t\t\t\t\t\t\tdisplay: 'single',\n\t\t\t\t\t\t\tacceleration: true,\n\t\t\t\t\t\t\tgradients: !$.isTouch,\n\t\t\t\t\t\t\televation:50,\n\t\t\t\t\t\t\twhen: {\n\t\t\t\t\t\t\t\tturned: function(e, page) {\n\t\t\t\t\t\t\t\t\t/*console.log('Current view: ', $(this).turn('view'));*/\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t});\n\t\n\t\n\t$(window).bind('keydown', function(e){\n\t\t\n\t\tif (e.keyCode==37)\n\t\t\t$('#magazine').turn('previous');\n\t\telse if (e.keyCode==39)\n\t\t\t$('#magazine').turn('next');\n\t\t\t\n\t});\n\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "license.txt",
    "content": "turn.js 3rd release\nwww.turnjs.com\n\nCopyright (c) 2012, Emmanuel Garcia\nAll rights reserved.\n\nRedistribution and use in source and binary forms,\nwith or without modification, are permitted provided\nthat the following conditions are met:\n\n- Redistributions of source code must retain the above copyright notice,\n  this list of conditions and the following disclaimer.\n\n- Any redistribution, use, or modification is done solely for personal \n  benefit and not for any commercial purpose or for monetary gain.\n\nTHIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ''AS IS'' AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\nOR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\nHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGE."
  },
  {
    "path": "readme.md",
    "content": "\n![Bilby Stampede](http://turnjs.com/pics/small-turnjs-letters.png)\n\n**Get the turn.js 4th release on [turnjs.com](http://www.turnjs.com/)**\n\n\n### What's new in turn.js 4th release?\n\n- Added option `autoCenter`\n\n- Added option `zoom`\n\n- Added property `animating`\n\n- Added property `zoom`\n\n- Added method `center`\n\n- Added method `destroy`\n\n- Added method `is`\n\n- Added method `zoom`\n\n- Added event `missing`\n\n- Added event `zooming`\n\n- Added class `.even`\n\n- Added class `.fixed`\n\n- Added class `.hard`\n\n- Added class `.odd`\n\n- Added class `.own-size`\n\n- Added class `.sheet`\n\n- Added the ignore attribute\n\n- New turn.html4.js\n\n- New scissors.js\n\n- Changed the class `.turn-page` to `.page`\n\n- Improved the animation frame generator with requestAnimationFrame\n\n- Improved the animation speed for hard pages with CSS3 transitions\n\n- Redesigned the event sequence to listen to only three events\n\n- Fixed issue #79\n\n- Fixed issue #91\n\n- Fixed issue about the event order turning + turned\n\n- Fixed issue about appending pages in wrong locations\n\nAvailable only on [turnjs.com](http://www.turnjs.com/)\n\n* * *\n\nturn.js 3rd release\n=========\n\n### Make a flip book with HTML5\n\nTurn.js is a plugin for jQuery that adds a beautiful transition similar to real pages in a book or magazine. It works in all modern browsers including touch devices.\n\n### What's new?\n\n- New `addPage` for creating pages dynamically.\n\n- New `display` for single and double pages.\n\n- Gradients for non-webkit browsers.\n\n#### Usage\n\n**CSS code:**\n```css\n#magazine{\n\twidth: 800px;\n\theight: 400px;\n}\n#magazine .turn-page{\n\tbackground-color:#ccc;\n}\n```\n\n**HTML code:**\n```html\n<div id=\"magazine\">\n\t<div><span class=\"text\">Page 1</span></div>\n\t<div><span class=\"text\">Page 2</span></div>\n\t<div><span class=\"text\">Page 3</span></div>\n</div>\n```\n\n**JavaScript code:**\n```javascript\n$('#magazine').turn({gradients: true, acceleration: true});\n```\n\n#### Requirements\n\njQuery 1.7 or later\n\n#### Browser support\n* Chrome 12, Safari 5, Firefox 10, IE 9\n\n#### License\nReleased under a non-commercial BSD license\n\n[Full documentation](https://github.com/blasten/turn.js/wiki/Reference)\n\n* * *\n\n[turnjs.com](http://www.turnjs.com/)\n"
  },
  {
    "path": "turn.js",
    "content": "/**\n * turn.js 3rd release\n * www.turnjs.com\n *\n * Copyright (C) 2012, Emmanuel Garcia.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *\n * 2. Any redistribution, use, or modification is done solely for personal \n * benefit and not for any commercial purpose or for monetary gain.\n * \n **/\n\n(function($) {\n\n'use strict';\n\nvar has3d,\n\n\tvendor ='',\n\n\tPI = Math.PI,\n\n\tA90 = PI/2,\n\n\tisTouch = 'ontouchstart' in window,\n\n\tevents = (isTouch) ? {start: 'touchstart', move: 'touchmove', end: 'touchend'}\n\t\t\t: {start: 'mousedown', move: 'mousemove', end: 'mouseup'},\n\n\t// Contansts used for each corner\n\t// tl * tr\n\t// *     *\n\t// bl * br\n\n\tcorners = {\n\t\tbackward: ['bl', 'tl'],\n\t\tforward: ['br', 'tr'],\n\t\tall: ['tl', 'bl', 'tr', 'br']\n\t},\n\n\tdisplays = ['single', 'double'],\n\n\t// Default options\n\n\tturnOptions = {\n\n\t\t// First page\n\n\t\tpage: 1,\n\t\t\n\t\t// Enables gradients\n\n\t\tgradients: true,\n\n\t\t// Duration of transition in milliseconds\n\n\t\tduration: 600,\n\n\t\t// Enables hardware acceleration\n\n\t\tacceleration: true,\n\n\t\t// Display\n\n\t\tdisplay: 'double',\n\n\t\t// Events\n\n\t\twhen: null\n\t},\n\n\tflipOptions = {\n\n\t\t// Back page\n\t\t\n\t\tfolding: null,\n\n\t\t// Corners\n\t\t// backward: Activates both tl and bl corners\n\t\t// forward: Activates both tr and br corners\n\t\t// all: Activates all the corners\n\n\t\tcorners: 'forward',\n\t\t\n\t\t// Size of the active zone of each corner\n\n\t\tcornerSize: 100,\n\n\t\t// Enables gradients\n\n\t\tgradients: true,\n\n\t\t// Duration of transition in milliseconds\n\n\t\tduration: 600,\n\n\t\t// Enables hardware acceleration\n\n\t\tacceleration: true\n\t},\n\n\t// Number of pages in the DOM, minimum value: 6\n\n\tpagesInDOM = 6,\n\t\n\tpagePosition = {0: {top: 0, left: 0, right: 'auto', bottom: 'auto'},\n\t\t\t\t\t1: {top: 0, right: 0, left: 'auto', bottom: 'auto'}},\n\n\t// Gets basic attributes for a layer\n\n\tdivAtt = function(top, left, zIndex, overf) {\n\t\treturn {'css': {\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: top,\n\t\t\t\t\tleft: left,\n\t\t\t\t\t'overflow': overf || 'hidden',\n\t\t\t\t\t'z-index': zIndex || 'auto'\n\t\t\t\t\t}\n\t\t\t};\n\t},\n\n\t// Gets a 2D point from a bezier curve of four points\n\n\tbezier = function(p1, p2, p3, p4, t) {\n\t\tvar mum1 = 1 - t,\n\t\t\tmum13 = mum1 * mum1 * mum1,\n\t\t\tmu3 = t * t * t;\n\n\t\treturn point2D(Math.round(mum13*p1.x + 3*t*mum1*mum1*p2.x + 3*t*t*mum1*p3.x + mu3*p4.x),\n\t\t\t\t\t\tMath.round(mum13*p1.y + 3*t*mum1*mum1*p2.y + 3*t*t*mum1*p3.y + mu3*p4.y));\n\t},\n\t\n\t// Converts an angle from degrees to radians\n\n\trad = function(degrees) {\n\t\treturn degrees/180*PI;\n\t},\n\n\t// Converts an angle from radians to degrees\n\n\tdeg = function(radians) {\n\t\treturn radians/PI*180;\n\t},\n\n\t// Gets a 2D point\n\n\tpoint2D = function(x, y) {\n\t\treturn {x: x, y: y};\n\t},\n\n\t// Returns the traslate value\n\n\ttranslate = function(x, y, use3d) {\n\t\treturn (has3d && use3d) ? ' translate3d(' + x + 'px,' + y + 'px, 0px) ' : ' translate(' + x + 'px, ' + y + 'px) ';\n\t},\n\n\t// Returns the rotation value\n\n\trotate = function(degrees) {\n\t\treturn ' rotate(' + degrees + 'deg) ';\n\t},\n\n\t// Checks if a property belongs to an object\n\n\thas = function(property, object) {\n\t\treturn Object.prototype.hasOwnProperty.call(object, property);\n\t},\n\n\t// Gets the CSS3 vendor prefix\n\n\tgetPrefix = function() {\n\t\tvar vendorPrefixes = ['Moz','Webkit','Khtml','O','ms'],\n\t\t\tlen = vendorPrefixes.length,\n\t\t\tvendor = '';\n\n\t\twhile (len--)\n\t\t\tif ((vendorPrefixes[len] + 'Transform') in document.body.style)\n\t\t\t\tvendor='-'+vendorPrefixes[len].toLowerCase()+'-';\n\n\t\treturn vendor;\n\t},\n\n\t// Adds gradients\n\n\tgradient = function(obj, p0, p1, colors, numColors) {\n\t\n\t\tvar j, cols = [];\n\n\t\tif (vendor=='-webkit-') {\n\t\t\n\t\t\tfor (j = 0; j<numColors; j++)\n\t\t\t\t\tcols.push('color-stop('+colors[j][0]+', '+colors[j][1]+')');\n\t\t\t\n\t\t\tobj.css({'background-image': '-webkit-gradient(linear, '+p0.x+'% '+p0.y+'%,  '+p1.x+'% '+p1.y+'%, '+ cols.join(',') +' )'});\n\n\t\t} else {\n\n\t\t\t// This procedure makes the gradients for non-webkit browsers\n\t\t\t// It will be reduced to one unique way for gradients in next versions\n\t\t\t\n\t\t\tp0 = {x:p0.x/100 * obj.width(), y:p0.y/100 * obj.height()};\n\t\t\tp1 = {x:p1.x/100 * obj.width(), y:p1.y/100 * obj.height()};\n\n\t\t\tvar dx = p1.x-p0.x,\n\t\t\t\tdy = p1.y-p0.y,\n\t\t\t\tangle = Math.atan2(dy, dx),\n\t\t\t\tangle2 = angle - Math.PI/2,\n\t\t\t\tdiagonal = Math.abs(obj.width()*Math.sin(angle2)) + Math.abs(obj.height()*Math.cos(angle2)),\n\t\t\t\tgradientDiagonal = Math.sqrt(dy*dy + dx*dx),\n\t\t\t\tcorner = point2D((p1.x<p0.x) ? obj.width() : 0, (p1.y<p0.y) ? obj.height() : 0),\n\t\t\t\tslope = Math.tan(angle),\n\t\t\t\tinverse = -1/slope,\n\t\t\t\tx = (inverse*corner.x - corner.y - slope*p0.x + p0.y) / (inverse-slope),\n\t\t\t\tc = {x: x, y: inverse*x - inverse*corner.x + corner.y},\n\t\t\t\tsegA = (Math.sqrt( Math.pow(c.x-p0.x,2) + Math.pow(c.y-p0.y,2)));\n\n\t\t\t\tfor (j = 0; j<numColors; j++)\n\t\t\t\t\tcols.push(' '+colors[j][1]+' '+(( segA + gradientDiagonal*colors[j][0] )*100/diagonal)+'%');\n\t\t\n\t\t\t\tobj.css({'background-image': vendor+'linear-gradient(' + (-angle) + 'rad,' + cols.join(',') + ')'});\n\t\t}\n\t},\n\nturnMethods = {\n\n\t// Singleton constructor\n\t// $('#selector').turn([options]);\n\n\tinit: function(opts) {\n\n\t\t// Define constants\n\t\tif (has3d===undefined) {\n\t\t\thas3d = 'WebKitCSSMatrix' in window || 'MozPerspective' in document.body.style;\n\t\t\tvendor = getPrefix();\n\t\t}\n\n\t\tvar i, data = this.data(), ch = this.children();\n\t\n\t\topts = $.extend({width: this.width(), height: this.height()}, turnOptions, opts);\n\t\tdata.opts = opts;\n\t\tdata.pageObjs = {};\n\t\tdata.pages = {};\n\t\tdata.pageWrap = {};\n\t\tdata.pagePlace = {};\n\t\tdata.pageMv = [];\n\t\tdata.totalPages = opts.pages || 0;\n\n\t\tif (opts.when)\n\t\t\tfor (i in opts.when)\n\t\t\t\tif (has(i, opts.when))\n\t\t\t\t\tthis.bind(i, opts.when[i]);\n\n\n\t\tthis.css({position: 'relative', width: opts.width, height: opts.height});\n\n\t\tthis.turn('display', opts.display);\n\n\t\tif (has3d && !isTouch && opts.acceleration)\n\t\t\tthis.transform(translate(0, 0, true));\n\t\n\t\tfor (i = 0; i<ch.length; i++)\n\t\t\tthis.turn('addPage', ch[i], i+1);\n\t\n\t\tthis.turn('page', opts.page);\n\n        // allow setting active corners as an option\n        corners = $.extend({}, corners, opts.corners);\n\n\t\t// Event listeners\n\n\t\t$(this).bind(events.start, function(e) {\n\t\t\tfor (var page in data.pages)\n\t\t\t\tif (has(page, data.pages) && flipMethods._eventStart.call(data.pages[page], e)===false)\n\t\t\t\t\treturn false;\n\t\t});\n\t\t\t\n\t\t$(document).bind(events.move, function(e) {\n\t\t\tfor (var page in data.pages)\n\t\t\t\tif (has(page, data.pages))\n\t\t\t\t\tflipMethods._eventMove.call(data.pages[page], e);\n\t\t}).\n\t\tbind(events.end, function(e) {\n\t\t\tfor (var page in data.pages)\n\t\t\t\tif (has(page, data.pages))\n\t\t\t\t\tflipMethods._eventEnd.call(data.pages[page], e);\n\n\t\t});\n\n\t\tdata.done = true;\n\n\t\treturn this;\n\t},\n\n\t// Adds a page from external data\n\n\taddPage: function(element, page) {\n\n\t\tvar incPages = false,\n\t\t\tdata = this.data(),\n\t\t\tlastPage = data.totalPages+1;\n\n\t\tif (page) {\n\t\t\tif (page==lastPage) {\n\t\t\t\tpage = lastPage;\n\t\t\t\tincPages = true;\n\t\t\t} else if (page>lastPage)\n\t\t\t\tthrow new Error ('It is impossible to add the page \"'+page+'\", the maximum value is: \"'+lastPage+'\"');\n\n\t\t} else {\n\t\t\tpage = lastPage;\n\t\t\tincPages = true;\n\t\t}\n\n\t\tif (page>=1 && page<=lastPage) {\n\n\t\t\t// Stop animations\n\t\t\tif (data.done) this.turn('stop');\n\n\t\t\t// Move pages if it's necessary\n\t\t\tif (page in data.pageObjs)\n\t\t\t\tturnMethods._movePages.call(this, page, 1);\n\n\t\t\t// Update number of pages\n\t\t\tif (incPages)\n\t\t\t\tdata.totalPages = lastPage;\n\n\t\t\t// Add element\n\t\t\tdata.pageObjs[page] = $(element).addClass('turn-page p' + page);\n\n\t\t\t// Add page\n\t\t\tturnMethods._addPage.call(this, page);\n\n\t\t\t// Update view\n\t\t\tif (data.done)\n\t\t\t\tthis.turn('update');\n\n\t\t\tturnMethods._removeFromDOM.call(this);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t// Adds a page from internal data\n\n\t_addPage: function(page) {\n\t\t\n\t\tvar data = this.data(),\n\t\t\telement = data.pageObjs[page];\n\n\t\tif (element)\n\t\t\tif (turnMethods._necessPage.call(this, page)) {\n\t\t\t\t\n\t\t\t\tif (!data.pageWrap[page]) {\n\n\t\t\t\t\tvar pageWidth = (data.display=='double') ? this.width()/2 : this.width(),\n\t\t\t\t\t\tpageHeight = this.height();\n\n\t\t\t\t\telement.css({width:pageWidth, height:pageHeight});\n\n\t\t\t\t\t// Place\n\t\t\t\t\tdata.pagePlace[page] = page;\n\n\t\t\t\t\t// Wrapper\n\t\t\t\t\tdata.pageWrap[page] = $('<div/>', {'class': 'turn-page-wrapper',\n\t\t\t\t\t\t\t\t\t\t\t\t\tpage: page,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcss: {position: 'absolute',\n\t\t\t\t\t\t\t\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\t\t\t\t\t\t\t\twidth: pageWidth,\n\t\t\t\t\t\t\t\t\t\t\t\t\theight: pageHeight}}).\n\t\t\t\t\t\t\t\t\t\t\t\t\tcss(pagePosition[(data.display=='double') ? page%2 : 0]);\n\n\t\t\t\t\t// Append to this\n\t\t\t\t\tthis.append(data.pageWrap[page]);\n\n\t\t\t\t\t// Move data.pageObjs[page] (element) to wrapper\n\t\t\t\t\tdata.pageWrap[page].prepend(data.pageObjs[page]);\n\t\t\t\t}\n\n\t\t\t\t// If the page is in the current view, create the flip effect\n\t\t\t\tif (!page || turnMethods._setPageLoc.call(this, page)==1)\n\t\t\t\t\tturnMethods._makeFlip.call(this, page);\n\t\t\t\t\n\t\t\t} else {\n\n\t\t\t\t// Place\n\t\t\t\tdata.pagePlace[page] = 0;\n\n\t\t\t\t// Remove element from the DOM\n\t\t\t\tif (data.pageObjs[page])\n\t\t\t\t\tdata.pageObjs[page].remove();\n\n\t\t\t}\n\n\t},\n\n\t// Checks if a page is in memory\n\t\n\thasPage: function(page) {\n\n\t\treturn page in this.data().pageObjs;\n\t\n\t},\n\n\t// Prepares the flip effect for a page\n\n\t_makeFlip: function(page) {\n\n\t\tvar data = this.data();\n\n\t\tif (!data.pages[page] && data.pagePlace[page]==page) {\n\n\t\t\tvar single = data.display=='single',\n\t\t\t\teven = page%2;\n\t\t\t\n\t\t\tdata.pages[page] = data.pageObjs[page].\n\t\t\t\t\t\t\t\tcss({width: (single) ? this.width() : this.width()/2, height: this.height()}).\n\t\t\t\t\t\t\t\tflip({page: page,\n\t\t\t\t\t\t\t\t\tnext: (single && page === data.totalPages) ? page -1 : ((even || single) ? page+1 : page-1),\n\t\t\t\t\t\t\t\t\tturn: this,\n\t\t\t\t\t\t\t\t\tduration: data.opts.duration,\n\t\t\t\t\t\t\t\t\tacceleration : data.opts.acceleration,\n\t\t\t\t\t\t\t\t\tcorners: (single) ? 'all' : ((even) ? 'forward' : 'backward'),\n\t\t\t\t\t\t\t\t\tbackGradient: data.opts.gradients,\n\t\t\t\t\t\t\t\t\tfrontGradient: data.opts.gradients\n\t\t\t\t\t\t\t\t\t}).\n\t\t\t\t\t\t\t\t\tflip('disable', data.disabled).\n\t\t\t\t\t\t\t\t\tbind('pressed', turnMethods._pressed).\n\t\t\t\t\t\t\t\t\tbind('released', turnMethods._released).\n\t\t\t\t\t\t\t\t\tbind('start', turnMethods._start).\n\t\t\t\t\t\t\t\t\tbind('end', turnMethods._end).\n\t\t\t\t\t\t\t\t\tbind('flip', turnMethods._flip);\n\t\t}\n\t\treturn data.pages[page];\n\t},\n\n\t// Makes pages within a range\n\n\t_makeRange: function() {\n\n\t\tvar page,\n\t\t\tdata = this.data(),\n\t\t\trange = this.turn('range');\n\n\t\t\tfor (page = range[0]; page<=range[1]; page++)\n\t\t\t\tturnMethods._addPage.call(this, page);\n\n\t},\n\n\t// Returns a range of `pagesInDOM` pages that should be in the DOM\n\t// Example:\n\t// - page of the current view, return true\n\t// * page is in the range, return true\n\t// 0 page is not in the range, return false\n\t//\n\t// 1 2-3 4-5 6-7 8-9 10-11 12-13\n\t//    **  **  --   **  **\n\n\trange: function(page) {\n\n\t\tvar remainingPages, left, right,\n\t\t\tdata = this.data();\n\t\t\tpage = page || data.tpage || data.page;\n\t\t\tvar view = turnMethods._view.call(this, page);\n\n\t\t\tif (page<1 || page>data.totalPages)\n\t\t\t\tthrow new Error ('\"'+page+'\" is not a page for range');\n\t\t\n\t\t\tview[1] = view[1] || view[0];\n\t\t\t\n\t\t\tif (view[0]>=1 && view[1]<=data.totalPages) {\n\n\t\t\t\tremainingPages = Math.floor((pagesInDOM-2)/2);\n\n\t\t\t\tif (data.totalPages-view[1] > view[0]) {\n\t\t\t\t\tleft = Math.min(view[0]-1, remainingPages);\n\t\t\t\t\tright = 2*remainingPages-left;\n\t\t\t\t} else {\n\t\t\t\t\tright = Math.min(data.totalPages-view[1], remainingPages);\n\t\t\t\t\tleft = 2*remainingPages-right;\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tleft = pagesInDOM-1;\n\t\t\t\tright = pagesInDOM-1;\n\t\t\t}\n\n\t\t\treturn [Math.max(1, view[0]-left), Math.min(data.totalPages, view[1]+right)];\n\n\t},\n\n\t// Detects if a page is within the range of `pagesInDOM` from the current view\n\n\t_necessPage: function(page) {\n\t\t\n\t\tif (page===0)\n\t\t\treturn true;\n\n\t\tvar range = this.turn('range');\n\n\t\treturn page>=range[0] && page<=range[1];\n\t\t\n\t},\n\n\t// Releases memory by removing pages from the DOM\n\n\t_removeFromDOM: function() {\n\n\t\tvar page, data = this.data();\n\n\t\tfor (page in data.pageWrap)\n\t\t\tif (has(page, data.pageWrap) && !turnMethods._necessPage.call(this, page))\n\t\t\t\tturnMethods._removePageFromDOM.call(this, page);\n\t\t\n\n\t},\n\n\t// Removes a page from DOM and its internal references\n\n\t_removePageFromDOM: function(page) {\n\n\t\tvar data = this.data();\n\n\t\tif (data.pages[page]) {\n\t\t\tvar dd = data.pages[page].data();\n\t\t\tif (dd.f && dd.f.fwrapper)\n\t\t\t\tdd.f.fwrapper.remove();\n\t\t\tdata.pages[page].remove();\n\t\t\tdelete data.pages[page];\n\t\t}\n\n\t\tif (data.pageObjs[page])\n\t\t\tdata.pageObjs[page].remove();\n\n\t\tif (data.pageWrap[page]) {\n\t\t\tdata.pageWrap[page].remove();\n\t\t\tdelete data.pageWrap[page];\n\t\t}\n\n\t\tdelete data.pagePlace[page];\n\n\t},\n\n\t// Removes a page\n\n\tremovePage: function(page) {\n\n\t\tvar data = this.data();\n\n\t\tif (data.pageObjs[page]) {\n\t\t\t// Stop animations\n\t\t\tthis.turn('stop');\n\n\t\t\t// Remove `page`\n\t\t\tturnMethods._removePageFromDOM.call(this, page);\n\t\t\tdelete data.pageObjs[page];\n\n\t\t\t// Move the pages behind `page`\n\t\t\tturnMethods._movePages.call(this, page, -1);\n\n\t\t\t// Resize the size of this magazine\n\t\t\tdata.totalPages = data.totalPages-1;\n\t\t\tturnMethods._makeRange.call(this);\n\n\t\t\t// Check the current view\n\t\t\tif (data.page>data.totalPages)\n\t\t\t\tthis.turn('page', data.totalPages);\n\t\t}\n\n\t\treturn this;\n\t\n\t},\n\n\t// Moves pages\n\n\t_movePages: function(from, change) {\n\n\t\tvar page,\n\t\t\tdata = this.data(),\n\t\t\tsingle = data.display=='single',\n\t\t\tmove = function(page) {\n\n\t\t\t\tvar next = page + change,\n\t\t\t\t\todd = next%2;\n\n\t\t\t\tif (data.pageObjs[page])\n\t\t\t\t\tdata.pageObjs[next] = data.pageObjs[page].removeClass('page' + page).addClass('page' + next);\n\n\t\t\t\tif (data.pagePlace[page] && data.pageWrap[page]) {\n\t\t\t\t\tdata.pagePlace[next] = next;\n\t\t\t\t\tdata.pageWrap[next] = data.pageWrap[page].css(pagePosition[(single) ? 0 : odd]).attr('page', next);\n\t\t\t\t\t\n\t\t\t\t\tif (data.pages[page])\n\t\t\t\t\t\tdata.pages[next] = data.pages[page].flip('options', {\n\t\t\t\t\t\t\tpage: next,\n\t\t\t\t\t\t\tnext: (single || odd) ? next+1 : next-1,\n\t\t\t\t\t\t\tcorners: (single) ? 'all' : ((odd) ? 'forward' : 'backward')\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (change) {\n\t\t\t\t\t\tdelete data.pages[page];\n\t\t\t\t\t\tdelete data.pagePlace[page];\n\t\t\t\t\t\tdelete data.pageObjs[page];\n\t\t\t\t\t\tdelete data.pageWrap[page];\n\t\t\t\t\t\tdelete data.pageObjs[page];\n\t\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tif (change>0)\n\t\t\tfor (page=data.totalPages; page>=from; page--) move(page);\n\t\telse\n\t\t\tfor (page=from; page<=data.totalPages; page++) move(page);\n\n\t},\n\n\t// Sets or Gets the display mode\n\n\tdisplay: function(display) {\n\n\t\tvar data = this.data(),\n\t\t\tcurrentDisplay = data.display;\n\n\t\tif (display) {\n\n\t\t\tif ($.inArray(display, displays)==-1)\n\t\t\t\tthrow new Error ('\"'+display + '\" is not a value for display');\n\t\t\t\n\t\t\tif (display=='single') {\n\t\t\t\tif (!data.pageObjs[0]) {\n\t\t\t\t\tthis.turn('stop').\n\t\t\t\t\t\tcss({'overflow': 'hidden'});\n\t\t\t\t\tdata.pageObjs[0] = $('<div />', {'class': 'turn-page p-temporal'}).\n\t\t\t\t\t\t\t\t\tcss({width: this.width(), height: this.height()}).\n\t\t\t\t\t\t\t\t\t\tappendTo(this);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (data.pageObjs[0]) {\n\t\t\t\t\tthis.turn('stop').\n\t\t\t\t\t\tcss({'overflow': ''});\n\t\t\t\t\tdata.pageObjs[0].remove();\n\t\t\t\t\tdelete data.pageObjs[0];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdata.display = display;\n\n\t\t\tif (currentDisplay) {\n\t\t\t\tvar size = this.turn('size');\n\t\t\t\tturnMethods._movePages.call(this, 1, 0);\n\t\t\t\tthis.turn('size', size.width, size.height).\n\t\t\t\t\t\tturn('update');\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t} else\n\t\t\treturn currentDisplay;\n\t\n\t},\n\n\t// Detects if the pages are being animated\n\n\tanimating: function() {\n\n\t\treturn this.data().pageMv.length>0;\n\n\t},\n\n\t// Disables and enables the effect\n\n\tdisable: function(bool) {\n\n\t\tvar page,\n\t\t\tdata = this.data(),\n\t\t\tview = this.turn('view');\n\n\t\t\tdata.disabled = bool===undefined || bool===true;\n\n\t\tfor (page in data.pages)\n\t\t\tif (has(page, data.pages))\n\t\t\t\tdata.pages[page].flip('disable', bool ? $.inArray(page, view) : false );\n\n\t\treturn this;\n\n\t},\n\n\t// Gets and sets the size\n\n\tsize: function(width, height) {\n\n\t\tif (width && height) {\n\n\t\t\tvar data = this.data(), pageWidth = (data.display=='double') ? width/2 : width, page;\n\n\t\t\tthis.css({width: width, height: height});\n\n\t\t\tif (data.pageObjs[0])\n\t\t\t\tdata.pageObjs[0].css({width: pageWidth, height: height});\n\t\t\t\n\t\t\tfor (page in data.pageWrap) {\n\t\t\t\tif (!has(page, data.pageWrap)) continue;\n\t\t\t\tdata.pageObjs[page].css({width: pageWidth, height: height});\n\t\t\t\tdata.pageWrap[page].css({width: pageWidth, height: height});\n\t\t\t\tif (data.pages[page])\n\t\t\t\t\tdata.pages[page].css({width: pageWidth, height: height});\n\t\t\t}\n\n\t\t\tthis.turn('resize');\n\n\t\t\treturn this;\n\n\t\t} else {\n\t\t\t\n\t\t\treturn {width: this.width(), height: this.height()};\n\n\t\t}\n\t},\n\n\t// Resizes each page\n\n\tresize: function() {\n\n\t\tvar page, data = this.data();\n\n\t\tif (data.pages[0]) {\n\t\t\tdata.pageWrap[0].css({left: -this.width()});\n\t\t\tdata.pages[0].flip('resize', true);\n\t\t}\n\n\t\tfor (page = 1; page <= data.totalPages; page++)\n\t\t\tif (data.pages[page])\n\t\t\t\tdata.pages[page].flip('resize', true);\n\n\n\t},\n\n\t// Removes an animation from the cache\n\n\t_removeMv: function(page) {\n\n\t\tvar i, data = this.data();\n\t\t\t\n\t\tfor (i=0; i<data.pageMv.length; i++)\n\t\t\tif (data.pageMv[i]==page) {\n\t\t\t\tdata.pageMv.splice(i, 1);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\treturn false;\n\n\t},\n\n\t// Adds an animation to the cache\n\t\n\t_addMv: function(page) {\n\n\t\tvar data = this.data();\n\n\t\tturnMethods._removeMv.call(this, page);\n\t\tdata.pageMv.push(page);\n\n\t},\n\n\t// Gets indexes for a view\n\n\t_view: function(page) {\n\t\n\t\tvar data = this.data();\n\t\tpage = page || data.page;\n\n\t\tif (data.display=='double')\n\t\t\treturn (page%2) ? [page-1, page] : [page, page+1];\n\t\telse\n\t\t\treturn [page];\n\n\t},\n\n\t// Gets a view\n\n\tview: function(page) {\n\n\t\tvar data = this.data(), view = turnMethods._view.call(this, page);\n\n\t\treturn (data.display=='double') ? [(view[0]>0) ? view[0] : 0, (view[1]<=data.totalPages) ? view[1] : 0]\n\t\t\t\t: [(view[0]>0 && view[0]<=data.totalPages) ? view[0] : 0];\n\n\t},\n\n\t// Stops animations\n\n\tstop: function(ok) {\n\n\t\tvar i, opts, data = this.data(), pages = data.pageMv;\n\n\t\tdata.pageMv = [];\n\n\t\tif (data.tpage) {\n\t\t\tdata.page = data.tpage;\n\t\t\tdelete data['tpage'];\n\t\t}\n\n\t\tfor (i in pages) {\n\t\t\tif (!has(i, pages)) continue;\n\t\t\topts = data.pages[pages[i]].data().f.opts;\n\t\t\tflipMethods._moveFoldingPage.call(data.pages[pages[i]], null);\n\t\t\tdata.pages[pages[i]].flip('hideFoldedPage');\n\t\t\tdata.pagePlace[opts.next] = opts.next;\n\t\t\t\n\t\t\tif (opts.force) {\n\t\t\t\topts.next = (opts.page%2===0) ? opts.page-1 : opts.page+1;\n\t\t\t\tdelete opts['force'];\n\t\t\t}\n\n\t\t}\n\n\t\tthis.turn('update');\n\n\t\treturn this;\n\t},\n\n\t// Gets and sets the number of pages\n\n\tpages: function(pages) {\n\n\t\tvar data = this.data();\n\n\t\tif (pages) {\n\t\t\tif (pages<data.totalPages) {\n\n\t\t\t\tfor (var page = pages+1; page<=data.totalPages; page++)\n\t\t\t\t\tthis.turn('removePage', page);\n\n\t\t\t\tif (this.turn('page')>pages)\n\t\t\t\t\tthis.turn('page', pages);\n\t\t\t}\n\n\t\t\tdata.totalPages = pages;\n\n\t\t\treturn this;\n\t\t} else\n\t\t\treturn data.totalPages;\n\n\t},\n\n\t// Sets a page without effect\n\n\t_fitPage: function(page, ok) {\n\t\t\n\t\tvar data = this.data(), newView = this.turn('view', page);\n\t\t\n\t\tif (data.page!=page) {\n\t\t\tthis.trigger('turning', [page, newView]);\n\t\t\tif ($.inArray(1, newView)!=-1) this.trigger('first');\n\t\t\tif ($.inArray(data.totalPages, newView)!=-1) this.trigger('last');\n\t\t}\n\n\t\tif (!data.pageObjs[page])\n\t\t\treturn;\n\n\t\tdata.tpage = page;\n\n\t\tthis.turn('stop', ok);\n\t\tturnMethods._removeFromDOM.call(this);\n\t\tturnMethods._makeRange.call(this);\n\t\tthis.trigger('turned', [page, newView]);\n\n\t},\n\t\n\t// Turns to a page\n\n\t_turnPage: function(page) {\n\n\t\tvar current, next,\n\t\t\tdata = this.data(),\n\t\t\tview = this.turn('view'),\n\t\t\tnewView = this.turn('view', page);\n\t\n\t\tif (data.page!=page) {\n\t\t\tthis.trigger('turning', [page, newView]);\n\t\t\tif ($.inArray(1, newView)!=-1) this.trigger('first');\n\t\t\tif ($.inArray(data.totalPages, newView)!=-1) this.trigger('last');\n\t\t}\n\n\t\tif (!data.pageObjs[page])\n\t\t\treturn;\n\n\t\tdata.tpage = page;\n\n\t\tthis.turn('stop');\n\n\t\tturnMethods._makeRange.call(this);\n\n\t\tif (data.display=='single') {\n\t\t\tcurrent = view[0];\n\t\t\tnext = newView[0];\n\t\t} else if (view[1] && page>view[1]) {\n\t\t\tcurrent = view[1];\n\t\t\tnext = newView[0];\n\t\t} else if (view[0] && page<view[0]) {\n\t\t\tcurrent = view[0];\n\t\t\tnext = newView[1];\n\t\t}\n\n\t\tif (data.pages[current]) {\n\n\t\t\tvar opts = data.pages[current].data().f.opts;\n\t\t\tdata.tpage = next;\n\t\t\t\n\t\t\tif (opts.next!=next) {\n\t\t\t\topts.next = next;\n\t\t\t\tdata.pagePlace[next] = opts.page;\n\t\t\t\topts.force = true;\n\t\t\t}\n\n\t\t\tif (data.display=='single')\n\t\t\t\tdata.pages[current].flip('turnPage', (newView[0] > view[0]) ? 'br' : 'bl');\n\t\t\telse\n\t\t\t\tdata.pages[current].flip('turnPage');\n\t\t}\n\n\t},\n\n\t// Gets and sets a page\n\n\tpage: function(page) {\n\n\t\tpage = parseInt(page, 10);\n\n\t\tvar data = this.data();\n\n\t\tif (page>0 && page<=data.totalPages) {\n\t\t\tif (!data.done || $.inArray(page, this.turn('view'))!=-1)\n\t\t\t\tturnMethods._fitPage.call(this, page);\n\t\t\telse\n\t\t\t\tturnMethods._turnPage.call(this, page);\n\t\t\n\t\t\treturn this;\n\n\t\t} else\n\t\t\treturn data.page;\n\t\n\t},\n\n\t// Turns to the next view\n\n\tnext: function() {\n\n\t\tvar data = this.data();\n\t\treturn this.turn('page', turnMethods._view.call(this, data.page).pop() + 1);\n\t\n\t},\n\n\t// Turns to the previous view\n\n\tprevious: function() {\n\t\t\n\t\tvar data = this.data();\n\t\treturn this.turn('page', turnMethods._view.call(this, data.page).shift() - 1);\n\n\t},\n\n\t// Adds a motion to the internal list\n\n\t_addMotionPage: function() {\n\n\t\tvar opts = $(this).data().f.opts,\n\t\t\tturn = opts.turn,\n\t\t\tdd = turn.data();\n\n\t\topts.pageMv = opts.page;\n\t\tturnMethods._addMv.call(turn, opts.pageMv);\n\t\tdd.pagePlace[opts.next] = opts.page;\n\t\tturn.turn('update');\n\n\t},\n\n\t// This event is called in context of flip\n\n\t_start: function(e, opts, corner) {\n\n\t\t\tvar data = opts.turn.data(),\n\t\t\t\tevent = $.Event('start');\n\n\t\t\te.stopPropagation();\n\n\t\t\topts.turn.trigger(event, [opts, corner]);\n\n\t\t\tif (event.isDefaultPrevented()) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\n\t\tif (data.display=='single') {\n\n\t\t\tvar left = corner.charAt(1)=='l';\n\t\t\tif ((opts.page==1 && left) || (opts.page==data.totalPages && !left))\n\t\t\t\te.preventDefault();\n\t\t\telse {\n\t\t\t\tif (left) {\n\t\t\t\t\topts.next = (opts.next<opts.page) ? opts.next : opts.page-1;\n\t\t\t\t\topts.force = true;\n\t\t\t\t} else\n\t\t\t\t\topts.next = (opts.next>opts.page) ? opts.next : opts.page+1;\n\t\t\t}\n\n\t\t}\n\n\t\tturnMethods._addMotionPage.call(this);\n\t},\n\n\t// This event is called in context of flip\n\n\t_end: function(e, turned) {\n\t\t\n\t\tvar that = $(this),\n\t\t\tdata = that.data().f,\n\t\t\topts = data.opts,\n\t\t\tturn = opts.turn,\n\t\t\tdd = turn.data();\n\n\t\te.stopPropagation();\n\n\t\tif (turned || dd.tpage) {\n\n\t\t\tif (dd.tpage==opts.next || dd.tpage==opts.page) {\n\t\t\t\tdelete dd['tpage'];\n\t\t\t\tturnMethods._fitPage.call(turn, dd.tpage || opts.next, true);\n\t\t\t}\n\n\t\t} else {\n\t\t\tturnMethods._removeMv.call(turn, opts.pageMv);\n\t\t\tturn.turn('update');\n\t\t}\n\t\t\n\t},\n\t\n\t// This event is called in context of flip\n\n\t_pressed: function() {\n\n\t\tvar page,\n\t\t\tthat = $(this),\n\t\t\tdata = that.data().f,\n\t\t\tturn = data.opts.turn,\n\t\t\tpages = turn.data().pages;\n\t\n\t\tfor (page in pages)\n\t\t\tif (page!=data.opts.page)\n\t\t\t\tpages[page].flip('disable', true);\n\n\t\treturn data.time = new Date().getTime();\n\n\t},\n\n\t// This event is called in context of flip\n\n\t_released: function(e, point) {\n\t\t\n\t\tvar that = $(this),\n\t\t\tdata = that.data().f;\n\n\t\t\te.stopPropagation();\n\n\t\tif ((new Date().getTime())-data.time<200 || point.x<0 || point.x>$(this).width()) {\n\t\t\te.preventDefault();\n\t\t\tdata.opts.turn.data().tpage = data.opts.next;\n\t\t\tdata.opts.turn.turn('update');\n\t\t\t$(that).flip('turnPage');\n\t\t}\n\n\t},\n\n\t// This event is called in context of flip\n\t\n\t_flip: function() {\n\n\t\tvar opts = $(this).data().f.opts;\n\n\t\topts.turn.trigger('turn', [opts.next]);\n\n\t},\n\n\t// Calculate the z-index value for pages during the animation\n\n\tcalculateZ: function(mv) {\n\n\t\tvar i, page, nextPage, placePage, dpage,\n\t\t\tthat = this,\n\t\t\tdata = this.data(),\n\t\t\tview = this.turn('view'),\n\t\t\tcurrentPage = view[0] || view[1],\n\t\t\tr = {pageZ: {}, partZ: {}, pageV: {}},\n\n\t\t\taddView = function(page) {\n\t\t\t\tvar view = that.turn('view', page);\n\t\t\t\tif (view[0]) r.pageV[view[0]] = true;\n\t\t\t\tif (view[1]) r.pageV[view[1]] = true;\n\t\t\t};\n\t\t\n\t\t\tfor (i = 0; i<mv.length; i++) {\n\t\t\t\tpage = mv[i];\n\t\t\t\tnextPage = data.pages[page].data().f.opts.next;\n\t\t\t\tplacePage = data.pagePlace[page];\n\t\t\t\taddView(page);\n\t\t\t\taddView(nextPage);\n\t\t\t\tdpage = (data.pagePlace[nextPage]==nextPage) ? nextPage : page;\n\t\t\t\tr.pageZ[dpage] = data.totalPages - Math.abs(currentPage-dpage);\n\t\t\t\tr.partZ[placePage] = data.totalPages*2 + Math.abs(currentPage-dpage);\n\t\t\t}\n\n\t\treturn r;\n\t},\n\n\t// Updates the z-index and display property of every page\n\n\tupdate: function() {\n\n\t\tvar page,\n\t\t\tdata = this.data();\n\n\t\tif (data.pageMv.length && data.pageMv[0]!==0) {\n\n\t\t\t// Update motion\n\n\t\t\tvar apage,\n\t\t\t\tpos = this.turn('calculateZ', data.pageMv),\n\t\t\t\tview = this.turn('view', data.tpage);\n\t\t\n\t\t\tif (data.pagePlace[view[0]]==view[0]) apage = view[0];\n\t\t\telse if (data.pagePlace[view[1]]==view[1]) apage = view[1];\n\t\t\n\t\t\tfor (page in data.pageWrap) {\n\n\t\t\t\tif (!has(page, data.pageWrap)) continue;\n\n\t\t\t\tdata.pageWrap[page].css({display: (pos.pageV[page]) ? '' : 'none', 'z-index': pos.pageZ[page] || 0});\n\n\t\t\t\tif (data.pages[page]) {\n\t\t\t\t\tdata.pages[page].flip('z', pos.partZ[page] || null);\n\n\t\t\t\t\tif (pos.pageV[page])\n\t\t\t\t\t\tdata.pages[page].flip('resize');\n\n\t\t\t\t\tif (data.tpage)\n\t\t\t\t\t\tdata.pages[page].flip('disable', true); // data.disabled || page!=apage\n\t\t\t\t}\n\t\t\t}\n\t\t\t\t\n\t\t} else {\n\n\t\t\t// Update static pages\n\n\t\t\tfor (page in data.pageWrap) {\n\t\t\t\tif (!has(page, data.pageWrap)) continue;\n\t\t\t\t\tvar pageLocation = turnMethods._setPageLoc.call(this, page);\n\t\t\t\t\tif (data.pages[page])\n\t\t\t\t\t\tdata.pages[page].flip('disable', data.disabled || pageLocation!=1).flip('z', null);\n\t\t\t}\n\t\t}\n\t},\n\n\t// Sets the z-index and display property of a page\n\t// It depends on the current view\n\n\t_setPageLoc: function(page) {\n\n\t\tvar data = this.data(),\n\t\t\tview = this.turn('view');\n\n\t\tif (page==view[0] || page==view[1]) {\n\t\t\tdata.pageWrap[page].css({'z-index': data.totalPages, display: ''});\n\t\t\treturn 1;\n\t\t} else if ((data.display=='single' && page==view[0]+1) || (data.display=='double' && page==view[0]-2 || page==view[1]+2)) {\n\t\t\tdata.pageWrap[page].css({'z-index': data.totalPages-1, display: ''});\n\t\t\treturn 2;\n\t\t} else {\n\t\t\tdata.pageWrap[page].css({'z-index': 0, display: 'none'});\n\t\t\treturn 0;\n\t\t}\n\t}\n},\n\n// Methods and properties for the flip page effect\n\nflipMethods = {\n\n\t// Constructor\n\n\tinit: function(opts) {\n\n\t\tif (opts.gradients) {\n\t\t\topts.frontGradient = true;\n\t\t\topts.backGradient = true;\n\t\t}\n\n\t\tthis.data({f: {}});\n\t\tthis.flip('options', opts);\n\n\t\tflipMethods._addPageWrapper.call(this);\n\n\t\treturn this;\n\t},\n\n\tsetData: function(d) {\n\t\t\n\t\tvar data = this.data();\n\n\t\tdata.f = $.extend(data.f, d);\n\n\t\treturn this;\n\t},\n\n\toptions: function(opts) {\n\t\t\n\t\tvar data = this.data().f;\n\n\t\tif (opts) {\n\t\t\tflipMethods.setData.call(this, {opts: $.extend({}, data.opts || flipOptions, opts) });\n\t\t\treturn this;\n\t\t} else\n\t\t\treturn data.opts;\n\n\t},\n\n\tz: function(z) {\n\n\t\tvar data = this.data().f;\n\t\tdata.opts['z-index'] = z;\n\t\tdata.fwrapper.css({'z-index': z || parseInt(data.parent.css('z-index'), 10) || 0});\n\n\t\treturn this;\n\t},\n\n\t_cAllowed: function() {\n\n\t\treturn corners[this.data().f.opts.corners] || this.data().f.opts.corners;\n\n\t},\n\n\t_cornerActivated: function(e) {\n\t\tif (e.originalEvent === undefined) {\n\t\t\treturn false;\n\t\t}\t\t\n\n\t\te = (isTouch) ? e.originalEvent.touches : [e];\n\n\t\tvar data = this.data().f,\n\t\t\tpos = data.parent.offset(),\n\t\t\twidth = this.width(),\n\t\t\theight = this.height(),\n\t\t\tc = {x: Math.max(0, e[0].pageX-pos.left), y: Math.max(0, e[0].pageY-pos.top)},\n\t\t\tcsz = data.opts.cornerSize,\n\t\t\tallowedCorners = flipMethods._cAllowed.call(this);\n\n\t\t\tif (c.x<=0 || c.y<=0 || c.x>=width || c.y>=height) return false;\n\n\t\t\tif (c.y<csz) c.corner = 't';\n\t\t\telse if (c.y>=height-csz) c.corner = 'b';\n\t\t\telse return false;\n\t\t\t\n\t\t\tif (c.x<=csz) c.corner+= 'l';\n\t\t\telse if (c.x>=width-csz) c.corner+= 'r';\n\t\t\telse return false;\n\n\t\treturn ($.inArray(c.corner, allowedCorners)==-1) ? false : c;\n\n\t},\n\n\t_c: function(corner, opts) {\n\n\t\topts = opts || 0;\n\t\treturn ({tl: point2D(opts, opts),\n\t\t\t\ttr: point2D(this.width()-opts, opts),\n\t\t\t\tbl: point2D(opts, this.height()-opts),\n\t\t\t\tbr: point2D(this.width()-opts, this.height()-opts)})[corner];\n\n\t},\n\n\t_c2: function(corner) {\n\n\t\treturn {tl: point2D(this.width()*2, 0),\n\t\t\t\ttr: point2D(-this.width(), 0),\n\t\t\t\tbl: point2D(this.width()*2, this.height()),\n\t\t\t\tbr: point2D(-this.width(), this.height())}[corner];\n\n\t},\n\n\t_foldingPage: function(corner) {\n\n\t\tvar opts = this.data().f.opts;\n\t\t\n\t\tif (opts.folding) return opts.folding;\n\t\telse if(opts.turn) {\n\t\t\tvar data = opts.turn.data();\n\t\t\tif (data.display == 'single')\n\t\t\t\treturn (data.pageObjs[opts.next]) ? data.pageObjs[0] : null;\n\t\t\telse\n\t\t\t\treturn data.pageObjs[opts.next];\n\t\t}\n\n\t},\n\n\t_backGradient: function() {\n\n\t\tvar data =\tthis.data().f,\n\t\t\tturn = data.opts.turn,\n\t\t\tgradient = data.opts.backGradient &&\n\t\t\t\t\t\t(!turn || turn.data().display=='single' || (data.opts.page!=2 && data.opts.page!=turn.data().totalPages-1) );\n\n\n\t\tif (gradient && !data.bshadow)\n\t\t\tdata.bshadow = $('<div/>', divAtt(0, 0, 1)).\n\t\t\t\tcss({'position': '', width: this.width(), height: this.height()}).\n\t\t\t\t\tappendTo(data.parent);\n\n\t\treturn gradient;\n\n\t},\n\n\tresize: function(full) {\n\t\t\n\t\tvar data = this.data().f,\n\t\t\twidth = this.width(),\n\t\t\theight = this.height(),\n\t\t\tsize = Math.round(Math.sqrt(Math.pow(width, 2)+Math.pow(height, 2)));\n\n\t\tif (full) {\n\t\t\tdata.wrapper.css({width: size, height: size});\n\t\t\tdata.fwrapper.css({width: size, height: size}).\n\t\t\t\tchildren(':first-child').\n\t\t\t\t\tcss({width: width, height: height});\n\n\t\t\tdata.fpage.css({width: height, height: width});\n\n\t\t\tif (data.opts.frontGradient)\n\t\t\t\tdata.ashadow.css({width: height, height: width});\n\n\t\t\tif (flipMethods._backGradient.call(this))\n\t\t\t\tdata.bshadow.css({width: width, height: height});\n\t\t}\n\n\t\tif (data.parent.is(':visible')) {\n\t\t\tdata.fwrapper.css({top: data.parent.offset().top,\n\t\t\t\tleft: data.parent.offset().left});\n\n\t\t\tif (data.opts.turn)\n\t\t\t\tdata.fparent.css({top: -data.opts.turn.offset().top, left: -data.opts.turn.offset().left});\n\t\t}\n\n\t\tthis.flip('z', data.opts['z-index']);\n\n\t},\n\n\t// Prepares the page by adding a general wrapper and another objects\n\n\t_addPageWrapper: function() {\n\n\t\tvar att,\n\t\t\tdata = this.data().f,\n\t\t\tparent = this.parent();\n\n\t\tif (!data.wrapper) {\n\n\t\t\tvar left = this.css('left'),\n\t\t\t\ttop = this.css('top'),\n\t\t\t\twidth = this.width(),\n\t\t\t\theight = this.height(),\n\t\t\t\tsize = Math.round(Math.sqrt(Math.pow(width, 2)+Math.pow(height, 2)));\n\t\t\t\n\t\t\tdata.parent = parent;\n\t\t\tdata.fparent = (data.opts.turn) ? data.opts.turn.data().fparent : $('#turn-fwrappers');\n\n\t\t\tif (!data.fparent) {\n\t\t\t\tvar fparent = $('<div/>', {css: {'pointer-events': 'none'}}).hide();\n\t\t\t\t\tfparent.data().flips = 0;\n\n\t\t\t\tif (data.opts.turn) {\n\t\t\t\t\tfparent.css(divAtt(-data.opts.turn.offset().top, -data.opts.turn.offset().left, 'auto', 'visible').css).\n\t\t\t\t\t\t\tappendTo(data.opts.turn);\n\t\t\t\t\t\n\t\t\t\t\tdata.opts.turn.data().fparent = fparent;\n\t\t\t\t} else {\n\t\t\t\t\tfparent.css(divAtt(0, 0, 'auto', 'visible').css).\n\t\t\t\t\t\tattr('id', 'turn-fwrappers').\n\t\t\t\t\t\t\tappendTo($('body'));\n\t\t\t\t}\n\n\t\t\t\tdata.fparent = fparent;\n\t\t\t}\n\n\t\t\tthis.css({position: 'absolute', top: 0, left: 0, bottom: 'auto', right: 'auto'});\n\n\t\t\tdata.wrapper = $('<div/>', divAtt(0, 0, this.css('z-index'))).\n\t\t\t\t\t\t\t\tappendTo(parent).\n\t\t\t\t\t\t\t\t\tprepend(this);\n\n\t\t\tdata.fwrapper = $('<div/>', divAtt(parent.offset().top, parent.offset().left)).\n\t\t\t\t\t\t\t\thide().\n\t\t\t\t\t\t\t\t\tappendTo(data.fparent);\n\n\t\t\tdata.fpage = $('<div/>', {css: {cursor: 'default'}}).\n\t\t\t\t\tappendTo($('<div/>', divAtt(0, 0, 0, 'visible')).\n\t\t\t\t\t\t\t\tappendTo(data.fwrapper));\n\n\t\t\tif (data.opts.frontGradient)\n\t\t\t\tdata.ashadow = $('<div/>', divAtt(0, 0,  1)).\n\t\t\t\t\tappendTo(data.fpage);\n\n\t\t\t// Save data\n\n\t\t\tflipMethods.setData.call(this, data);\n\n\t\t\t// Set size\n\t\t\tflipMethods.resize.call(this, true);\n\t\t}\n\n\t},\n\n\t// Takes a 2P point from the screen and applies the transformation\n\n\t_fold: function(point) {\n\n\t\tvar that = this,\n\t\t\ta = 0,\n\t\t\talpha = 0,\n\t\t\tbeta,\n\t\t\tpx,\n\t\t\tgradientEndPointA,\n\t\t\tgradientEndPointB,\n\t\t\tgradientStartV,\n\t\t\tgradientSize,\n\t\t\tgradientOpacity,\n\t\t\tmv = point2D(0, 0),\n\t\t\tdf = point2D(0, 0),\n\t\t\ttr = point2D(0, 0),\n\t\t\twidth = this.width(),\n\t\t\theight = this.height(),\n\t\t\tfolding = flipMethods._foldingPage.call(this),\n\t\t\ttan = Math.tan(alpha),\n\t\t\tdata = this.data().f,\n\t\t\tac = data.opts.acceleration,\n\t\t\th = data.wrapper.height(),\n\t\t\to = flipMethods._c.call(this, point.corner),\n\t\t\ttop = point.corner.substr(0, 1) == 't',\n\t\t\tleft = point.corner.substr(1, 1) == 'l',\n\n\t\t\tcompute = function() {\n\t\t\t\tvar rel = point2D((o.x) ? o.x - point.x : point.x, (o.y) ? o.y - point.y : point.y),\n\t\t\t\t\ttan = (Math.atan2(rel.y, rel.x)),\n\t\t\t\t\tmiddle;\n\n\t\t\t\talpha = A90 - tan;\n\t\t\t\ta = deg(alpha);\n\t\t\t\tmiddle = point2D((left) ? width - rel.x/2 : point.x + rel.x/2, rel.y/2);\n\n\t\t\t\tvar gamma = alpha - Math.atan2(middle.y, middle.x),\n\t\t\t\t\tdistance =  Math.max(0, Math.sin(gamma) * Math.sqrt(Math.pow(middle.x, 2) + Math.pow(middle.y, 2)));\n\n\t\t\t\t\ttr = point2D(distance * Math.sin(alpha), distance * Math.cos(alpha));\n\n\t\t\t\t\tif (alpha > A90) {\n\t\t\t\t\t\n\t\t\t\t\t\ttr.x = tr.x + Math.abs(tr.y * Math.tan(tan));\n\t\t\t\t\t\ttr.y = 0;\n\n\t\t\t\t\t\tif (Math.round(tr.x*Math.tan(PI-alpha)) < height) {\n\n\t\t\t\t\t\t\tpoint.y = Math.sqrt(Math.pow(height, 2)+2 * middle.x * rel.x);\n\t\t\t\t\t\t\tif (top) point.y =  height - point.y;\n\t\t\t\t\t\t\treturn compute();\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\n\t\t\t\tif (alpha>A90) {\n\t\t\t\t\tvar beta = PI-alpha, dd = h - height/Math.sin(beta);\n\t\t\t\t\tmv = point2D(Math.round(dd*Math.cos(beta)), Math.round(dd*Math.sin(beta)));\n\t\t\t\t\tif (left) mv.x = - mv.x;\n\t\t\t\t\tif (top) mv.y = - mv.y;\n\t\t\t\t}\n\n\t\t\t\tpx = Math.round(tr.y/Math.tan(alpha) + tr.x);\n\t\t\t\n\t\t\t\tvar side = width - px,\n\t\t\t\t\tsideX = side*Math.cos(alpha*2),\n\t\t\t\t\tsideY = side*Math.sin(alpha*2);\n\t\t\t\t\tdf = point2D(Math.round( (left ? side -sideX : px+sideX)), Math.round((top) ? sideY : height - sideY));\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t// GRADIENTS\n\n\t\t\t\t\tgradientSize = side*Math.sin(alpha);\n\t\t\t\t\t\tvar endingPoint = flipMethods._c2.call(that, point.corner),\n\t\t\t\t\t\tfar = Math.sqrt(Math.pow(endingPoint.x-point.x, 2)+Math.pow(endingPoint.y-point.y, 2));\n\n\t\t\t\t\tgradientOpacity = (far<width) ? far/width : 1;\n\n\n\t\t\t\tif (data.opts.frontGradient) {\n\n\t\t\t\t\tgradientStartV = gradientSize>100 ? (gradientSize-100)/gradientSize : 0;\n\t\t\t\t\tgradientEndPointA = point2D(gradientSize*Math.sin(A90-alpha)/height*100, gradientSize*Math.cos(A90-alpha)/width*100);\n\t\t\t\t\n\t\t\t\t\tif (top) gradientEndPointA.y = 100-gradientEndPointA.y;\n\t\t\t\t\tif (left) gradientEndPointA.x = 100-gradientEndPointA.x;\n\t\t\t\t}\n\n\t\t\t\tif (flipMethods._backGradient.call(that)) {\n\n\t\t\t\t\tgradientEndPointB = point2D(gradientSize*Math.sin(alpha)/width*100, gradientSize*Math.cos(alpha)/height*100);\n\t\t\t\t\tif (!left) gradientEndPointB.x = 100-gradientEndPointB.x;\n\t\t\t\t\tif (!top) gradientEndPointB.y = 100-gradientEndPointB.y;\n\t\t\t\t}\n\t\t\t\t//\n\n\t\t\t\ttr.x = Math.round(tr.x);\n\t\t\t\ttr.y = Math.round(tr.y);\n\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\ttransform = function(tr, c, x, a) {\n\t\t\t\n\t\t\t\tvar f = ['0', 'auto'], mvW = (width-h)*x[0]/100, mvH = (height-h)*x[1]/100,\n\t\t\t\t\tv = {left: f[c[0]], top: f[c[1]], right: f[c[2]], bottom: f[c[3]]},\n\t\t\t\t\taliasingFk = (a!=90 && a!=-90) ? (left ? -1 : 1) : 0;\n\n\t\t\t\t\tx = x[0] + '% ' + x[1] + '%';\n\n\t\t\t\tthat.css(v).transform(rotate(a) + translate(tr.x + aliasingFk, tr.y, ac), x);\n\n\t\t\t\tdata.fpage.parent().css(v);\n\t\t\t\tdata.wrapper.transform(translate(-tr.x + mvW-aliasingFk, -tr.y + mvH, ac) + rotate(-a), x);\n\n\t\t\t\tdata.fwrapper.transform(translate(-tr.x + mv.x + mvW, -tr.y + mv.y + mvH, ac) + rotate(-a), x);\n\t\t\t\tdata.fpage.parent().transform(rotate(a) + translate(tr.x + df.x - mv.x, tr.y + df.y - mv.y, ac), x);\n\n\t\t\t\tif (data.opts.frontGradient)\n\t\t\t\t\tgradient(data.ashadow,\n\t\t\t\t\t\t\tpoint2D(left?100:0, top?100:0),\n\t\t\t\t\t\t\tpoint2D(gradientEndPointA.x, gradientEndPointA.y),\n\t\t\t\t\t\t\t[[gradientStartV, 'rgba(0,0,0,0)'],\n\t\t\t\t\t\t\t[((1-gradientStartV)*0.8)+gradientStartV, 'rgba(0,0,0,'+(0.2*gradientOpacity)+')'],\n\t\t\t\t\t\t\t[1, 'rgba(255,255,255,'+(0.2*gradientOpacity)+')']],\n\t\t\t\t\t\t\t3,\n\t\t\t\t\t\t\talpha);\n\t\t\n\t\t\t\tif (flipMethods._backGradient.call(that))\n\t\t\t\t\tgradient(data.bshadow,\n\t\t\t\t\t\t\tpoint2D(left?0:100, top?0:100),\n\t\t\t\t\t\t\tpoint2D(gradientEndPointB.x, gradientEndPointB.y),\n\t\t\t\t\t\t\t[[0.8, 'rgba(0,0,0,0)'],\n\t\t\t\t\t\t\t[1, 'rgba(0,0,0,'+(0.3*gradientOpacity)+')'],\n\t\t\t\t\t\t\t[1, 'rgba(0,0,0,0)']],\n\t\t\t\t\t\t\t3);\n\t\t\t\t\n\t\t\t};\n\n\t\tswitch (point.corner) {\n\t\t\tcase 'tl' :\n\t\t\t\tpoint.x = Math.max(point.x, 1);\n\t\t\t\tcompute();\n\t\t\t\ttransform(tr, [1,0,0,1], [100, 0], a);\n\t\t\t\tdata.fpage.transform(translate(-height, -width, ac) + rotate(90-a*2) , '100% 100%');\n\t\t\t\tfolding.transform(rotate(90) + translate(0, -height, ac), '0% 0%');\n\t\t\tbreak;\n\t\t\tcase 'tr' :\n\t\t\t\tpoint.x = Math.min(point.x, width-1);\n\t\t\t\tcompute();\n\t\t\t\ttransform(point2D(-tr.x, tr.y), [0,0,0,1], [0, 0], -a);\n\t\t\t\tdata.fpage.transform(translate(0, -width, ac) + rotate(-90+a*2) , '0% 100%');\n\t\t\t\tfolding.transform(rotate(270) + translate(-width, 0, ac), '0% 0%');\n\t\t\tbreak;\n\t\t\tcase 'bl' :\n\t\t\t\tpoint.x = Math.max(point.x, 1);\n\t\t\t\tcompute();\n\t\t\t\ttransform(point2D(tr.x, -tr.y), [1,1,0,0], [100, 100], -a);\n\t\t\t\tdata.fpage.transform(translate(-height, 0, ac) + rotate(-90+a*2), '100% 0%');\n\t\t\t\tfolding.transform(rotate(270) + translate(-width, 0, ac), '0% 0%');\n\t\t\tbreak;\n\t\t\tcase 'br' :\n\t\t\t\tpoint.x = Math.min(point.x, width-1);\n\t\t\t\tcompute();\n\t\t\t\ttransform(point2D(-tr.x, -tr.y), [0,1,1,0], [0, 100], a);\n\t\t\t\tdata.fpage.transform(rotate(90-a*2), '0% 0%');\n\t\t\t\tfolding.transform(rotate(90) + translate(0, -height, ac), '0% 0%');\n\n\t\t\tbreak;\n\t\t}\n\n\t\tdata.point = point;\n\t\n\t},\n\n\t_moveFoldingPage: function(bool) {\n\n\t\tvar data = this.data().f,\n\t\t\tfolding = flipMethods._foldingPage.call(this);\n\n\t\tif (folding) {\n\t\t\tif (bool) {\n\t\t\t\tif (!data.fpage.children()[data.ashadow? '1' : '0']) {\n\t\t\t\t\tflipMethods.setData.call(this, {backParent: folding.parent()});\n\t\t\t\t\tdata.fpage.prepend(folding);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (data.backParent)\n\t\t\t\t\tdata.backParent.prepend(folding);\n\n\t\t\t}\n\t\t}\n\n\t},\n\n\t_showFoldedPage: function(c, animate) {\n\n\t\tvar folding = flipMethods._foldingPage.call(this),\n\t\t\tdd = this.data(),\n\t\t\tdata = dd.f;\n\n\t\tif (!data.point || data.point.corner!=c.corner) {\n\t\t\tvar event = $.Event('start');\n\t\t\tthis.trigger(event, [data.opts, c.corner]);\n\n\t\t\tif (event.isDefaultPrevented())\n\t\t\t\treturn false;\n\t\t}\n\n\n\t\tif (folding) {\n\n\t\t\tif (animate) {\n\n\t\t\t\tvar that = this, point = (data.point && data.point.corner==c.corner) ? data.point : flipMethods._c.call(this, c.corner, 1);\n\t\t\t\n\t\t\t\tthis.animatef({from: [point.x, point.y], to:[c.x, c.y], duration: 500, frame: function(v) {\n\t\t\t\t\tc.x = Math.round(v[0]);\n\t\t\t\t\tc.y = Math.round(v[1]);\n\t\t\t\t\tflipMethods._fold.call(that, c);\n\t\t\t\t}});\n\n\t\t\t} else\t{\n\n\t\t\t\tflipMethods._fold.call(this, c);\n\t\t\t\tif (dd.effect && !dd.effect.turning)\n\t\t\t\t\tthis.animatef(false);\n\n\t\t\t}\n\n\t\t\tif (!data.fwrapper.is(':visible')) {\n\t\t\t\tdata.fparent.show().data().flips++;\n\t\t\t\tflipMethods._moveFoldingPage.call(this, true);\n\t\t\t\tdata.fwrapper.show();\n\n\t\t\t\tif (data.bshadow)\n\t\t\t\t\tdata.bshadow.show();\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t},\n\n\thide: function() {\n\n\t\tvar data = this.data().f,\n\t\t\tfolding = flipMethods._foldingPage.call(this);\n\n\t\tif ((--data.fparent.data().flips)===0)\n\t\t\tdata.fparent.hide();\n\n\t\tthis.css({left: 0, top: 0, right: 'auto', bottom: 'auto'}).transform('', '0% 100%');\n\n\t\tdata.wrapper.transform('', '0% 100%');\n\n\t\tdata.fwrapper.hide();\n\n\t\tif (data.bshadow)\n\t\t\tdata.bshadow.hide();\n\n\t\tfolding.transform('', '0% 0%');\n\n\t\treturn this;\n\t},\n\n\thideFoldedPage: function(animate) {\n\n\t\tvar data = this.data().f;\n\n\t\tif (!data.point) return;\n\n\t\tvar that = this,\n\t\t\tp1 = data.point,\n\t\t\thide = function() {\n\t\t\t\tdata.point = null;\n\t\t\t\tthat.flip('hide');\n\t\t\t\tthat.trigger('end', [false]);\n\t\t\t};\n\n\t\tif (animate) {\n\t\t\tvar p4 = flipMethods._c.call(this, p1.corner),\n\t\t\t\ttop = (p1.corner.substr(0,1)=='t'),\n\t\t\t\tdelta = (top) ? Math.min(0, p1.y-p4.y)/2 : Math.max(0, p1.y-p4.y)/2,\n\t\t\t\tp2 = point2D(p1.x, p1.y+delta),\n\t\t\t\tp3 = point2D(p4.x, p4.y-delta);\n\t\t\n\t\t\tthis.animatef({\n\t\t\t\tfrom: 0,\n\t\t\t\tto: 1,\n\t\t\t\tframe: function(v) {\n\t\t\t\t\tvar np = bezier(p1, p2, p3, p4, v);\n\t\t\t\t\tp1.x = np.x;\n\t\t\t\t\tp1.y = np.y;\n\t\t\t\t\tflipMethods._fold.call(that, p1);\n\t\t\t\t},\n\t\t\t\tcomplete: hide,\n\t\t\t\tduration: 800,\n\t\t\t\thiding: true\n\t\t\t\t});\n\n\t\t} else {\n\t\t\tthis.animatef(false);\n\t\t\thide();\n\t\t}\n\t},\n\n\tturnPage: function(corner) {\n\n\t\tvar that = this,\n\t\t\tdata = this.data().f;\n\n\t\tcorner = {corner: (data.corner) ? data.corner.corner : corner || flipMethods._cAllowed.call(this)[0]};\n\n\t\tvar p1 = data.point || flipMethods._c.call(this, corner.corner, (data.opts.turn) ? data.opts.turn.data().opts.elevation : 0),\n\t\t\tp4 = flipMethods._c2.call(this, corner.corner);\n\n\t\t\tthis.trigger('flip').\n\t\t\t\tanimatef({\n\t\t\t\t\tfrom: 0,\n\t\t\t\t\tto: 1,\n\t\t\t\t\tframe: function(v) {\n\t\t\t\t\t\tvar np = bezier(p1, p1, p4, p4, v);\n\t\t\t\t\t\tcorner.x = np.x;\n\t\t\t\t\t\tcorner.y = np.y;\n\t\t\t\t\t\tflipMethods._showFoldedPage.call(that, corner);\n\t\t\t\t\t},\n\t\t\t\t\t\n\t\t\t\t\tcomplete: function() {\n\t\t\t\t\t\tthat.trigger('end', [true]);\n\t\t\t\t\t},\n\t\t\t\t\tduration: data.opts.duration,\n\t\t\t\t\tturning: true\n\t\t\t\t});\n\n\t\t\tdata.corner = null;\n\t},\n\n\tmoving: function() {\n\n\t\treturn 'effect' in this.data();\n\t\n\t},\n\n\tisTurning: function() {\n\n\t\treturn this.flip('moving') && this.data().effect.turning;\n\t\n\t},\n\n\t_eventStart: function(e) {\n\n\t\tvar data = this.data().f;\n\n\t\tif (!data.disabled && !this.flip('isTurning')) {\n\t\t\tdata.corner = flipMethods._cornerActivated.call(this, e);\n\t\t\tif (data.corner && flipMethods._foldingPage.call(this, data.corner)) {\n\t\t\t\tflipMethods._moveFoldingPage.call(this, true);\n\t\t\t\tthis.trigger('pressed', [data.point]);\n\t\t\t\treturn false;\n\t\t\t} else\n\t\t\t\tdata.corner = null;\n\t\t}\n\n\t},\n\n\t_eventMove: function(e) {\n\n\t\tvar data = this.data().f;\n\n\t\tif (!data.disabled) {\n\t\t\te = (isTouch) ? e.originalEvent.touches : [e];\n\t\t\n\t\t\tif (data.corner) {\n\n\t\t\t\tvar pos = data.parent.offset();\n\n\t\t\t\tdata.corner.x = e[0].pageX-pos.left;\n\t\t\t\tdata.corner.y = e[0].pageY-pos.top;\n\n\t\t\t\tflipMethods._showFoldedPage.call(this, data.corner);\n\t\t\t\n\t\t\t} else if (!this.data().effect && this.is(':visible')) { // roll over\n\t\t\t\t\n\t\t\t\tvar corner = flipMethods._cornerActivated.call(this, e[0]);\n\t\t\t\tif (corner) {\n\t\t\t\t\tvar origin = flipMethods._c.call(this, corner.corner, data.opts.cornerSize/2);\n\t\t\t\t\tcorner.x = origin.x;\n\t\t\t\t\tcorner.y = origin.y;\n\t\t\t\t\tflipMethods._showFoldedPage.call(this, corner, true);\n\t\t\t\t} else\n\t\t\t\t\tflipMethods.hideFoldedPage.call(this, true);\n\n\t\t\t}\n\t\t}\n\t},\n\n\t_eventEnd: function() {\n\n\t\tvar data = this.data().f;\n\n\t\tif (!data.disabled && data.point) {\n\t\t\tvar event = $.Event('released');\n\t\t\tthis.trigger(event, [data.point]);\n\t\t\tif (!event.isDefaultPrevented())\n\t\t\t\tflipMethods.hideFoldedPage.call(this, true);\n\t\t}\n\n\t\tdata.corner = null;\n\n\t},\n\n\tdisable: function(disable) {\n\n\t\tflipMethods.setData.call(this, {'disabled': disable});\n\t\treturn this;\n\n\t}\n},\n\ncla = function(that, methods, args) {\n\n\tif (!args[0] || typeof(args[0])=='object')\n\t\treturn methods.init.apply(that, args);\n\telse if(methods[args[0]] && args[0].toString().substr(0, 1)!='_')\n\t\treturn methods[args[0]].apply(that, Array.prototype.slice.call(args, 1));\n\telse\n\t\tthrow args[0] + ' is an invalid value';\n};\n\n$.extend($.fn, {\n\n\tflip: function(req, opts) {\n\t\treturn cla(this, flipMethods, arguments);\n\t},\n\n\tturn: function(req) {\n\t\treturn cla(this, turnMethods, arguments);\n\t},\n\n\ttransform: function(transform, origin) {\n\n\t\tvar properties = {};\n\t\t\n\t\tif (origin)\n\t\t\tproperties[vendor+'transform-origin'] = origin;\n\t\t\n\t\tproperties[vendor+'transform'] = transform;\n\t\n\t\treturn this.css(properties);\n\n\t},\n\n\tanimatef: function(point) {\n\n\t\tvar data = this.data();\n\n\t\tif (data.effect)\n\t\t\tclearInterval(data.effect.handle);\n\n\t\tif (point) {\n\n\t\t\tif (!point.to.length) point.to = [point.to];\n\t\t\tif (!point.from.length) point.from = [point.from];\n\t\t\tif (!point.easing) point.easing = function (x, t, b, c, data) { return c * Math.sqrt(1 - (t=t/data-1)*t) + b; };\n\n\t\t\tvar j, diff = [],\n\t\t\t\tlen = point.to.length,\n\t\t\t\tthat = this,\n\t\t\t\tfps = point.fps || 30,\n\t\t\t\ttime = - fps,\n\t\t\t\tf = function() {\n\t\t\t\t\tvar j, v = [];\n\t\t\t\t\ttime = Math.min(point.duration, time + fps);\n\t\n\t\t\t\t\tfor (j = 0; j < len; j++)\n\t\t\t\t\t\tv.push(point.easing(1, time, point.from[j], diff[j], point.duration));\n\n\t\t\t\t\tpoint.frame((len==1) ? v[0] : v);\n\n\t\t\t\t\tif (time==point.duration) {\n\t\t\t\t\t\tclearInterval(data.effect.handle);\n\t\t\t\t\t\tdelete data['effect'];\n\t\t\t\t\t\tthat.data(data);\n\t\t\t\t\t\tif (point.complete)\n\t\t\t\t\t\t\tpoint.complete();\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\tfor (j = 0; j < len; j++)\n\t\t\t\tdiff.push(point.to[j] - point.from[j]);\n\n\t\t\tdata.effect = point;\n\t\t\tdata.effect.handle = setInterval(f, fps);\n\t\t\tthis.data(data);\n\t\t\tf();\n\t\t} else {\n\t\t\tdelete data['effect'];\n\t\t}\n\t}\n});\n\n\n$.isTouch = isTouch;\n\n})(jQuery);"
  }
]