// JavaScript Document // this is used for any GLOBAL javascript. In most cases, things should NOT be added here. function unsetNoJavascript () { // remove default state if we have JS: $('body').removeClass('noJavascript'); } /*! * Copyright (c) 2009 Simo Kinnunen. * Licensed under the MIT license. * * @version ${Version} */ var Cufon = (function() { var api = function() { return api.replace.apply(null, arguments); }; var DOM = api.DOM = { ready: (function() { var complete = false, readyStatus = { loaded: 1, complete: 1 }; var queue = [], perform = function() { if (complete) return; complete = true; for (var fn; fn = queue.shift(); fn()); }; // Gecko, Opera, WebKit r26101+ if (document.addEventListener) { document.addEventListener('DOMContentLoaded', perform, false); window.addEventListener('pageshow', perform, false); // For cached Gecko pages } // Old WebKit, Internet Explorer if (!window.opera && document.readyState) (function() { readyStatus[document.readyState] ? perform() : setTimeout(arguments.callee, 10); })(); // Internet Explorer if (document.readyState && document.createStyleSheet) (function() { try { document.body.doScroll('left'); perform(); } catch (e) { setTimeout(arguments.callee, 1); } })(); addEvent(window, 'load', perform); // Fallback return function(listener) { if (!arguments.length) perform(); else complete ? listener() : queue.push(listener); }; })(), root: function() { return document.documentElement || document.body; } }; var CSS = api.CSS = { Size: function(value, base) { this.value = parseFloat(value); this.unit = String(value).match(/[a-z%]*$/)[0] || 'px'; this.convert = function(value) { return value / base * this.value; }; this.convertFrom = function(value) { return value / this.value * base; }; this.toString = function() { return this.value + this.unit; }; }, addClass: function(el, className) { var current = el.className; el.className = current + (current && ' ') + className; return el; }, color: cached(function(value) { var parsed = {}; parsed.color = value.replace(/^rgba\((.*?),\s*([\d.]+)\)/, function($0, $1, $2) { parsed.opacity = parseFloat($2); return 'rgb(' + $1 + ')'; }); return parsed; }), // has no direct CSS equivalent. // @see http://msdn.microsoft.com/en-us/library/system.windows.fontstretches.aspx fontStretch: cached(function(value) { if (typeof value == 'number') return value; if (/%$/.test(value)) return parseFloat(value) / 100; return { 'ultra-condensed': 0.5, 'extra-condensed': 0.625, condensed: 0.75, 'semi-condensed': 0.875, 'semi-expanded': 1.125, expanded: 1.25, 'extra-expanded': 1.5, 'ultra-expanded': 2 }[value] || 1; }), getStyle: function(el) { var view = document.defaultView; if (view && view.getComputedStyle) return new Style(view.getComputedStyle(el, null)); if (el.currentStyle) return new Style(el.currentStyle); return new Style(el.style); }, gradient: cached(function(value) { var gradient = { id: value, type: value.match(/^-([a-z]+)-gradient\(/)[1], stops: [] }, colors = value.substr(value.indexOf('(')).match(/([\d.]+=)?(#[a-f0-9]+|[a-z]+\(.*?\)|[a-z]+)/ig); for (var i = 0, l = colors.length, stop; i < l; ++i) { stop = colors[i].split('=', 2).reverse(); gradient.stops.push([ stop[1] || i / (l - 1), stop[0] ]); } return gradient; }), quotedList: cached(function(value) { // doesn't work properly with empty quoted strings (""), but // it's not worth the extra code. var list = [], re = /\s*((["'])([\s\S]*?[^\\])\2|[^,]+)\s*/g, match; while (match = re.exec(value)) list.push(match[3] || match[1]); return list; }), recognizesMedia: cached(function(media) { var el = document.createElement('style'), sheet, container, supported; el.type = 'text/css'; el.media = media; try { // this is cached anyway el.appendChild(document.createTextNode('/**/')); } catch (e) {} container = elementsByTagName('head')[0]; container.insertBefore(el, container.firstChild); sheet = (el.sheet || el.styleSheet); supported = sheet && !sheet.disabled; container.removeChild(el); return supported; }), removeClass: function(el, className) { var re = RegExp('(?:^|\\s+)' + className + '(?=\\s|$)', 'g'); el.className = el.className.replace(re, ''); return el; }, supports: function(property, value) { var checker = document.createElement('span').style; if (checker[property] === undefined) return false; checker[property] = value; return checker[property] === value; }, textAlign: function(word, style, position, wordCount) { if (style.get('textAlign') == 'right') { if (position > 0) word = ' ' + word; } else if (position < wordCount - 1) word += ' '; return word; }, textShadow: cached(function(value) { if (value == 'none') return null; var shadows = [], currentShadow = {}, result, offCount = 0; var re = /(#[a-f0-9]+|[a-z]+\(.*?\)|[a-z]+)|(-?[\d.]+[a-z%]*)|,/ig; while (result = re.exec(value)) { if (result[0] == ',') { shadows.push(currentShadow); currentShadow = {}; offCount = 0; } else if (result[1]) { currentShadow.color = result[1]; } else { currentShadow[[ 'offX', 'offY', 'blur' ][offCount++]] = result[2]; } } shadows.push(currentShadow); return shadows; }), textTransform: (function() { var map = { uppercase: function(s) { return s.toUpperCase(); }, lowercase: function(s) { return s.toLowerCase(); }, capitalize: function(s) { return s.replace(/\b./g, function($0) { return $0.toUpperCase(); }); } }; return function(text, style) { var transform = map[style.get('textTransform')]; return transform ? transform(text) : text; }; })(), whiteSpace: (function() { var ignore = { inline: 1, 'inline-block': 1, 'run-in': 1 }; var wsStart = /^\s+/, wsEnd = /\s+$/; return function(text, style, node, previousElement) { if (previousElement) { if (previousElement.nodeName.toLowerCase() == 'br') { text = text.replace(wsStart, ''); } } if (ignore[style.get('display')]) return text; if (!node.previousSibling) text = text.replace(wsStart, ''); if (!node.nextSibling) text = text.replace(wsEnd, ''); return text; }; })() }; CSS.ready = (function() { // don't do anything in Safari 2 (it doesn't recognize any media type) var complete = !CSS.recognizesMedia('all'), hasLayout = false; var queue = [], perform = function() { complete = true; for (var fn; fn = queue.shift(); fn()); }; var links = elementsByTagName('link'), styles = elementsByTagName('style'); function isContainerReady(el) { return el.disabled || isSheetReady(el.sheet, el.media || 'screen'); } function isSheetReady(sheet, media) { // in Opera sheet.disabled is true when it's still loading, // even though link.disabled is false. they stay in sync if // set manually. if (!CSS.recognizesMedia(media || 'all')) return true; if (!sheet || sheet.disabled) return false; try { var rules = sheet.cssRules, rule; if (rules) { // needed for Safari 3 and Chrome 1.0. // in standards-conforming browsers cssRules contains @-rules. // Chrome 1.0 weirdness: rules[] // returns the last rule, so a for loop is the only option. search: for (var i = 0, l = rules.length; rule = rules[i], i < l; ++i) { switch (rule.type) { case 2: // @charset break; case 3: // @import if (!isSheetReady(rule.styleSheet, rule.media.mediaText)) return false; break; default: // only @charset can precede @import break search; } } } } catch (e) {} // probably a style sheet from another domain return true; } function allStylesLoaded() { // Internet Explorer's style sheet model, there's no need to do anything if (document.createStyleSheet) return true; // standards-compliant browsers var el, i; for (i = 0; el = links[i]; ++i) { if (el.rel.toLowerCase() == 'stylesheet' && !isContainerReady(el)) return false; } for (i = 0; el = styles[i]; ++i) { if (!isContainerReady(el)) return false; } return true; } DOM.ready(function() { // getComputedStyle returns null in Gecko if used in an iframe with display: none if (!hasLayout) hasLayout = CSS.getStyle(document.body).isUsable(); if (complete || (hasLayout && allStylesLoaded())) perform(); else setTimeout(arguments.callee, 10); }); return function(listener) { if (complete) listener(); else queue.push(listener); }; })(); function Font(data) { var face = this.face = data.face, wordSeparators = { '\u0020': 1, '\u00a0': 1, '\u3000': 1 }; this.glyphs = data.glyphs; this.w = data.w; this.baseSize = parseInt(face['units-per-em'], 10); this.family = face['font-family'].toLowerCase(); this.weight = face['font-weight']; this.style = face['font-style'] || 'normal'; this.viewBox = (function () { var parts = face.bbox.split(/\s+/); var box = { minX: parseInt(parts[0], 10), minY: parseInt(parts[1], 10), maxX: parseInt(parts[2], 10), maxY: parseInt(parts[3], 10) }; box.width = box.maxX - box.minX; box.height = box.maxY - box.minY; box.toString = function() { return [ this.minX, this.minY, this.width, this.height ].join(' '); }; return box; })(); this.ascent = -parseInt(face.ascent, 10); this.descent = -parseInt(face.descent, 10); this.height = -this.ascent + this.descent; this.spacing = function(chars, letterSpacing, wordSpacing) { var glyphs = this.glyphs, glyph, kerning, k, jumps = [], width = 0, w, i = -1, j = -1, chr; while (chr = chars[++i]) { glyph = glyphs[chr] || this.missingGlyph; if (!glyph) continue; if (kerning) { width -= k = kerning[chr] || 0; jumps[j] -= k; } w = glyph.w; if (isNaN(w)) w = +this.w; // may have been a String in old fonts w += letterSpacing; if (wordSeparators[chr]) w += wordSpacing; width += jumps[++j] = ~~w; // get rid of decimals kerning = glyph.k; } jumps.total = width; return jumps; }; } function FontFamily() { var styles = {}, mapping = { oblique: 'italic', italic: 'oblique' }; this.add = function(font) { (styles[font.style] || (styles[font.style] = {}))[font.weight] = font; }; this.get = function(style, weight) { var weights = styles[style] || styles[mapping[style]] || styles.normal || styles.italic || styles.oblique; if (!weights) return null; // we don't have to worry about "bolder" and "lighter" // because IE's currentStyle returns a numeric value for it, // and other browsers use the computed value anyway weight = { normal: 400, bold: 700 }[weight] || parseInt(weight, 10); if (weights[weight]) return weights[weight]; // http://www.w3.org/TR/CSS21/fonts.html#propdef-font-weight // Gecko uses x99/x01 for lighter/bolder var up = { 1: 1, 99: 0 }[weight % 100], alts = [], min, max; if (up === undefined) up = weight > 400; if (weight == 500) weight = 400; for (var alt in weights) { if (!hasOwnProperty(weights, alt)) continue; alt = parseInt(alt, 10); if (!min || alt < min) min = alt; if (!max || alt > max) max = alt; alts.push(alt); } if (weight < min) weight = min; if (weight > max) weight = max; alts.sort(function(a, b) { return (up ? (a >= weight && b >= weight) ? a < b : a > b : (a <= weight && b <= weight) ? a > b : a < b) ? -1 : 1; }); return weights[alts[0]]; }; } function HoverHandler() { function contains(node, anotherNode) { if (node.contains) return node.contains(anotherNode); return node.compareDocumentPosition(anotherNode) & 16; } function onOverOut(e) { var related = e.relatedTarget; if (!related || contains(this, related)) return; trigger(this, e.type == 'mouseover'); } function onEnterLeave(e) { trigger(this, e.type == 'mouseenter'); } function trigger(el, hoverState) { // A timeout is needed so that the event can actually "happen" // before replace is triggered. This ensures that styles are up // to date. setTimeout(function() { var options = sharedStorage.get(el).options; api.replace(el, hoverState ? merge(options, options.hover) : options, true); }, 10); } this.attach = function(el) { if (el.onmouseenter === undefined) { addEvent(el, 'mouseover', onOverOut); addEvent(el, 'mouseout', onOverOut); } else { addEvent(el, 'mouseenter', onEnterLeave); addEvent(el, 'mouseleave', onEnterLeave); } }; } function ReplaceHistory() { var list = [], map = {}; function filter(keys) { var values = [], key; for (var i = 0; key = keys[i]; ++i) values[i] = list[map[key]]; return values; } this.add = function(key, args) { map[key] = list.push(args) - 1; }; this.repeat = function() { var snapshot = arguments.length ? filter(arguments) : list, args; for (var i = 0; args = snapshot[i++];) api.replace(args[0], args[1], true); }; } function Storage() { var map = {}, at = 0; function identify(el) { return el.cufid || (el.cufid = ++at); } this.get = function(el) { var id = identify(el); return map[id] || (map[id] = {}); }; } function Style(style) { var custom = {}, sizes = {}; this.extend = function(styles) { for (var property in styles) { if (hasOwnProperty(styles, property)) custom[property] = styles[property]; } return this; }; this.get = function(property) { return custom[property] != undefined ? custom[property] : style[property]; }; this.getSize = function(property, base) { return sizes[property] || (sizes[property] = new CSS.Size(this.get(property), base)); }; this.isUsable = function() { return !!style; }; } function addEvent(el, type, listener) { if (el.addEventListener) { el.addEventListener(type, listener, false); } else if (el.attachEvent) { el.attachEvent('on' + type, function() { return listener.call(el, window.event); }); } } function attach(el, options) { var storage = sharedStorage.get(el); if (storage.options) return el; if (options.hover && options.hoverables[el.nodeName.toLowerCase()]) { hoverHandler.attach(el); } storage.options = options; return el; } function cached(fun) { var cache = {}; return function(key) { if (!hasOwnProperty(cache, key)) cache[key] = fun.apply(null, arguments); return cache[key]; }; } function getFont(el, style) { var families = CSS.quotedList(style.get('fontFamily').toLowerCase()), family; for (var i = 0; family = families[i]; ++i) { if (fonts[family]) return fonts[family].get(style.get('fontStyle'), style.get('fontWeight')); } return null; } function elementsByTagName(query) { return document.getElementsByTagName(query); } function hasOwnProperty(obj, property) { return obj.hasOwnProperty(property); } function merge() { var merged = {}, arg, key; for (var i = 0, l = arguments.length; arg = arguments[i], i < l; ++i) { for (key in arg) { if (hasOwnProperty(arg, key)) merged[key] = arg[key]; } } return merged; } function process(font, text, style, options, node, el) { var fragment = document.createDocumentFragment(), processed; if (text === '') return fragment; var separate = options.separate; var parts = text.split(separators[separate]), needsAligning = (separate == 'words'); if (needsAligning && HAS_BROKEN_REGEXP) { // @todo figure out a better way to do this if (/^\s/.test(text)) parts.unshift(''); if (/\s$/.test(text)) parts.push(''); } for (var i = 0, l = parts.length; i < l; ++i) { processed = engines[options.engine](font, needsAligning ? CSS.textAlign(parts[i], style, i, l) : parts[i], style, options, node, el, i < l - 1); if (processed) fragment.appendChild(processed); } return fragment; } function replaceElement(el, options) { var name = el.nodeName.toLowerCase(); if (options.ignore[name]) return; var replace = !options.textless[name]; var style = CSS.getStyle(attach(el, options)).extend(options); var font = getFont(el, style), node, type, next, anchor, text, lastElement; if (!font) return; for (node = el.firstChild; node; node = next) { type = node.nodeType; next = node.nextSibling; if (replace && type == 3) { // Node.normalize() is broken in IE 6, 7, 8 if (anchor) { anchor.appendData(node.data); el.removeChild(node); } else anchor = node; if (next) continue; } if (anchor) { el.replaceChild(process(font, CSS.whiteSpace(anchor.data, style, anchor, lastElement), style, options, node, el), anchor); anchor = null; } if (type == 1) { if (node.firstChild) { if (node.nodeName.toLowerCase() == 'cufon') { engines[options.engine](font, null, style, options, node, el); } else arguments.callee(node, options); } lastElement = node; } } } var HAS_BROKEN_REGEXP = ' '.split(/\s+/).length == 0; var sharedStorage = new Storage(); var hoverHandler = new HoverHandler(); var replaceHistory = new ReplaceHistory(); var initialized = false; var engines = {}, fonts = {}, defaultOptions = { autoDetect: false, engine: null, //fontScale: 1, //fontScaling: false, forceHitArea: false, hover: false, hoverables: { a: true }, ignore: { applet: 1, canvas: 1, col: 1, colgroup: 1, head: 1, iframe: 1, map: 1, noscript: 1, optgroup: 1, option: 1, script: 1, select: 1, style: 1, textarea: 1, title: 1, pre: 1 }, printable: true, //rotation: 0, //selectable: false, selector: ( window.Sizzle || (window.jQuery && function(query) { return jQuery(query); }) // avoid noConflict issues || (window.dojo && dojo.query) || (window.Ext && Ext.query) || (window.YAHOO && YAHOO.util && YAHOO.util.Selector && YAHOO.util.Selector.query) || (window.$$ && function(query) { return $$(query); }) || (window.$ && function(query) { return $(query); }) || (document.querySelectorAll && function(query) { return document.querySelectorAll(query); }) || elementsByTagName ), separate: 'words', // 'none' and 'characters' are also accepted textless: { dl: 1, html: 1, ol: 1, table: 1, tbody: 1, thead: 1, tfoot: 1, tr: 1, ul: 1 }, textShadow: 'none' }; var separators = { // The first pattern may cause unicode characters above // code point 255 to be removed in Safari 3.0. Luckily enough // Safari 3.0 does not include non-breaking spaces in \s, so // we can just use a simple alternative pattern. words: /\s/.test('\u00a0') ? /[^\S\u00a0]+/ : /\s+/, characters: '', none: /^/ }; api.now = function() { DOM.ready(); return api; }; api.refresh = function() { replaceHistory.repeat.apply(replaceHistory, arguments); return api; }; api.registerEngine = function(id, engine) { if (!engine) return api; engines[id] = engine; return api.set('engine', id); }; api.registerFont = function(data) { if (!data) return api; var font = new Font(data), family = font.family; if (!fonts[family]) fonts[family] = new FontFamily(); fonts[family].add(font); return api.set('fontFamily', '"' + family + '"'); }; api.replace = function(elements, options, ignoreHistory) { options = merge(defaultOptions, options); if (!options.engine) return api; // there's no browser support so we'll just stop here if (!initialized) { CSS.addClass(DOM.root(), 'cufon-active cufon-loading'); CSS.ready(function() { // fires before any replace() calls, but it doesn't really matter CSS.addClass(CSS.removeClass(DOM.root(), 'cufon-loading'), 'cufon-ready'); }); initialized = true; } if (options.hover) options.forceHitArea = true; if (options.autoDetect) delete options.fontFamily; if (typeof options.textShadow == 'string') { options.textShadow = CSS.textShadow(options.textShadow); } if (typeof options.color == 'string' && /^-/.test(options.color)) { options.textGradient = CSS.gradient(options.color); } else delete options.textGradient; if (!ignoreHistory) replaceHistory.add(elements, arguments); if (elements.nodeType || typeof elements == 'string') elements = [ elements ]; CSS.ready(function() { for (var i = 0, l = elements.length; i < l; ++i) { var el = elements[i]; if (typeof el == 'string') api.replace(options.selector(el), options, true); else replaceElement(el, options); } }); return api; }; api.set = function(option, value) { defaultOptions[option] = value; return api; }; return api; })(); Cufon.registerEngine('canvas', (function() { // Safari 2 doesn't support .apply() on native methods var check = document.createElement('canvas'); if (!check || !check.getContext || !check.getContext.apply) return; check = null; var HAS_INLINE_BLOCK = Cufon.CSS.supports('display', 'inline-block'); // Firefox 2 w/ non-strict doctype (almost standards mode) var HAS_BROKEN_LINEHEIGHT = !HAS_INLINE_BLOCK && (document.compatMode == 'BackCompat' || /frameset|transitional/i.test(document.doctype.publicId)); var styleSheet = document.createElement('style'); styleSheet.type = 'text/css'; styleSheet.appendChild(document.createTextNode(( 'cufon{text-indent:0;}' + '@media screen,projection{' + 'cufon{display:inline;display:inline-block;position:relative;vertical-align:middle;' + (HAS_BROKEN_LINEHEIGHT ? '' : 'font-size:1px;line-height:1px;') + '}cufon cufontext{display:-moz-inline-box;display:inline-block;width:0;height:0;overflow:hidden;text-indent:-10000in;}' + (HAS_INLINE_BLOCK ? 'cufon canvas{position:relative;}' : 'cufon canvas{position:absolute;}') + '}' + '@media print{' + 'cufon{padding:0;}' + // Firefox 2 'cufon canvas{display:none;}' + '}' ).replace(/;/g, '!important;'))); document.getElementsByTagName('head')[0].appendChild(styleSheet); function generateFromVML(path, context) { var atX = 0, atY = 0; var code = [], re = /([mrvxe])([^a-z]*)/g, match; generate: for (var i = 0; match = re.exec(path); ++i) { var c = match[2].split(','); switch (match[1]) { case 'v': code[i] = { m: 'bezierCurveTo', a: [ atX + ~~c[0], atY + ~~c[1], atX + ~~c[2], atY + ~~c[3], atX += ~~c[4], atY += ~~c[5] ] }; break; case 'r': code[i] = { m: 'lineTo', a: [ atX += ~~c[0], atY += ~~c[1] ] }; break; case 'm': code[i] = { m: 'moveTo', a: [ atX = ~~c[0], atY = ~~c[1] ] }; break; case 'x': code[i] = { m: 'closePath' }; break; case 'e': break generate; } context[code[i].m].apply(context, code[i].a); } return code; } function interpret(code, context) { for (var i = 0, l = code.length; i < l; ++i) { var line = code[i]; context[line.m].apply(context, line.a); } } return function(font, text, style, options, node, el) { var redraw = (text === null); if (redraw) text = node.getAttribute('alt'); var viewBox = font.viewBox; var size = style.getSize('fontSize', font.baseSize); var expandTop = 0, expandRight = 0, expandBottom = 0, expandLeft = 0; var shadows = options.textShadow, shadowOffsets = []; if (shadows) { for (var i = shadows.length; i--;) { var shadow = shadows[i]; var x = size.convertFrom(parseFloat(shadow.offX)); var y = size.convertFrom(parseFloat(shadow.offY)); shadowOffsets[i] = [ x, y ]; if (y < expandTop) expandTop = y; if (x > expandRight) expandRight = x; if (y > expandBottom) expandBottom = y; if (x < expandLeft) expandLeft = x; } } var chars = Cufon.CSS.textTransform(text, style).split(''); var jumps = font.spacing(chars, ~~size.convertFrom(parseFloat(style.get('letterSpacing')) || 0), ~~size.convertFrom(parseFloat(style.get('wordSpacing')) || 0) ); if (!jumps.length) return null; // there's nothing to render var width = jumps.total; expandRight += viewBox.width - jumps[jumps.length - 1]; expandLeft += viewBox.minX; var wrapper, canvas; if (redraw) { wrapper = node; canvas = node.firstChild; } else { wrapper = document.createElement('cufon'); wrapper.className = 'cufon cufon-canvas'; wrapper.setAttribute('alt', text); canvas = document.createElement('canvas'); wrapper.appendChild(canvas); if (options.printable) { var print = document.createElement('cufontext'); print.appendChild(document.createTextNode(text)); wrapper.appendChild(print); } } var wStyle = wrapper.style; var cStyle = canvas.style; var height = size.convert(viewBox.height); var roundedHeight = Math.ceil(height); var roundingFactor = roundedHeight / height; var stretchFactor = roundingFactor * Cufon.CSS.fontStretch(style.get('fontStretch')); var stretchedWidth = width * stretchFactor; var canvasWidth = Math.ceil(size.convert(stretchedWidth + expandRight - expandLeft)); var canvasHeight = Math.ceil(size.convert(viewBox.height - expandTop + expandBottom)); canvas.width = canvasWidth; canvas.height = canvasHeight; // needed for WebKit and full page zoom cStyle.width = canvasWidth + 'px'; cStyle.height = canvasHeight + 'px'; // minY has no part in canvas.height expandTop += viewBox.minY; cStyle.top = Math.round(size.convert(expandTop - font.ascent)) + 'px'; cStyle.left = Math.round(size.convert(expandLeft)) + 'px'; var wrapperWidth = Math.max(Math.ceil(size.convert(stretchedWidth)), 0) + 'px'; if (HAS_INLINE_BLOCK) { wStyle.width = wrapperWidth; wStyle.height = size.convert(font.height) + 'px'; } else { wStyle.paddingLeft = wrapperWidth; wStyle.paddingBottom = (size.convert(font.height) - 1) + 'px'; } var g = canvas.getContext('2d'), scale = height / viewBox.height; // proper horizontal scaling is performed later g.scale(scale, scale * roundingFactor); g.translate(-expandLeft, -expandTop); g.save(); function renderText() { var glyphs = font.glyphs, glyph, i = -1, j = -1, chr; g.scale(stretchFactor, 1); while (chr = chars[++i]) { var glyph = glyphs[chars[i]] || font.missingGlyph; if (!glyph) continue; if (glyph.d) { g.beginPath(); if (glyph.code) interpret(glyph.code, g); else glyph.code = generateFromVML('m' + glyph.d, g); g.fill(); } g.translate(jumps[++j], 0); } g.restore(); } if (shadows) { for (var i = shadows.length; i--;) { var shadow = shadows[i]; g.save(); g.fillStyle = shadow.color; g.translate.apply(g, shadowOffsets[i]); renderText(); } } var gradient = options.textGradient; if (gradient) { var stops = gradient.stops, fill = g.createLinearGradient(0, viewBox.minY, 0, viewBox.maxY); for (var i = 0, l = stops.length; i < l; ++i) { fill.addColorStop.apply(fill, stops[i]); } g.fillStyle = fill; } else g.fillStyle = style.get('color'); renderText(); return wrapper; }; })()); Cufon.registerEngine('vml', (function() { var ns = document.namespaces; if (!ns) return; ns.add('cvml', 'urn:schemas-microsoft-com:vml'); ns = null; var check = document.createElement('cvml:shape'); check.style.behavior = 'url(#default#VML)'; if (!check.coordsize) return; // VML isn't supported check = null; var HAS_BROKEN_LINEHEIGHT = (document.documentMode || 0) < 8; document.write(('').replace(/;/g, '!important;')); function getFontSizeInPixels(el, value) { return getSizeInPixels(el, /(?:em|ex|%)$|^[a-z-]+$/i.test(value) ? '1em' : value); } // Original by Dead Edwards. // Combined with getFontSizeInPixels it also works with relative units. function getSizeInPixels(el, value) { if (value === '0') return 0; if (/px$/i.test(value)) return parseFloat(value); var style = el.style.left, runtimeStyle = el.runtimeStyle.left; el.runtimeStyle.left = el.currentStyle.left; el.style.left = value.replace('%', 'em'); var result = el.style.pixelLeft; el.style.left = style; el.runtimeStyle.left = runtimeStyle; return result; } function getSpacingValue(el, style, size, property) { var key = 'computed' + property, value = style[key]; if (isNaN(value)) { value = style.get(property); style[key] = value = (value == 'normal') ? 0 : ~~size.convertFrom(getSizeInPixels(el, value)); } return value; } var fills = {}; function gradientFill(gradient) { var id = gradient.id; if (!fills[id]) { var stops = gradient.stops, fill = document.createElement('cvml:fill'), colors = []; fill.type = 'gradient'; fill.angle = 180; fill.focus = '0'; fill.method = 'sigma'; fill.color = stops[0][1]; for (var j = 1, k = stops.length - 1; j < k; ++j) { colors.push(stops[j][0] * 100 + '% ' + stops[j][1]); } fill.colors = colors.join(','); fill.color2 = stops[k][1]; fills[id] = fill; } return fills[id]; } return function(font, text, style, options, node, el, hasNext) { var redraw = (text === null); if (redraw) text = node.alt; var viewBox = font.viewBox; var size = style.computedFontSize || (style.computedFontSize = new Cufon.CSS.Size(getFontSizeInPixels(el, style.get('fontSize')) + 'px', font.baseSize)); var wrapper, canvas; if (redraw) { wrapper = node; canvas = node.firstChild; } else { wrapper = document.createElement('cufon'); wrapper.className = 'cufon cufon-vml'; wrapper.alt = text; canvas = document.createElement('cufoncanvas'); wrapper.appendChild(canvas); if (options.printable) { var print = document.createElement('cufontext'); print.appendChild(document.createTextNode(text)); wrapper.appendChild(print); } // ie6, for some reason, has trouble rendering the last VML element in the document. // we can work around this by injecting a dummy element where needed. // @todo find a better solution if (!hasNext) wrapper.appendChild(document.createElement('cvml:shape')); } var wStyle = wrapper.style; var cStyle = canvas.style; var height = size.convert(viewBox.height), roundedHeight = Math.ceil(height); var roundingFactor = roundedHeight / height; var stretchFactor = roundingFactor * Cufon.CSS.fontStretch(style.get('fontStretch')); var minX = viewBox.minX, minY = viewBox.minY; cStyle.height = roundedHeight; cStyle.top = Math.round(size.convert(minY - font.ascent)); cStyle.left = Math.round(size.convert(minX)); wStyle.height = size.convert(font.height) + 'px'; var color = style.get('color'); var chars = Cufon.CSS.textTransform(text, style).split(''); var jumps = font.spacing(chars, getSpacingValue(el, style, size, 'letterSpacing'), getSpacingValue(el, style, size, 'wordSpacing') ); if (!jumps.length) return null; var width = jumps.total; var fullWidth = -minX + width + (viewBox.width - jumps[jumps.length - 1]); var shapeWidth = size.convert(fullWidth * stretchFactor), roundedShapeWidth = Math.round(shapeWidth); var coordSize = fullWidth + ',' + viewBox.height, coordOrigin; var stretch = 'r' + coordSize + 'ns'; var fill = options.textGradient && gradientFill(options.textGradient); var glyphs = font.glyphs, offsetX = 0; var shadows = options.textShadow; var i = -1, j = 0, chr; while (chr = chars[++i]) { var glyph = glyphs[chars[i]] || font.missingGlyph, shape; if (!glyph) continue; if (redraw) { // some glyphs may be missing so we can't use i shape = canvas.childNodes[j]; while (shape.firstChild) shape.removeChild(shape.firstChild); // shadow, fill } else { shape = document.createElement('cvml:shape'); canvas.appendChild(shape); } shape.stroked = 'f'; shape.coordsize = coordSize; shape.coordorigin = coordOrigin = (minX - offsetX) + ',' + minY; shape.path = (glyph.d ? 'm' + glyph.d + 'xe' : '') + 'm' + coordOrigin + stretch; shape.fillcolor = color; if (fill) shape.appendChild(fill.cloneNode(false)); // it's important to not set top/left or IE8 will grind to a halt var sStyle = shape.style; sStyle.width = roundedShapeWidth; sStyle.height = roundedHeight; if (shadows) { // due to the limitations of the VML shadow element there // can only be two visible shadows. opacity is shared // for all shadows. var shadow1 = shadows[0], shadow2 = shadows[1]; var color1 = Cufon.CSS.color(shadow1.color), color2; var shadow = document.createElement('cvml:shadow'); shadow.on = 't'; shadow.color = color1.color; shadow.offset = shadow1.offX + ',' + shadow1.offY; if (shadow2) { color2 = Cufon.CSS.color(shadow2.color); shadow.type = 'double'; shadow.color2 = color2.color; shadow.offset2 = shadow2.offX + ',' + shadow2.offY; } shadow.opacity = color1.opacity || (color2 && color2.opacity) || 1; shape.appendChild(shadow); } offsetX += jumps[j++]; } // addresses flickering issues on :hover var cover = shape.nextSibling, coverFill, vStyle; if (options.forceHitArea) { if (!cover) { cover = document.createElement('cvml:rect'); cover.stroked = 'f'; cover.className = 'cufon-vml-cover'; coverFill = document.createElement('cvml:fill'); coverFill.opacity = 0; cover.appendChild(coverFill); canvas.appendChild(cover); } vStyle = cover.style; vStyle.width = roundedShapeWidth; vStyle.height = roundedHeight; } else if (cover) canvas.removeChild(cover); wStyle.width = Math.max(Math.ceil(size.convert(width * stretchFactor)), 0); if (HAS_BROKEN_LINEHEIGHT) { var yAdjust = style.computedYAdjust; if (yAdjust === undefined) { var lineHeight = style.get('lineHeight'); if (lineHeight == 'normal') lineHeight = '1em'; else if (!isNaN(lineHeight)) lineHeight += 'em'; // no unit style.computedYAdjust = yAdjust = 0.5 * (getSizeInPixels(el, lineHeight) - parseFloat(wStyle.height)); } if (yAdjust) { wStyle.marginTop = Math.ceil(yAdjust) + 'px'; wStyle.marginBottom = yAdjust + 'px'; } } return wrapper; }; })()); /*! * The following copyright notice may not be removed under any circumstances. * * Copyright: * © 2006 Microsoft Corporation. All Rights Reserved. * * Trademark: * Georgia is either a registered trademark or a trademark of Microsoft * Corporation in the United States and/or other countries. * * Manufacturer: * Carter & Cone * * Designer: * Matthew Carter * * License information: * http://www.microsoft.com/typography/fonts/ */ Cufon.registerFont({"w":231,"face":{"font-family":"Georgia","font-weight":400,"font-style":"italic","font-stretch":"normal","units-per-em":"360","panose-1":"2 4 5 2 5 4 5 9 3 3","ascent":"288","descent":"-72","x-height":"5","bbox":"-63 -272.094 392 78.3031","underline-thickness":"16.875","underline-position":"-23.7305","slope":"-13","unicode-range":"U+0020-U+00A3"},"glyphs":{" ":{"w":86},"\u00a0":{"w":86},"!":{"d":"117,-238v-14,61,-32,93,-52,162r-14,0r21,-156v1,-22,43,-37,45,-6xm48,-44v13,0,24,11,24,24v0,13,-11,24,-24,24v-13,0,-24,-11,-24,-24v0,-13,11,-24,24,-24","w":119},"\"":{"d":"118,-170v4,-46,-12,-113,38,-94v12,29,-21,60,-28,94r-10,0xm52,-170v4,-46,-12,-113,38,-94v12,29,-21,60,-28,94r-10,0","w":148},"#":{"d":"207,-131r-40,0r-17,44r46,0r-5,22r-49,0r-24,65r-20,0r25,-65r-39,0r-24,65r-20,0r25,-65r-38,0r5,-22r41,0r17,-44r-46,0r5,-22r49,0r24,-63r19,0r-24,63r38,0r24,-63r20,0r-24,63r37,0xm148,-131r-39,0r-17,45r39,0"},"$":{"d":"42,-74v29,-1,15,34,5,43v6,14,18,19,38,21r21,-91v-27,-12,-58,-21,-59,-57v-1,-42,47,-70,89,-70r8,-40r17,0r-10,40v29,3,54,17,57,43v3,25,-36,37,-40,11v11,-20,11,-41,-20,-41r-19,85v28,11,61,22,62,58v1,45,-45,75,-93,75r-11,50r-17,0r12,-49v-32,-1,-63,-19,-64,-48v0,-15,9,-30,24,-30xm133,-214v-52,-8,-75,63,-25,77r6,3xm101,-9v57,9,79,-77,20,-88","w":219},"%":{"d":"107,-255v31,-1,48,19,48,49v0,43,-31,81,-73,81v-30,0,-50,-19,-49,-49v2,-47,27,-79,74,-81xm84,-137v27,0,43,-40,43,-73v0,-17,-7,-34,-23,-34v-28,0,-43,40,-42,74v-1,17,6,33,22,33xm225,-125v30,-1,49,20,49,50v1,42,-32,80,-74,80v-30,0,-51,-19,-49,-49v3,-45,27,-80,74,-81xm203,-6v28,0,43,-41,42,-74v1,-17,-6,-33,-22,-33v-28,0,-42,39,-42,74v0,17,6,33,22,33xm295,-250r-257,250r-25,0r256,-250r26,0","w":294},"&":{"d":"201,-133v-2,-10,-15,-10,-27,-13r3,-12r94,0r-3,12v-60,3,-67,64,-102,92v12,23,31,42,66,42r-3,12r-68,0r-20,-32v-20,17,-41,37,-76,38v-34,1,-64,-22,-62,-56v3,-48,35,-67,76,-89v-34,-44,-12,-120,54,-116v26,2,48,14,47,41v-2,43,-28,52,-66,72r45,79v16,-21,36,-40,42,-70xm109,-152v27,-14,47,-27,48,-61v0,-17,-9,-28,-26,-28v-44,0,-44,60,-22,89xm84,-128v-43,12,-65,111,-1,111v21,0,38,-11,51,-24","w":255},"'":{"d":"49,-170v4,-45,-11,-113,38,-94v12,29,-21,60,-27,94r-11,0","w":77},"(":{"d":"95,58v-106,-13,-84,-190,-35,-258v28,-40,60,-64,100,-69r-3,14v-75,24,-105,118,-105,216v0,43,11,78,46,84","w":135},")":{"d":"49,-269v107,12,83,189,35,257v-28,40,-60,65,-100,70r3,-15v76,-23,105,-118,105,-216v0,-42,-11,-77,-46,-83","w":135},"*":{"d":"112,-196v25,1,58,-24,65,3v-6,26,-43,1,-65,3v11,18,30,26,37,47v0,6,-7,12,-13,12v-22,-8,-15,-32,-29,-56v-14,22,-6,48,-28,56v-6,0,-14,-5,-13,-12v5,-21,25,-28,36,-47v-23,-3,-59,23,-65,-3v7,-27,41,-1,65,-3v-10,-18,-31,-28,-36,-48v-1,-6,8,-12,13,-12v21,5,16,39,28,57v14,-20,7,-51,29,-57v5,0,14,6,13,12v-5,20,-23,26,-37,48","w":169},"+":{"d":"211,-87r-80,0r0,79r-22,0r0,-79r-79,0r0,-22r79,0r0,-80r22,0r0,80r80,0r0,22"},",":{"d":"48,-44v44,2,20,67,0,78v-12,12,-26,21,-40,28r-6,-12v22,-11,42,-26,50,-50v-17,2,-30,-5,-30,-20v0,-13,11,-25,26,-24","w":97},"-":{"d":"125,-109r-6,27r-105,0r6,-27r105,0","w":134},"\u00ad":{"d":"125,-109r-6,27r-105,0r6,-27r105,0","w":134},".":{"d":"46,-44v13,0,24,11,24,24v0,13,-11,24,-24,24v-13,0,-24,-11,-24,-24v0,-13,11,-24,24,-24","w":97},"\/":{"d":"185,-268r-181,343r-24,0r181,-343r24,0","w":168},"0":{"d":"137,-194v45,-2,75,30,75,71v0,75,-46,126,-120,129v-44,2,-75,-29,-75,-71v0,-74,46,-126,120,-129xm95,-8v58,-2,76,-64,79,-122v1,-31,-13,-51,-40,-51v-57,0,-76,65,-79,123v-2,29,12,51,40,50","w":220},"1":{"d":"41,-172v30,2,55,-8,70,-22r15,0r-39,165v-1,17,23,15,36,17r-3,12r-118,0r3,-12v21,-2,44,-1,48,-21r29,-125r-44,0","w":154},"2":{"d":"36,-133v1,-71,153,-88,153,-6v0,82,-114,63,-157,108r140,0r-7,31r-165,0v11,-87,143,-52,152,-143v5,-43,-56,-47,-74,-22v3,25,0,47,-25,47v-11,0,-17,-6,-17,-15","w":201},"3":{"d":"37,-134v2,-65,150,-89,150,-11v0,43,-34,57,-66,71v28,4,54,16,52,48v-3,60,-48,88,-111,90v-33,1,-62,-16,-65,-43v-3,-27,39,-42,43,-14v1,11,-8,21,-11,29v43,36,107,-3,107,-65v0,-32,-30,-35,-65,-33r4,-20v48,6,73,-24,75,-66v2,-41,-53,-39,-70,-18v2,27,-3,48,-28,48v-12,0,-15,-6,-15,-16","w":198},"4":{"d":"194,-38r-6,22r-36,0r-19,80r-34,0r19,-80r-113,0r7,-29r156,-148r24,0r-35,155r37,0xm150,-154r-123,116r96,0","w":203},"5":{"d":"19,-6v29,0,16,32,9,43v43,41,112,-16,105,-74v4,-55,-76,-50,-95,-20r-11,-5r42,-127r127,0r-8,31r-111,0r-24,75v37,-28,122,-19,118,43v-5,63,-47,101,-111,104v-32,2,-63,-15,-65,-42v-1,-14,10,-28,24,-28","w":190},"6":{"d":"133,-160v35,-1,61,29,59,64v-3,61,-40,100,-101,102v-105,3,-74,-156,-23,-201v30,-27,72,-55,121,-61r0,17v-64,7,-103,52,-123,104v20,-15,38,-24,67,-25xm95,-7v35,-1,60,-44,60,-84v0,-57,-64,-60,-93,-27v-11,37,-15,113,33,111","w":203},"7":{"d":"172,-160v-60,2,-128,-13,-134,40r-12,0r16,-69r165,0r-2,12r-180,241r-23,0","w":178},"8":{"d":"51,-181v-5,-75,161,-112,161,-21v0,36,-28,58,-59,71v25,12,44,26,44,56v0,47,-54,81,-106,81v-41,0,-74,-20,-74,-58v0,-45,28,-61,68,-76v-19,-13,-32,-28,-34,-53xm142,-137v35,-12,59,-104,-1,-106v-41,-2,-75,51,-42,82v9,8,24,16,43,24xm98,-7v48,0,87,-58,47,-89v-13,-10,-30,-19,-48,-26v-50,11,-68,115,1,115","w":214},"9":{"d":"122,-194v73,-4,87,83,60,143v-28,62,-81,106,-159,116r0,-17v67,-10,103,-46,124,-101v-39,39,-131,28,-126,-40v4,-59,41,-98,101,-101xm59,-96v-4,53,64,58,92,26v12,-33,14,-113,-32,-111v-43,2,-57,43,-60,85","w":203},":":{"d":"83,-174v13,0,26,11,25,24v0,13,-12,24,-25,24v-13,0,-24,-12,-24,-24v-1,-13,11,-24,24,-24xm54,-44v13,0,25,12,25,24v0,13,-12,24,-25,24v-13,0,-24,-12,-24,-24v0,-12,11,-24,24,-24","w":138},";":{"d":"83,-174v13,0,26,11,25,24v0,13,-12,24,-25,24v-13,0,-24,-12,-24,-24v-1,-13,11,-24,24,-24xm57,-44v43,3,19,66,0,78v-12,12,-26,21,-41,28r-5,-12v21,-12,42,-25,49,-50v-17,2,-29,-5,-29,-20v0,-13,11,-25,26,-24","w":138},"\u037e":{"d":"83,-174v13,0,26,11,25,24v0,13,-12,24,-25,24v-13,0,-24,-12,-24,-24v-1,-13,11,-24,24,-24xm57,-44v43,3,19,66,0,78v-12,12,-26,21,-41,28r-5,-12v21,-12,42,-25,49,-50v-17,2,-29,-5,-29,-20v0,-13,11,-25,26,-24","w":138},"<":{"d":"201,-4r-163,-84r0,-20r163,-85r0,24r-135,71r135,70r0,24"},"=":{"d":"209,-120r-178,0r0,-22r178,0r0,22xm209,-55r-178,0r0,-22r178,0r0,22"},">":{"d":"202,-88r-163,84r0,-24r136,-70r-136,-71r0,-24r163,85r0,20"},"?":{"d":"111,-255v71,-5,84,85,39,122v-19,15,-40,25,-69,29r-9,38r-16,0r14,-67v43,-4,74,-22,74,-70v0,-36,-36,-48,-61,-32v2,25,-3,42,-26,42v-9,0,-14,-7,-15,-15v5,-31,33,-45,69,-47xm57,-44v13,0,24,11,24,24v0,13,-11,24,-24,24v-13,0,-24,-11,-24,-24v0,-13,11,-24,24,-24","w":172},"@":{"d":"179,41v40,0,67,-10,89,-29r6,9v-23,20,-54,36,-96,34v-86,-3,-144,-51,-144,-139v0,-93,62,-157,159,-157v74,0,115,43,117,115v1,52,-32,102,-83,102v-21,0,-35,-12,-38,-29v-9,15,-21,27,-41,28v-29,0,-41,-19,-41,-48v0,-49,33,-90,82,-95v16,-2,24,11,28,22r8,-20r26,0v-12,39,-28,73,-37,114v0,11,6,17,17,17v41,-2,66,-46,64,-93v-2,-62,-38,-98,-104,-98v-80,0,-128,56,-128,139v0,78,37,128,116,128xm138,-70v-3,36,24,37,39,20v19,-21,25,-52,36,-80v-3,-16,-8,-27,-24,-28v-36,7,-47,47,-51,88","w":334},"A":{"d":"154,-101r-16,-98r-60,98r76,0xm38,-25v2,11,19,11,32,13r-2,12r-96,0r3,-12v24,-2,37,-13,48,-30r130,-211r14,0r37,227v5,8,14,15,28,14r-3,12r-102,0r3,-12v14,-2,33,0,35,-13r-9,-62r-87,0v-11,20,-25,40,-31,62","w":241},"B":{"d":"54,-249v66,6,171,-23,174,44v2,48,-40,58,-73,72v31,5,62,17,62,53v0,96,-123,79,-222,80r3,-12v19,0,36,-5,39,-21r42,-188v0,-14,-17,-15,-28,-17xm98,-139v55,4,88,-16,88,-65v0,-31,-30,-34,-65,-32xm107,-13v68,0,99,-114,19,-112r-31,1r-21,94v1,14,16,17,33,17","w":235},"C":{"d":"18,-94v-4,-114,106,-196,209,-143v5,-7,9,-15,24,-12r-19,89r-15,0v2,-47,-11,-84,-56,-81v-70,4,-102,69,-102,144v0,45,25,84,68,84v40,0,67,-28,83,-57r13,7v-26,43,-54,69,-112,69v-59,0,-92,-39,-93,-100"},"D":{"d":"54,-249v104,-3,216,-9,212,96v-3,96,-66,153,-162,153r-109,0r3,-12v18,1,34,-4,38,-20r43,-189v1,-14,-18,-14,-28,-17xm112,-14v77,0,111,-62,113,-139v2,-59,-40,-92,-104,-82r-46,202v1,17,16,19,37,19","w":269},"E":{"d":"78,-214v7,-19,-16,-23,-30,-24r3,-11r193,0r-14,60r-13,0v-1,-33,-16,-53,-56,-47r-40,0r-23,100v45,5,71,-10,78,-41r13,0r-22,97v-8,1,-17,2,-12,-10v4,-35,-27,-34,-60,-33v-6,32,-16,59,-20,93v2,18,13,13,37,16v65,7,75,-31,98,-59r12,0r-21,73r-208,0r3,-12v20,0,37,-4,41,-21","w":235},"F":{"d":"78,-214v7,-19,-16,-23,-30,-24r3,-11r196,0r-15,62r-13,0v-1,-33,-15,-49,-55,-49r-43,0r-23,101v45,4,73,-7,80,-41r14,0r-23,98v-16,4,-12,-8,-13,-22v-2,-27,-34,-21,-62,-22v-6,32,-16,60,-20,94v-1,15,19,14,31,16r-3,12r-108,0r3,-12v19,0,35,-3,39,-20","w":215},"G":{"d":"18,-95v0,-119,116,-194,219,-142v5,-7,9,-15,24,-12r-19,87r-14,0v-2,-46,-15,-82,-64,-79v-73,5,-99,70,-105,148v-5,68,63,107,114,69v6,-18,12,-36,14,-59v2,-18,-23,-15,-36,-18r2,-11r110,0r-3,11v-46,-1,-42,50,-51,85v-72,39,-191,27,-191,-79","w":261},"H":{"d":"233,-214v6,-18,-14,-23,-28,-24r3,-11r103,0r-2,11v-18,2,-34,5,-38,22r-43,188v1,12,15,16,28,16r-2,12r-104,0r3,-12v18,0,34,-4,38,-20r21,-90r-117,0v-6,32,-18,60,-21,94v-1,13,15,16,28,16r-3,12r-103,0r2,-12v18,-1,34,-3,38,-20r43,-188v1,-15,-17,-16,-29,-18r3,-11r104,0r-3,11v-18,2,-34,5,-38,22r-18,79r118,0","w":293},"I":{"d":"79,-214v6,-19,-17,-22,-32,-24r3,-11r112,0r-3,11v-19,3,-38,3,-42,22r-43,188v-1,15,21,13,33,16r-2,12r-113,0r3,-12v19,0,38,-4,42,-20","w":140},"J":{"d":"132,-214v6,-20,-18,-22,-33,-24r3,-11r111,0r-3,11v-18,1,-39,4,-40,22v-28,88,-13,217,-125,222v-31,1,-54,-16,-54,-46v-1,-21,13,-46,32,-44v41,5,3,52,-9,64v12,21,63,15,69,-8v26,-51,32,-125,49,-186","w":186},"K":{"d":"208,-230v-3,-6,-12,-7,-23,-8r2,-11r94,0v-1,21,-36,10,-47,26r-99,86r69,111v8,9,18,14,34,14r-3,12r-64,0v-19,-41,-42,-81,-67,-118r-10,0v-6,31,-16,57,-20,90v-2,14,18,13,28,16r-2,12r-104,0r3,-12v18,-1,33,-4,37,-20r43,-188v1,-15,-17,-14,-28,-18r3,-11r103,0r-2,11v-18,2,-36,4,-39,22r-20,89v43,-26,87,-62,112,-103","w":249},"L":{"d":"77,-46v-16,38,25,36,60,31v27,-3,25,-15,43,-32v14,-13,10,-29,33,-27r-22,74r-195,0r2,-12v19,0,35,-4,39,-21r42,-187v1,-14,-19,-15,-29,-18r3,-11r105,0r-2,11v-18,3,-36,5,-40,23","w":217},"M":{"d":"73,-199v8,-25,-9,-38,-30,-39r3,-11r84,0r27,187r107,-175v3,-6,5,-10,5,-12r84,0r-3,11v-18,2,-36,5,-39,22r-42,188v-1,13,16,15,29,16r-2,12r-110,0r3,-12v21,0,41,-5,44,-22r43,-186r-2,0r-136,216r-9,0r-31,-220r-2,0r-39,171v-8,29,10,39,33,41r-3,12r-100,0r2,-12v38,-1,46,-21,54,-57","w":333},"N":{"d":"239,-197v9,-32,-13,-38,-34,-41r3,-11r101,0r-3,11v-18,3,-38,6,-43,25v-19,66,-34,145,-52,215r-16,0r-102,-210r-37,170v-2,20,20,24,36,26r-3,12r-102,0r2,-12v37,-2,48,-21,55,-58r30,-139v0,-20,-20,-26,-37,-29r3,-11r72,0r95,195","w":276},"O":{"d":"163,-255v59,-3,100,42,97,102v-5,89,-56,154,-145,159v-58,3,-100,-42,-97,-101v4,-92,55,-156,145,-160xm118,-9v73,-5,98,-78,100,-155v1,-43,-18,-80,-59,-77v-70,5,-98,79,-100,154v-1,45,17,81,59,78","w":262},"P":{"d":"52,-249v71,4,179,-20,179,50v0,69,-61,93,-139,89r-19,83v-1,15,18,14,32,15r-2,12r-107,0r2,-12v19,0,35,-4,39,-21r42,-189v1,-15,-18,-13,-30,-16xm95,-124v58,5,93,-21,93,-71v0,-35,-28,-45,-67,-41","w":219},"Q":{"d":"163,-255v59,-3,99,42,97,102v-3,79,-46,132,-109,153v-10,42,29,60,69,46r-3,13v-46,17,-120,12,-106,-53v-56,-1,-95,-43,-93,-101v4,-92,55,-156,145,-160xm118,-9v73,-5,98,-78,100,-155v1,-43,-18,-80,-59,-77v-70,5,-98,79,-100,154v-1,45,17,81,59,78","w":262},"R":{"d":"234,-202v0,51,-37,70,-79,81v28,37,29,102,86,109r-3,12r-63,0v-18,-46,-35,-75,-56,-114r-26,0r-20,87v-1,15,17,14,31,15r-3,12r-106,0r3,-12v19,0,35,-4,39,-21r42,-189v2,-15,-18,-14,-29,-16r3,-11v70,5,181,-23,181,47xm96,-128v55,7,94,-22,95,-70v1,-35,-32,-41,-70,-38","w":252},"S":{"d":"144,-136v85,37,27,141,-57,141v-27,0,-50,-8,-65,-18v-5,7,-9,16,-24,13r18,-85r14,0v3,43,17,76,63,76v33,0,59,-21,58,-54v-4,-69,-111,-38,-111,-114v0,-71,95,-98,147,-60v5,-7,9,-15,24,-12r-18,82r-14,0v-1,-40,-11,-74,-54,-74v-43,0,-70,67,-28,85","w":201},"T":{"d":"126,-237v-53,-6,-74,25,-91,55r-12,0r15,-67r218,0r-16,67r-12,0v-1,-38,-17,-62,-65,-55r-47,208v-2,17,22,14,35,17r-3,12r-117,0r2,-12v21,0,42,-4,46,-22","w":222},"U":{"d":"235,-200v8,-29,-13,-36,-34,-38r2,-11r102,0r-2,11v-22,2,-38,6,-45,27v-29,89,-18,219,-142,217v-49,0,-87,-24,-77,-72r35,-154v-1,-13,-16,-17,-28,-18r3,-11r104,0r-3,11v-18,2,-36,5,-39,22v-10,54,-29,104,-34,160v-5,56,84,51,108,21v33,-41,35,-106,50,-165","w":272},"V":{"d":"217,-215v11,-19,-15,-21,-31,-23r3,-11r95,0v-6,21,-41,15,-48,41r-133,211r-15,0r-34,-227v-5,-8,-16,-13,-27,-14r2,-11r101,0r-2,11v-19,3,-37,-1,-34,18r24,169r86,-139v7,-12,11,-20,13,-25","w":239},"W":{"d":"326,-213v10,-21,-8,-23,-28,-25r2,-11r92,0r-2,11v-22,3,-37,14,-45,31r-113,210r-15,0r-21,-192r-109,192r-15,0r-11,-217v0,-17,-14,-22,-29,-24r3,-11r100,0r-3,11v-52,-1,-35,33,-32,86r5,93r105,-187r16,0r21,191","w":351},"X":{"d":"215,-228v-1,-7,-18,-10,-27,-10r3,-11r93,0r-3,11v-48,3,-64,41,-92,66v-23,20,-21,23,-36,38v20,40,32,87,59,119v4,4,15,3,23,3r-3,12r-112,0r3,-12v18,0,41,0,32,-24r-29,-73v-23,25,-58,55,-76,88v0,9,17,8,27,9r-2,12r-94,0r2,-12v51,-3,67,-41,94,-68r42,-43r-47,-102v-3,-9,-20,-12,-32,-13r3,-11r111,0r-3,11v-19,0,-44,3,-32,23v10,29,15,40,28,68v27,-31,49,-48,68,-81","w":255},"Y":{"d":"198,-213v17,-17,-2,-26,-23,-25r3,-11r89,0v-6,22,-35,15,-47,36v-29,32,-61,73,-87,109v-8,20,-16,49,-19,74v-2,17,21,16,35,18r-3,12r-116,0r2,-12v21,-1,43,-2,45,-22v4,-29,22,-59,9,-88v-18,-40,-12,-106,-61,-116r3,-11r102,0v3,24,-46,-2,-35,32r30,96","w":221},"Z":{"d":"137,-236v-49,-6,-70,32,-91,57r-13,0r24,-70r187,0r-2,6r-206,230v39,0,86,3,113,-10v16,-13,38,-38,49,-55r13,0r-27,78r-200,0r2,-6r206,-230r-55,0","w":216},"[":{"d":"163,-267r-3,15r-63,0r-67,291r62,0r-3,15r-94,0r74,-321r94,0","w":135},"\\":{"d":"123,75r-23,0r-42,-343r23,0","w":168},"]":{"d":"145,-267r-74,321r-93,0r3,-15r62,0r68,-291r-63,0r4,-15r93,0","w":135},"^":{"d":"207,-140r-26,0r-56,-92r-57,92r-26,0r73,-116r19,0"},"_":{"d":"205,32r-4,17r-233,0r4,-17r233,0"},"`":{"d":"104,-237v-15,-7,-13,-34,5,-33v22,1,25,24,34,38r19,31r-7,6","w":180},"a":{"d":"193,-9v-28,15,-67,19,-72,-14v-14,12,-29,27,-54,28v-36,0,-56,-29,-55,-68v0,-76,70,-138,143,-103v11,-1,26,-12,34,-6r-31,138v-3,22,22,17,37,14xm49,-63v-6,56,52,60,76,23r22,-94v1,-21,-11,-31,-31,-31v-46,0,-62,51,-67,102","w":206},"b":{"d":"78,-153v36,-42,112,-25,109,43v-4,80,-68,138,-147,106v-11,-5,-17,-13,-24,-23r48,-212v1,-17,-14,-17,-29,-18r2,-11r66,-4v-3,39,-18,80,-25,119xm85,-7v48,-4,61,-52,66,-102v5,-53,-53,-61,-78,-26r-23,104v3,15,16,25,35,24","w":199},"c":{"d":"155,-42v-14,23,-44,46,-77,47v-42,0,-67,-27,-66,-69v2,-64,34,-109,97,-113v30,-1,49,12,52,37v3,28,-38,43,-42,15v0,-8,9,-25,10,-31v-45,-33,-84,36,-81,87v2,30,12,54,41,54v27,-1,42,-17,56,-35","w":163},"d":{"d":"194,-9v-27,14,-68,21,-71,-15v-14,12,-30,28,-56,29v-36,0,-56,-29,-55,-68v-1,-78,69,-138,144,-103v5,-25,12,-47,15,-73v2,-19,-18,-16,-34,-18r2,-11r71,-4r2,3r-53,235v-3,23,23,17,38,14xm49,-63v-5,58,53,58,78,22r22,-95v-3,-17,-14,-29,-34,-29v-46,0,-61,51,-66,102","w":207},"e":{"d":"113,-177v30,-1,50,11,50,36v0,54,-64,60,-116,69v-1,34,11,57,41,57v30,0,42,-15,57,-35r10,8v-15,24,-44,47,-79,47v-42,1,-64,-26,-64,-67v0,-65,37,-112,101,-115xm48,-84v40,-6,84,-15,82,-61v-2,-35,-44,-19,-59,3v-11,16,-20,35,-23,58","w":169},"f":{"d":"178,-252v-7,37,-39,14,-45,-6v-31,6,-33,50,-43,86r44,0r-3,16r-44,0v-25,90,-19,222,-120,234v-17,2,-30,-6,-30,-21v7,-36,39,-12,45,7v26,-7,33,-36,40,-68r32,-152r-34,0r4,-16r33,0v11,-52,35,-96,91,-100v17,-1,30,6,30,20","w":118},"g":{"d":"12,-64v-1,-77,70,-137,143,-102v11,-1,26,-12,34,-6v-31,99,-12,248,-140,250v-26,0,-47,-4,-47,-25v0,-10,6,-20,18,-19v17,1,22,20,28,32v53,-1,66,-42,77,-90v-18,9,-31,29,-60,28v-36,-1,-53,-30,-53,-68xm49,-64v-6,58,55,57,79,23r20,-95v0,-20,-13,-29,-32,-29v-47,0,-62,51,-67,101","w":206},"h":{"d":"159,-58v-9,26,-1,52,33,38r-2,11v-32,19,-80,17,-68,-33r22,-89v-2,-44,-59,-19,-72,2r-30,129r-32,0r54,-239v1,-17,-14,-17,-29,-18r3,-11r65,-4r2,3r-28,121v25,-32,109,-48,100,17v-4,26,-10,49,-18,73","w":202},"i":{"d":"63,-58v-7,22,-7,50,24,41v4,-1,8,-1,10,-2r-3,11v-31,20,-81,15,-67,-33v10,-33,18,-64,22,-100v4,-23,-21,-16,-36,-13r2,-11v30,-19,80,-19,67,32xm87,-266v13,-2,22,11,22,22v1,13,-9,25,-22,25v-12,0,-22,-11,-22,-23v0,-12,9,-25,22,-24","w":107},"j":{"d":"17,-165v30,-19,82,-19,68,32v-24,84,-22,201,-116,211v-31,3,-41,-40,-12,-40v16,0,22,15,28,26v52,-32,51,-133,67,-205v5,-23,-24,-16,-38,-12xm88,-266v14,0,23,10,23,22v0,13,-10,25,-23,25v-12,0,-22,-12,-22,-23v0,-11,10,-24,22,-24","w":104},"k":{"d":"153,-172v13,-9,36,-4,35,15v-1,22,-30,25,-45,14v-15,11,-28,18,-42,33v21,35,21,110,83,90r-3,12v-18,6,-25,12,-44,11v-42,-3,-42,-59,-59,-88r-21,17r-15,68r-32,0r54,-239v1,-17,-14,-17,-29,-18r3,-11r65,-4r2,3r-43,183v30,-28,58,-63,91,-86","w":190},"l":{"d":"63,-226v7,-23,-5,-32,-27,-31r2,-11r66,-4v-11,79,-41,156,-52,238v-3,22,24,19,40,15r-3,11v-31,20,-81,17,-69,-33","w":102},"m":{"d":"273,-58v-8,26,-1,53,33,38r-2,11v-32,19,-83,17,-68,-33v9,-29,18,-57,22,-89v3,-26,-25,-30,-45,-20v-8,4,-16,11,-25,21r-31,130r-33,0r31,-132v-5,-41,-57,-21,-73,3r-30,129r-33,0r31,-139v2,-22,-22,-17,-36,-13r3,-11v24,-14,68,-21,69,16v24,-17,33,-29,66,-30v20,-1,33,15,37,31v23,-17,35,-31,68,-31v59,0,28,82,16,119","w":316},"n":{"d":"169,-58v-9,19,-9,51,23,40v4,-1,8,-1,10,-2r-3,11v-31,20,-82,16,-67,-33v9,-29,16,-57,21,-89v-3,-45,-56,-19,-71,2r-30,129r-33,0r31,-139v2,-22,-22,-17,-36,-13r3,-11v24,-14,68,-21,69,16v23,-16,33,-30,66,-30v59,0,25,80,17,119","w":212},"o":{"d":"115,-177v41,-2,69,28,67,69v-3,65,-37,112,-105,113v-39,1,-66,-29,-65,-69v3,-66,37,-110,103,-113xm83,-7v48,0,61,-56,63,-108v0,-30,-10,-50,-35,-50v-48,0,-62,55,-63,107v-1,30,8,51,35,51","w":193},"p":{"d":"139,-177v37,1,57,28,57,67v0,78,-73,140,-142,102v-4,29,-32,78,18,75r-2,11r-97,0r2,-11v18,0,31,-4,34,-19r40,-187v3,-23,-21,-17,-35,-13r2,-11v22,-12,65,-22,69,11v17,-9,30,-25,54,-25xm94,-8v47,-6,62,-50,66,-101v4,-52,-50,-63,-77,-26r-23,100v2,14,16,28,34,27","w":208},"q":{"d":"142,38v-8,20,7,30,27,29r-3,11r-96,0r2,-11v18,0,32,-3,35,-19v4,-23,14,-50,16,-72v-15,10,-30,29,-56,29v-36,0,-56,-29,-55,-68v0,-77,71,-138,144,-103v11,-1,26,-12,34,-6xm49,-63v0,26,4,49,31,48v21,-1,34,-14,47,-26r22,-93v-1,-19,-11,-31,-32,-31v-46,0,-68,50,-68,102","w":199},"r":{"d":"85,-145v27,-18,41,-43,75,-26v15,13,8,53,-16,53v-24,0,-19,-29,-10,-41v-24,3,-39,17,-53,33r-28,126r-33,0r30,-139v2,-22,-22,-17,-36,-13r3,-11v24,-13,71,-24,68,18","w":166},"s":{"d":"136,-55v0,37,-34,60,-72,60v-28,0,-61,-9,-61,-33v0,-10,8,-20,18,-20v29,1,14,43,47,41v24,-1,38,-13,38,-36v0,-44,-83,-25,-80,-79v2,-37,39,-60,85,-55v17,2,37,9,37,27v0,30,-38,19,-40,-2v-11,-27,-55,-8,-52,18v5,44,80,27,80,79","w":155},"t":{"d":"61,-59v-15,32,9,53,44,38r-3,13v-28,16,-91,23,-79,-30r27,-118r-31,0r4,-16r32,0r12,-51r32,0r-12,51r49,0r-4,16r-49,0","w":124},"u":{"d":"195,-9v-28,16,-70,18,-72,-16v-19,15,-31,31,-63,29v-68,-5,-18,-94,-14,-143v2,-22,-21,-16,-35,-13r2,-11v28,-18,78,-20,66,32r-20,89v-1,42,54,23,68,2r31,-133v11,1,27,-5,33,1r-31,138v-3,22,22,17,37,14","w":207},"v":{"d":"160,-177v16,0,23,14,23,32v-5,76,-35,144,-108,150v-36,3,-57,-26,-48,-63r20,-81v3,-22,-24,-16,-37,-12r3,-12v29,-19,78,-19,66,32r-20,87v0,19,10,29,29,29v54,0,89,-81,55,-128v-9,-13,0,-34,17,-34","w":193},"w":{"d":"263,-177v16,0,22,14,22,32v-5,76,-33,150,-106,150v-24,0,-44,-14,-49,-34v-17,15,-30,34,-60,34v-76,0,-31,-92,-24,-144v4,-22,-21,-16,-35,-13r2,-11v28,-18,81,-19,66,32v-8,29,-18,55,-20,89v-3,44,55,24,68,3r31,-134v10,1,27,-6,33,1r-29,129v-1,20,11,30,30,28v47,-5,76,-55,66,-109v-14,-12,-26,-52,5,-53","w":296},"x":{"d":"152,-171v14,-9,37,-6,36,13v0,22,-29,22,-46,15v-12,13,-28,33,-38,51v10,38,14,90,67,72r-3,12v-29,15,-68,18,-77,-18r-10,-39v-21,25,-31,63,-69,68v-12,1,-19,-6,-19,-18v0,-22,31,-23,46,-14v11,-12,28,-33,38,-50v-10,-32,-10,-93,-62,-72r3,-12v13,-6,26,-12,39,-12v37,-1,34,41,43,69v14,-21,30,-52,52,-65","w":180},"y":{"d":"21,34v18,1,23,22,28,32v51,-1,69,-48,76,-91v-24,32,-109,47,-100,-17v4,-33,17,-63,21,-97v3,-22,-21,-16,-35,-13r2,-11v29,-19,78,-19,66,32r-20,88v0,44,56,22,70,2r29,-132v10,1,27,-6,33,1v-30,100,-17,250,-142,250v-25,0,-46,-3,-46,-25v0,-10,7,-19,18,-19","w":201},"z":{"d":"122,-158v-49,-4,-80,2,-88,39r-10,0r10,-53r130,0r-2,10r-126,148r64,-1v21,-4,24,-30,34,-46r11,0r-12,61r-138,0r3,-12","w":159},"{":{"d":"59,-65v0,-24,-18,-29,-46,-32r5,-21v53,-1,67,-38,72,-89v5,-47,39,-63,94,-63r-4,13v-86,-3,-36,123,-114,141v-8,5,-25,1,-27,12v26,5,48,14,48,45v0,28,-14,52,-14,79v0,21,18,24,38,25r-3,14v-41,-1,-65,-8,-66,-43v-1,-29,17,-53,17,-81","w":154},"|":{"d":"83,75r-22,0r0,-343r22,0r0,343","w":135},"}":{"d":"101,-146v0,24,18,29,46,31r-5,22v-112,-6,-21,163,-166,152r4,-14v86,3,36,-122,114,-140v9,-5,24,-2,27,-12v-64,-1,-47,-75,-34,-124v1,-22,-19,-24,-38,-26r3,-13v42,0,66,7,66,43v0,28,-17,54,-17,81","w":154},"~":{"d":"165,-100v19,1,27,-17,34,-31r14,5v-10,24,-27,52,-60,52v-32,0,-48,-24,-78,-24v-19,0,-26,16,-34,31r-14,-5v10,-24,28,-51,60,-52v34,-1,47,22,78,24"},"\u00a3":{"d":"169,-256v30,0,51,18,54,44v3,26,-39,44,-43,15v-1,-9,8,-24,11,-30v-23,-37,-73,1,-79,37r-10,64r69,0r-3,16r-69,0v-7,35,-28,62,-57,77r-1,3r153,0r-7,30r-185,0r6,-26v34,-12,50,-44,56,-84r-30,0r3,-16r30,0v1,-70,34,-129,102,-130","w":223}}}); // JavaScript Document function initCufon (elementOverride) { var elements = new Array ( 'h2', 'blockquote', //'.singleRecord .subHeading', '#categoryChooser li' ); if (typeof (elementOverride) == 'string' && elementOverride.length > 3) elements = elementOverride.split(','); else if (typeof (elementOverride) == 'object') elements = elementOverride; /* use element array instead of string! tab font color goes skewiff otherwise (weird but true) */ //Cufon.replace(elements,{separate: 'none'}); // force cufon to use 1 cufon element /*if ($('.cufon-alt').html()) Cufon.refresh(elements); else Cufon.replace(elements);*/ // forceHitArea to prevent IE7 bug if ($('.cufon-alt').html()) Cufon.refresh(elements,{forceHitArea:true}); else Cufon.replace(elements, {forceHitArea:true} ); } $(document).ready(function () { initCufon(); }); // need to put the whole thing in an enclosure really var heatmapTracker = (function(){ var heatArray = new Object(), clicks = new Object(), saveInterval = 2000, timeStamp = 0, changes = false, dataProcessUrl, saveHeatmapToServer = function () { if (changes) { //save off into new var to stop overwriting (still likely but this might help) var sendData = { 'heatmap' : heatArray, 'clicks' : clicks, 'url' : document.URL }; // clean the arrays heatArray = new Object(); clicks = new Object(); changes = false; // send to server $.ajax({ url: dataProcessUrl, async: true, data: sendData, type: 'POST' }); } // we don't listen for a response }, round5 = function (x) { return (x % 5) >= 2.5 ? parseInt(x / 5) * 5 + 5 : parseInt(x / 5) * 5; }, recordPosition = function (x, y, ts) { // only do if necessary changes = true; // add time since last timestamp to coordinate for that item. var timeSince = 0; if (timeStamp == 0) timeSince = 1; else timeSince = ts - timeStamp; //record for next call timeStamp = ts; // round position to nearest 5 x = round5(x); y = round5(y); // initialise if not existing if ( heatArray[ x ] == null) heatArray[ x ] = new Object(); if ( heatArray[ x ][ y ] == null) heatArray[ x ][ y ] = 0; // and record the time in that position heatArray[ x ][ y ] += timeSince; }, recordClick = function (x, y) { // only do if necessary changes = true; // round position to nearest 5 x = round5(x); y = round5(y); // initialise if not existing if ( clicks[ x ] == null) clicks[ x ] = new Object(); if ( clicks[ x ][ y ] == null) clicks[ x ][ y ] = 0; // and record the time in that position clicks[ x ][ y ] += 1; // as we are likely to be leaving the page, save the position one last time saveHeatmapToServer(); }; return { initialise: function (dataUrl) { dataProcessUrl = dataUrl; // record all mouse movements / coordinates // every N seconds, send them to the server // also send on page unload $('body').mousemove(function(event) { //var msg = 'Handler for .mousemove() called at ' + event.pageX + ', ' + event.pageY; //$('body').prepend('
' + msg + '
'); recordPosition(event.pageX, event.pageY, event.timeStamp); }); $('body').click(function (event) { recordClick(event.pageX, event.pageY); }); // call the activate function in an interval of 50ms (function(fn,interval){ setInterval(fn, interval); })(saveHeatmapToServer, saveInterval); } }; })(); /* Copyright (c) 2010, Patrick Wied. All rights reserved. Code licensed under the BSD License: http://patrick-wied.at/static/license.txt */ var heatmapDisplay; if (!$.browser.msie) heatmapDisplay = (function(){ // var definition // canvas: the canvas element // ctx: the canvas 2d context // width: the heatmap width for border calculations // height: the heatmap height for border calculations // invoke: the app doesn't react on the mouse events unless the invoke var is set to true var canvas, ctx, width, height, radius1 = 20, radius2 = 40, // invoke = false, // function for coloring the heatmap colorize = function(x,y,x2){ // initial check if x and y is outside the app // -> resetting values if(x+x2>width) x=width-x2; if(x<0) x=0; if(y<0) y=0; if(y+x2>height) y=height-x2; // get the image data for the mouse movement area var image = ctx.getImageData(x,y,x2,x2), // some performance tweaks imageData = image.data, length = imageData.length; // loop thru the area for(var i=3; i < length; i+=4){ var r = 0, g = 0, b = 0, tmp = 0, // [0] -> r, [1] -> g, [2] -> b, [3] -> alpha alpha = imageData[i]; // coloring depending on the current alpha value if(alpha<=255 && alpha >= 235){ tmp=255-alpha; r=255-tmp; g=tmp*12; }else if(alpha<=234 && alpha >= 200){ tmp=234-alpha; r=255-(tmp*8); g=255; }else if(alpha<= 199 && alpha >= 150){ tmp=199-alpha; g=255; b=tmp*5; }else if(alpha<= 149 && alpha >= 100){ tmp=149-alpha; g=255-(tmp*5); b=255; }else b=255; // we ve started with i=3 // set the new r, g and b values imageData[i-3]=r; imageData[i-2]=g; imageData[i-1]=b; } // the rgb data manipulation didn't affect the ImageData object(defined on the top) // after the manipulation process we have to set the manipulated data to the ImageData object image.data = imageData; ctx.putImageData(image,x,y); }, // this handler is listening to the mouse movement of the user showMousePosition = function(x,y){ if(typeof(x)=='undefined') return; // storing the variables because they will be often used var r1 = radius1; var r2 = radius2; // create a radial gradient with the defined parameters. we want to draw an alphamap var rgr = ctx.createRadialGradient(x,y,r1,x,y,r2); // the center of the radial gradient has .1 alpha value rgr.addColorStop(0, 'rgba(0,0,0,0.1)'); // and it fades out to 0 rgr.addColorStop(1, 'rgba(0,0,0,0)'); // drawing the gradient ctx.fillStyle = rgr; ctx.fillRect(x-r2,y-r2,2*r2,2*r2); // negate the invoke variable // next execution of the logic is when the activate method activates the invoke var again //invoke=!invoke; // at least colorize the area colorize(x-r2,y-r2,2*r2); }; // we don't want to capture all events because this would result in low performance // -> a function for activating the heatmap logic which will be called in a specified interval //activate = function(){ // invoke = !invoke; //}; return { // initialization initialise: function( dataUrl ){ // overlay everything with a grey block, then overlay that with a red square, with transparency appropriate to it's popularity var cWidth = $(document).width(); var cHeight = $(document).height(); var $mask = $(''); $mask.css('width',cWidth+'px').css('height', cHeight+'px'); //.css('backgroundColor','#000') $mask.css('position','absolute').css('left','0px').css('top','0px').css('zIndex','3000'); //.css('opacity','0.5'); $mask.click(function () {}); $('body').append($mask); // draw a background canvas = document.getElementById('heatMapMask'); ctx = canvas.getContext('2d'); // get the data $.ajax({ url: dataUrl, async: true, data: { 'getData': 'yes', 'url' : document.URL.replace('?showHeatMap','') }, type: 'GET', dataType: 'json', success: function (data) { // loop through the heatmap // find the max value of the popularity // then show it as a percentage for (var x in data['heatmap']) { for (var y in data['heatmap'][x]) { showMousePosition(x,y); } } // then mark any clicks } }); }, // if you like to process the image data e.g onbeforeunload // just call the getData method -> returns imagedata as a dataurl string getData: function(){ return canvas.toDataURL(); } }; })(); // record all movements $(document).ready(function () { // show heat map for this page var dataProcessUrl = "/heatmapping/heatmap.php"; if (document.URL.indexOf('?showHeatMap')!=-1) { heatmapDisplay.initialise( dataProcessUrl ); } else { heatmapTracker.initialise( dataProcessUrl ); } });