| var FontManager = (function(){ | 
 |  | 
 |     var maxWaitingTime = 5000; | 
 |  | 
 |     function setUpNode(font, family){ | 
 |         var parentNode = document.createElement('span'); | 
 |         parentNode.style.fontFamily    = family; | 
 |         var node = document.createElement('span'); | 
 |         // Characters that vary significantly among different fonts | 
 |         node.innerHTML = 'giItT1WQy@!-/#'; | 
 |         // Visible - so we can measure it - but not on the screen | 
 |         parentNode.style.position      = 'absolute'; | 
 |         parentNode.style.left          = '-10000px'; | 
 |         parentNode.style.top           = '-10000px'; | 
 |         // Large font size makes even subtle changes obvious | 
 |         parentNode.style.fontSize      = '300px'; | 
 |         // Reset any font properties | 
 |         parentNode.style.fontVariant   = 'normal'; | 
 |         parentNode.style.fontStyle     = 'normal'; | 
 |         parentNode.style.fontWeight    = 'normal'; | 
 |         parentNode.style.letterSpacing = '0'; | 
 |         parentNode.appendChild(node); | 
 |         document.body.appendChild(parentNode); | 
 |  | 
 |         // Remember width with no applied web font | 
 |         var width = node.offsetWidth; | 
 |         node.style.fontFamily = font + ', '+family; | 
 |         return {node:node, w:width, parent:parentNode}; | 
 |     } | 
 |  | 
 |     function checkLoadedFonts() { | 
 |         var i, len = this.fonts.length; | 
 |         var node, w; | 
 |         var loadedCount = len; | 
 |         for(i=0;i<len; i+= 1){ | 
 |             if(this.fonts[i].loaded){ | 
 |                 loadedCount -= 1; | 
 |                 continue; | 
 |             } | 
 |             if(this.fonts[i].fOrigin === 't'){ | 
 |                 if(window.Typekit && window.Typekit.load && this.typekitLoaded === 0){ | 
 |                     this.typekitLoaded = 1; | 
 |                     try{window.Typekit.load({ | 
 |                         async: true, | 
 |                         active: function() { | 
 |                             this.typekitLoaded = 2; | 
 |                         }.bind(this) | 
 |                     });}catch(e){} | 
 |                 } | 
 |                 if(this.typekitLoaded === 2) { | 
 |                     this.fonts[i].loaded = true; | 
 |                 } | 
 |             } else if(this.fonts[i].fOrigin === 'n'){ | 
 |                 this.fonts[i].loaded = true; | 
 |             } else{ | 
 |                 node = this.fonts[i].monoCase.node; | 
 |                 w = this.fonts[i].monoCase.w; | 
 |                 if(node.offsetWidth !== w){ | 
 |                     loadedCount -= 1; | 
 |                     this.fonts[i].loaded = true; | 
 |                 }else{ | 
 |                     node = this.fonts[i].sansCase.node; | 
 |                     w = this.fonts[i].sansCase.w; | 
 |                     if(node.offsetWidth !== w){ | 
 |                         loadedCount -= 1; | 
 |                         this.fonts[i].loaded = true; | 
 |                     } | 
 |                 } | 
 |                 if(this.fonts[i].loaded){ | 
 |                     this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent); | 
 |                     this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent); | 
 |                 } | 
 |             } | 
 |         } | 
 |  | 
 |         if(loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime){ | 
 |             setTimeout(checkLoadedFonts.bind(this),20); | 
 |         }else{ | 
 |             setTimeout(function(){this.loaded = true;}.bind(this),0); | 
 |  | 
 |         } | 
 |     }; | 
 |  | 
 |     function createHelper(def, fontData){ | 
 |         var tHelper = document.createElementNS(svgNS,'text'); | 
 |         tHelper.style.fontSize = '100px'; | 
 |         tHelper.style.fontFamily = fontData.fFamily; | 
 |         tHelper.textContent = '1'; | 
 |         if(fontData.fClass){ | 
 |             tHelper.style.fontFamily = 'inherit'; | 
 |             tHelper.className = fontData.fClass; | 
 |         } else { | 
 |             tHelper.style.fontFamily = fontData.fFamily; | 
 |         } | 
 |         def.appendChild(tHelper); | 
 |         var tCanvasHelper = document.createElement('canvas').getContext('2d'); | 
 |         tCanvasHelper.font = '100px '+ fontData.fFamily; | 
 |         return tCanvasHelper; | 
 |     } | 
 |  | 
 |     function addFonts(fontData, defs){ | 
 |         if(!fontData){ | 
 |             this.loaded = true; | 
 |             return; | 
 |         } | 
 |         if(this.chars){ | 
 |             this.loaded = true; | 
 |             this.fonts = fontData.list; | 
 |             return; | 
 |         } | 
 |  | 
 |         var fontArr = fontData.list; | 
 |         var i, len = fontArr.length; | 
 |         for(i=0; i<len; i+= 1){ | 
 |             fontArr[i].loaded = false; | 
 |             fontArr[i].monoCase = setUpNode(fontArr[i].fFamily,'monospace'); | 
 |             fontArr[i].sansCase = setUpNode(fontArr[i].fFamily,'sans-serif'); | 
 |             if(!fontArr[i].fPath) { | 
 |                 fontArr[i].loaded = true; | 
 |             }else if(fontArr[i].fOrigin === 'p'){ | 
 |                 var s = document.createElement('style'); | 
 |                 s.type = "text/css"; | 
 |                 s.innerHTML = "@font-face {" + "font-family: "+fontArr[i].fFamily+"; font-style: normal; src: url('"+fontArr[i].fPath+"');}"; | 
 |                 defs.appendChild(s); | 
 |             } else if(fontArr[i].fOrigin === 'g'){ | 
 |                 //<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'> | 
 |                 var l = document.createElement('link'); | 
 |                 l.type = "text/css"; | 
 |                 l.rel = "stylesheet"; | 
 |                 l.href = fontArr[i].fPath; | 
 |                 defs.appendChild(l); | 
 |             } else if(fontArr[i].fOrigin === 't'){ | 
 |                 //<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'> | 
 |                 var sc = document.createElement('script'); | 
 |                 sc.setAttribute('src',fontArr[i].fPath); | 
 |                 defs.appendChild(sc); | 
 |             } | 
 |             fontArr[i].helper = createHelper(defs,fontArr[i]); | 
 |             this.fonts.push(fontArr[i]); | 
 |         } | 
 |         checkLoadedFonts.bind(this)(); | 
 |     } | 
 |  | 
 |     function addChars(chars){ | 
 |         if(!chars){ | 
 |             return; | 
 |         } | 
 |         if(!this.chars){ | 
 |             this.chars = []; | 
 |         } | 
 |         var i, len = chars.length; | 
 |         var j, jLen = this.chars.length, found; | 
 |         for(i=0;i<len;i+=1){ | 
 |             j = 0; | 
 |             found = false; | 
 |             while(j<jLen){ | 
 |                 if(this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch){ | 
 |                     found = true; | 
 |                 } | 
 |                 j += 1; | 
 |             } | 
 |             if(!found){ | 
 |                 this.chars.push(chars[i]); | 
 |                 jLen += 1; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     function getCharData(char, style, font){ | 
 |         var i = 0, len = this.chars.length; | 
 |         while( i < len) { | 
 |             if(this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font){ | 
 |                 return this.chars[i]; | 
 |             } | 
 |             i+= 1; | 
 |         } | 
 |     } | 
 |  | 
 |     function measureText(char, fontName, size){ | 
 |         var fontData = this.getFontByName(fontName); | 
 |         var tHelper = fontData.helper; | 
 |         //tHelper.textContent = char; | 
 |         return tHelper.measureText(char).width*size/100; | 
 |         //return tHelper.getComputedTextLength()*size/100; | 
 |     } | 
 |  | 
 |     function getFontByName(name){ | 
 |         var i = 0, len = this.fonts.length; | 
 |         while(i<len){ | 
 |             if(this.fonts[i].fName === name) { | 
 |                 return this.fonts[i]; | 
 |             } | 
 |             i += 1; | 
 |         } | 
 |         return 'sans-serif'; | 
 |     } | 
 |  | 
 |     var Font = function(){ | 
 |         this.fonts = []; | 
 |         this.chars = null; | 
 |         this.typekitLoaded = 0; | 
 |         this.loaded = false; | 
 |         this.initTime = Date.now(); | 
 |     }; | 
 |     Font.prototype.addChars = addChars; | 
 |     Font.prototype.addFonts = addFonts; | 
 |     Font.prototype.getCharData = getCharData; | 
 |     Font.prototype.getFontByName = getFontByName; | 
 |     Font.prototype.measureText = measureText; | 
 |  | 
 |     return Font; | 
 |  | 
 | }()); |