Updated hyphenator, hastyscribe.
h3rald h3rald@h3rald.com
Sat, 22 Nov 2014 11:30:44 +0100
3 files changed,
2965 insertions(+),
19 deletions(-)
M
content/hastyscribe.erb
→
content/hastyscribe.erb
@@ -7,15 +7,15 @@ type: project
github: hastyscribe links: - "User Guide": /hastyscribe/HastyScribe_UserGuide.htm -- "Download": https://github.com/h3rald/hastyscribe/releases/v1.0.6 +- "Download": https://github.com/h3rald/hastyscribe/releases/v1.0.7 - "Source": https://github.com/h3rald/hastyscribe status: Active -version: 1.0.6 +version: 1.0.7 ----- <div class="jumbotron"> <p style="text-align:center;"><i class="hastyscribe" style="font-size: 180%; color: #000"></i></p> - <p>A simple, self-contained, command-line program able to convert <a href="http://daringfireball.net/projects/markdown">markdown</a> files into self-contained HTML pages, automatically embedding all the needed fonts, stylesheets and images.</p> + <p class="donthyphenate">A simple, self-contained, command-line program able to convert <a href="http://daringfireball.net/projects/markdown">markdown</a> files into self-contained HTML pages, automatically embedding all the needed fonts, stylesheets and images.</p> </div> <div class="row donthyphenate" style="text-align: center; margin: auto;">@@ -80,22 +80,22 @@ <i class="fa fa-download"></i> Download <span class="caret"></span>
</button> <ul class="dropdown-menu" role="menu" style="text-align: left;"> <li> - <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_macosx_x86.zip"> + <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_macosx_x86.zip"> <i class="fa fa-apple"></i> HastyScribe for OS X (x86) </a> </li> <li> - <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_linux_x86.zip"> + <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_linux_x86.zip"> <i class="fa fa-linux"></i> HastyScribe for Linux (x86) </a> </li> <li> - <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_linux_arm.zip"> + <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_linux_arm.zip"> <i class="fa fa-linux"></i> HastyScribe for Linux (ARM) </a> </li> <li> - <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_windows_x86.zip"> + <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_windows_x86.zip"> <i class="fa fa-windows"></i> HastyScribe for Windows (x86) </a> </li>
M
content/hastyscribe/HastyScribe_UserGuide.htm
→
content/hastyscribe/HastyScribe_UserGuide.htm
@@ -229,13 +229,13 @@ <h2 id="Getting.Started">Getting Started<a href="#document-top" title="Go to top"></a></h2>
<h3 id="Downloading.Pre-built.Binaries">Downloading Pre-built Binaries<a href="#document-top" title="Go to top"></a></h3> -<p>The easiest way to get HastyScribe is by downloading one of the prebuilt binaries from the <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6">Github Release Page</a>:</p> +<p>The easiest way to get HastyScribe is by downloading one of the prebuilt binaries from the <a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7">Github Release Page</a>:</p> <ul> -<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_macosx_x86.zip">HastyScribe for Mac OS X (x86)</a> – Compiled on OS X Mavericks (LLVM CLANG 6.0)</li> -<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_windows_x86.zip">HastyScribe for Windows (x86)</a> – Cross-compiled on OS X Mavericks (MinGW GCC 4.8.0)</li> -<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_linux_x86.zip">HastyScribe for Linux (x86)</a> – Cross-compiled on OS X Mavericks (GNU GCC 4.8.1)</li> -<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.6/hastyscribe_v1.0.6_linux_arm.zip">HastyScribe for Linux (ARM)</a> – Cross-compiled on OS X Mavericks (GNU GCC 4.8.2)</li> +<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_macosx_x86.zip">HastyScribe for Mac OS X (x86)</a> – Compiled on OS X Mavericks (LLVM CLANG 6.0)</li> +<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_windows_x86.zip">HastyScribe for Windows (x86)</a> – Cross-compiled on OS X Mavericks (MinGW GCC 4.8.0)</li> +<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_linux_x86.zip">HastyScribe for Linux (x86)</a> – Cross-compiled on OS X Mavericks (GNU GCC 4.8.1)</li> +<li><a href="https://github.com/h3rald/hastyscribe/releases/download/v1.0.7/hastyscribe_v1.0.7_linux_arm.zip">HastyScribe for Linux (ARM)</a> – Cross-compiled on OS X Mavericks (GNU GCC 4.8.2)</li> </ul>@@ -1105,7 +1105,7 @@ </ul>
</div> <div id="footer"> - <p><span class="copy"></span> Fabio Cevasco – October 26, 2014</p> + <p><span class="copy"></span> Fabio Cevasco – November 21, 2014</p> <p><span>Powered by</span> <a href="https://h3rald.com/hastyscribe"><span class="hastyscribe"></span></a></p> </div> </body>
M
content/js/hyphenator.js
→
content/js/hyphenator.js
@@ -1,6 +1,5 @@
-/* - * Hyphenator 4.0.0 - client side hyphenation for webbrowsers - * Copyright (C) 2011 Mathias Nater, Zürich (mathias at mnn dot ch) +/** @license Hyphenator 4.3.0 - client side hyphenation for webbrowsers + * Copyright (C) 2014 Mathias Nater, Zürich (mathiasnater at gmail dot com) * Project and Source hosted on http://code.google.com/p/hyphenator/ * * This JavaScript code is free software: you can redistribute@@ -49,8 +48,2955 @@ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + */ + +/* + * Comments are jsdoc3 formatted. See http://usejsdoc.org + * Use mergeAndPack.html to get rid of the comments and to reduce the file size of this script! */ -var Hyphenator=(function(window){var -supportedLang={'be':'be.js','ca':'ca.js','cs':'cs.js','da':'da.js','bn':'bn.js','de':'de.js','el':'el-monoton.js','el-monoton':'el-monoton.js','el-polyton':'el-polyton.js','en':'en-us.js','en-gb':'en-gb.js','en-us':'en-us.js','es':'es.js','fi':'fi.js','fr':'fr.js','grc':'grc.js','gu':'gu.js','hi':'hi.js','hu':'hu.js','hy':'hy.js','it':'it.js','kn':'kn.js','la':'la.js','lt':'lt.js','lv':'lv.js','ml':'ml.js','nb':'nb-no.js','no':'nb-no.js','nb-no':'nb-no.js','nl':'nl.js','or':'or.js','pa':'pa.js','pl':'pl.js','pt':'pt.js','ru':'ru.js','sk':'sk.js','sl':'sl.js','sv':'sv.js','ta':'ta.js','te':'te.js','tr':'tr.js','uk':'uk.js'},languageHint=(function(){var k,r='';for(k in supportedLang){if(supportedLang.hasOwnProperty(k)){r+=k+', ';}}r=r.substring(0,r.length-2);return r;}()),prompterStrings={'be':'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:','cs':'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:','da':'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:','de':'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:','en':'The language of this website could not be determined automatically. Please indicate the main language:','es':'El idioma del sitio no pudo determinarse autom%E1ticamente. Por favor, indique el idioma principal:','fi':'Sivun kielt%E4 ei tunnistettu automaattisesti. M%E4%E4rit%E4 sivun p%E4%E4kieli:','fr':'La langue de ce site n%u2019a pas pu %EAtre d%E9termin%E9e automatiquement. Veuillez indiquer une langue, s.v.p.%A0:','hu':'A weboldal nyelvét nem sikerült automatikusan megállapítani. Kérem adja meg a nyelvet:','hy':'Չհաջողվեց հայտնաբերել այս կայքի լեզուն։ Խնդրում ենք նշեք հիմնական լեզուն՝','it':'Lingua del sito sconosciuta. Indicare una lingua, per favore:','kn':'ಜಾಲ ತಾಣದ ಭಾಷೆಯನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ಮುಖ್ಯ ಭಾಷೆಯನ್ನು ಸೂಚಿಸಿ:','lt':'Nepavyko automatiškai nustatyti šios svetainės kalbos. Prašome įvesti kalbą:','lv':'Šīs lapas valodu nevarēja noteikt automātiski. Lūdzu norādiet pamata valodu:','ml':'ഈ വെ%u0D2C%u0D4D%u200Cസൈറ്റിന്റെ ഭാഷ കണ്ടുപിടിയ്ക്കാ%u0D28%u0D4D%u200D കഴിഞ്ഞില്ല. ഭാഷ ഏതാണെന്നു തിരഞ്ഞെടുക്കുക:','nl':'De taal van deze website kan niet automatisch worden bepaald. Geef de hoofdtaal op:','no':'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:','pt':'A língua deste site não pôde ser determinada automaticamente. Por favor indique a língua principal:','ru':'Язык этого сайта не может быть определен автоматически. Пожалуйста укажите язык:','sl':'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:','sv':'Spr%E5ket p%E5 den h%E4r webbplatsen kunde inte avg%F6ras automatiskt. V%E4nligen ange:','tr':'Bu web sitesinin dili otomatik olarak tespit edilememiştir. Lütfen dökümanın dilini seçiniz%A0:','uk':'Мова цього веб-сайту не може бути визначена автоматично. Будь ласка, вкажіть головну мову:'},basePath=(function(){var s=document.getElementsByTagName('script'),i=0,p,src,t;while(!!(t=s[i++])){if(!t.src){continue;}src=t.src;p=src.indexOf('Hyphenator.js');if(p!==-1){return src.substring(0,p);}}return'http://hyphenator.googlecode.com/svn/trunk/';}()),isLocal=(function(){var re=false;if(window.location.href.indexOf(basePath)!==-1){re=true;}return re;}()),documentLoaded=false,documentCount=0,persistentConfig=false,contextWindow=window,doFrames=false,dontHyphenate={'script':true,'code':true,'pre':true,'img':true,'br':true,'samp':true,'kbd':true,'var':true,'abbr':true,'acronym':true,'sub':true,'sup':true,'button':true,'option':true,'label':true,'textarea':true,'input':true,'math':true,'svg':true},enableCache=true,storageType='local',storage,enableReducedPatternSet=false,enableRemoteLoading=true,displayToggleBox=false,css3=false,css3_h9n,css3_gethsupport=function(){var s,ua=navigator.userAgent,r={support:false,property:'',languages:{}};if(window.getComputedStyle){s=window.getComputedStyle(window.document.getElementsByTagName('body')[0]);}else{css3_h9n=r;return;}if(ua.indexOf('Chrome')!==-1){r.support=false;}else if((ua.indexOf('Safari')!==-1)&&(s['-webkit-hyphens']!==undefined)){r.support=true;r.property='-webkit-hyphens';if(ua.indexOf('Mobile')!==-1){r.languages[navigator.language.split('-')[0]]=true;}else{r.languages={de:true,en:true,es:true,fr:true,it:true,nl:true,ru:true,zh:true};}}else if((ua.indexOf('Firefox')!==-1)&&(s['MozHyphens']!==undefined)){r.support=true;r.property='MozHyphens';r.languages={en:true};}css3_h9n=r;},hyphenateClass='hyphenate',dontHyphenateClass='donthyphenate',min=6,orphanControl=1,isBookmarklet=(function(){var loc=null,re=false,jsArray=document.getElementsByTagName('script'),i,l;for(i=0,l=jsArray.length;i<l;i++){if(!!jsArray[i].getAttribute('src')){loc=jsArray[i].getAttribute('src');}if(!loc){continue;}else if(loc.indexOf('Hyphenator.js?bm=true')!==-1){re=true;}}return re;}()),mainLanguage=null,defaultLanguage='',elements=(function(){var Element=function(element,data){this.element=element;this.hyphenated=false;this.treated=false;this.data=data;},ElementCollection=function(){this.count=0;this.hyCount=0;this.list={};};ElementCollection.prototype={add:function(el,lang,data){if(!this.list.hasOwnProperty(lang)){this.list[lang]=[];}this.list[lang].push(new Element(el,data));this.count+=1;},each:function(fn){var k;for(k in this.list){if(this.list.hasOwnProperty(k)){fn(k,this.list[k]);}}}};return new ElementCollection();}()),exceptions={},docLanguages={},state=0,url='(\\w*:\/\/)?((\\w*:)?(\\w*)@)?((([\\d]{1,3}\\.){3}([\\d]{1,3}))|((www\\.|[a-zA-Z]\\.)?[a-zA-Z0-9\\-\\.]+\\.([a-z]{2,4})))(:\\d*)?(\/[\\w#!:\\.?\\+=&%@!\\-]*)*',mail='[\\w-\\.]+@[\\w\\.]+',urlOrMailRE=new RegExp('('+url+')|('+mail+')','i'),zeroWidthSpace=(function(){var zws,ua=navigator.userAgent.toLowerCase();zws=String.fromCharCode(8203);if(ua.indexOf('msie 6')!==-1){zws='';}if(ua.indexOf('opera')!==-1&&ua.indexOf('version/10.00')!==-1){zws='';}return zws;}()),createElem=function(tagname,context){context=context||contextWindow;if(document.createElementNS){return context.document.createElementNS('http://www.w3.org/1999/xhtml',tagname);}else if(document.createElement){return context.document.createElement(tagname);}},onHyphenationDone=function(){},onError=function(e){window.alert("Hyphenator.js says:\n\nAn Error ocurred:\n"+e.message);},selectorFunction=function(){var tmp,el=[],i,l;if(document.getElementsByClassName){el=contextWindow.document.getElementsByClassName(hyphenateClass);}else{tmp=contextWindow.document.getElementsByTagName('*');l=tmp.length;for(i=0;i<l;i++){if(tmp[i].className.indexOf(hyphenateClass)!==-1&&tmp[i].className.indexOf(dontHyphenateClass)===-1){el.push(tmp[i]);}}}return el;},intermediateState='hidden',unhide='wait',hyphen=String.fromCharCode(173),urlhyphen=zeroWidthSpace,safeCopy=true,runOnContentLoaded=function(w,f){var DOMContentLoaded=function(){},toplevel,hyphRunForThis={};if(documentLoaded&&!hyphRunForThis[w.location.href]){f();hyphRunForThis[w.location.href]=true;return;}function init(context){contextWindow=context||window;if(!hyphRunForThis[contextWindow.location.href]&&(!documentLoaded||contextWindow!=window.parent)){documentLoaded=true;f();hyphRunForThis[contextWindow.location.href]=true;}}function doScrollCheck(){try{document.documentElement.doScroll("left");}catch(error){setTimeout(doScrollCheck,1);return;}init(window);}function doOnLoad(){var i,haveAccess,fl=window.frames.length;if(doFrames&&fl>0){for(i=0;i<fl;i++){haveAccess=undefined;try{haveAccess=window.frames[i].document.toString();}catch(e){haveAccess=undefined;}if(!!haveAccess){init(window.frames[i]);}}contextWindow=window;f();hyphRunForThis[window.location.href]=true;}else{init(window);}}if(document.addEventListener){DOMContentLoaded=function(){document.removeEventListener("DOMContentLoaded",DOMContentLoaded,false);if(doFrames&&window.frames.length>0){return;}else{init(window);}};}else if(document.attachEvent){DOMContentLoaded=function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",DOMContentLoaded);if(doFrames&&window.frames.length>0){return;}else{init(window);}}};}if(document.addEventListener){document.addEventListener("DOMContentLoaded",DOMContentLoaded,false);window.addEventListener("load",doOnLoad,false);}else if(document.attachEvent){document.attachEvent("onreadystatechange",DOMContentLoaded);window.attachEvent("onload",doOnLoad);toplevel=false;try{toplevel=window.frameElement===null;}catch(e){}if(document.documentElement.doScroll&&toplevel){doScrollCheck();}}},getLang=function(el,fallback){if(!!el.getAttribute('lang')){return el.getAttribute('lang').toLowerCase();}try{if(!!el.getAttribute('xml:lang')){return el.getAttribute('xml:lang').toLowerCase();}}catch(ex){}if(el.tagName!=='HTML'){return getLang(el.parentNode,true);}if(fallback){return mainLanguage;}return null;},autoSetMainLanguage=function(w){w=w||contextWindow;var el=w.document.getElementsByTagName('html')[0],m=w.document.getElementsByTagName('meta'),i,text,e,ul;mainLanguage=getLang(el,false);if(!mainLanguage){for(i=0;i<m.length;i++){if(!!m[i].getAttribute('http-equiv')&&(m[i].getAttribute('http-equiv').toLowerCase()==='content-language')){mainLanguage=m[i].getAttribute('content').toLowerCase();}if(!!m[i].getAttribute('name')&&(m[i].getAttribute('name').toLowerCase()==='dc.language')){mainLanguage=m[i].getAttribute('content').toLowerCase();}if(!!m[i].getAttribute('name')&&(m[i].getAttribute('name').toLowerCase()==='language')){mainLanguage=m[i].getAttribute('content').toLowerCase();}}}if(!mainLanguage&&doFrames&&contextWindow!=window.parent){autoSetMainLanguage(window.parent);}if(!mainLanguage&&defaultLanguage!==''){mainLanguage=defaultLanguage;}if(!mainLanguage){text='';ul=navigator.language?navigator.language:navigator.userLanguage;ul=ul.substring(0,2);if(prompterStrings.hasOwnProperty(ul)){text=prompterStrings[ul];}else{text=prompterStrings.en;}text+=' (ISO 639-1)\n\n'+languageHint;mainLanguage=window.prompt(unescape(text),ul).toLowerCase();}if(!supportedLang.hasOwnProperty(mainLanguage)){if(supportedLang.hasOwnProperty(mainLanguage.split('-')[0])){mainLanguage=mainLanguage.split('-')[0];}else{e=new Error('The language "'+mainLanguage+'" is not yet supported.');throw e;}}},gatherDocumentInfos=function(){var elToProcess,tmp,i=0,process=function(el,hide,lang){var n,i=0,hyphenatorSettings={};if(el.lang&&typeof(el.lang)==='string'){lang=el.lang.toLowerCase();}else if(lang){lang=lang.toLowerCase();}else{lang=getLang(el,true);}if(css3&&css3_h9n.support&&!!css3_h9n.languages[lang]){el.style[css3_h9n.property]="auto";el.style['-webkit-locale']="'"+lang+"'";}else{if(intermediateState==='hidden'){if(!!el.getAttribute('style')){hyphenatorSettings.hasOwnStyle=true;}else{hyphenatorSettings.hasOwnStyle=false;}hyphenatorSettings.isHidden=true;el.style.visibility='hidden';}if(supportedLang[lang]){docLanguages[lang]=true;}else{if(supportedLang.hasOwnProperty(lang.split('-')[0])){lang=lang.split('-')[0];hyphenatorSettings.language=lang;}else if(!isBookmarklet){onError(new Error('Language '+lang+' is not yet supported.'));}}elements.add(el,lang,hyphenatorSettings);}while(!!(n=el.childNodes[i++])){if(n.nodeType===1&&!dontHyphenate[n.nodeName.toLowerCase()]&&n.className.indexOf(dontHyphenateClass)===-1&&!(n in elToProcess)){process(n,false,lang);}}};if(css3){css3_gethsupport();}if(isBookmarklet){elToProcess=contextWindow.document.getElementsByTagName('body')[0];process(elToProcess,false,mainLanguage);}else{elToProcess=selectorFunction();while(!!(tmp=elToProcess[i++])){process(tmp,true,'');}}if(elements.count===0){state=3;onHyphenationDone();}},convertPatterns=function(lang){var size=0,tree={tpoints:[]},patterns,pattern,i,j,k,patternObject=Hyphenator.languages[lang].patterns,c,chars,points,t,p,codePoint,getPoints=(function(){if('in3se'.split(/\D/).length===1){return function(pattern){var chars=pattern.split(''),c,i,r=[],numb3rs={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9},lastWasNum=false;i=0;while(!!(c=chars[i])){if(numb3rs.hasOwnProperty(c)){r.push(c);i+=2;lastWasNum=true;}else{r.push('');i+=1;lastWasNum=false;}}if(!lastWasNum){r.push('');}return r;};}else{return function(pattern){return pattern.split(/\D/);};}}());for(size in patternObject){if(patternObject.hasOwnProperty(size)){patterns=patternObject[size].match(new RegExp('.{1,'+(+size)+'}','g'));i=0;while(!!(pattern=patterns[i++])){chars=pattern.replace(/[\d]/g,'').split('');points=getPoints(pattern);t=tree;j=0;while(!!(c=chars[j++])){codePoint=c.charCodeAt(0);if(!t[codePoint]){t[codePoint]={};}t=t[codePoint];}t.tpoints=[];for(k=0;k<points.length;k++){p=points[k];t.tpoints.push((p=="")?0:p);}}}}Hyphenator.languages[lang].patterns=tree;},recreatePattern=function(pattern,nodePoints){var r=[],c=pattern.split(''),i;for(i=0;i<nodePoints.length;i++){if(nodePoints[i]!==0){r.push(nodePoints[i]);}if(c[i]){r.push(c[i]);}}return r.join('');},convertExceptionsToObject=function(exc){var w=exc.split(', '),r={},i,l,key;for(i=0,l=w.length;i<l;i++){key=w[i].replace(/-/g,'');if(!r.hasOwnProperty(key)){r[key]=w[i];}}return r;},loadPatterns=function(lang){var url,xhr,head,script;if(supportedLang[lang]&&!Hyphenator.languages[lang]){url=basePath+'patterns/'+supportedLang[lang];}else{return;}if(isLocal&&!isBookmarklet){xhr=null;if(typeof XMLHttpRequest!=='undefined'){xhr=new XMLHttpRequest();}if(!xhr){try{xhr=new ActiveXObject("Msxml2.XMLHTTP");}catch(e){xhr=null;}}if(xhr){xhr.open('HEAD',url,false);xhr.setRequestHeader('Cache-Control','no-cache');xhr.send(null);if(xhr.status===404){onError(new Error('Could not load\n'+url));delete docLanguages[lang];return;}}}if(createElem){head=window.document.getElementsByTagName('head').item(0);script=createElem('script',window);script.src=url;script.type='text/javascript';head.appendChild(script);}},prepareLanguagesObj=function(lang){var lo=Hyphenator.languages[lang],wrd;if(!lo.prepared){if(enableCache){lo.cache={};lo['cache']=lo.cache;}if(enableReducedPatternSet){lo.redPatSet={};}if(lo.hasOwnProperty('exceptions')){Hyphenator.addExceptions(lang,lo.exceptions);delete lo.exceptions;}if(exceptions.hasOwnProperty('global')){if(exceptions.hasOwnProperty(lang)){exceptions[lang]+=', '+exceptions.global;}else{exceptions[lang]=exceptions.global;}}if(exceptions.hasOwnProperty(lang)){lo.exceptions=convertExceptionsToObject(exceptions[lang]);delete exceptions[lang];}else{lo.exceptions={};}convertPatterns(lang);wrd='[\\w'+lo.specialChars+'@'+String.fromCharCode(173)+String.fromCharCode(8204)+'-]{'+min+',}';lo.genRegExp=new RegExp('('+url+')|('+mail+')|('+wrd+')','gi');lo.prepared=true;}if(!!storage){try{storage.setItem('Hyphenator_'+lang,window.JSON.stringify(lo));}catch(e){}}},prepare=function(callback){var lang,interval,tmp1,tmp2;if(!enableRemoteLoading){for(lang in Hyphenator.languages){if(Hyphenator.languages.hasOwnProperty(lang)){prepareLanguagesObj(lang);}}state=2;callback('*');return;}state=1;for(lang in docLanguages){if(docLanguages.hasOwnProperty(lang)){if(!!storage&&storage.getItem('Hyphenator_'+lang)){Hyphenator.languages[lang]=window.JSON.parse(storage.getItem('Hyphenator_'+lang));if(exceptions.hasOwnProperty('global')){tmp1=convertExceptionsToObject(exceptions.global);for(tmp2 in tmp1){if(tmp1.hasOwnProperty(tmp2)){Hyphenator.languages[lang].exceptions[tmp2]=tmp1[tmp2];}}}if(exceptions.hasOwnProperty(lang)){tmp1=convertExceptionsToObject(exceptions[lang]);for(tmp2 in tmp1){if(tmp1.hasOwnProperty(tmp2)){Hyphenator.languages[lang].exceptions[tmp2]=tmp1[tmp2];}}delete exceptions[lang];}tmp1='[\\w'+Hyphenator.languages[lang].specialChars+'@'+String.fromCharCode(173)+String.fromCharCode(8204)+'-]{'+min+',}';Hyphenator.languages[lang].genRegExp=new RegExp('('+url+')|('+mail+')|('+tmp1+')','gi');delete docLanguages[lang];callback(lang);continue;}else{loadPatterns(lang);}}}interval=window.setInterval(function(){var finishedLoading=true,lang;for(lang in docLanguages){if(docLanguages.hasOwnProperty(lang)){finishedLoading=false;if(!!Hyphenator.languages[lang]){delete docLanguages[lang];prepareLanguagesObj(lang);callback(lang);}}}if(finishedLoading){window.clearInterval(interval);state=2;}},100);},toggleBox=function(){var myBox,bdy,myIdAttribute,myTextNode,myClassAttribute,text=(Hyphenator.doHyphenation?'Hy-phen-a-tion':'Hyphenation');if(!!(myBox=contextWindow.document.getElementById('HyphenatorToggleBox'))){myBox.firstChild.data=text;}else{bdy=contextWindow.document.getElementsByTagName('body')[0];myBox=createElem('div',contextWindow);myIdAttribute=contextWindow.document.createAttribute('id');myIdAttribute.nodeValue='HyphenatorToggleBox';myClassAttribute=contextWindow.document.createAttribute('class');myClassAttribute.nodeValue=dontHyphenateClass;myTextNode=contextWindow.document.createTextNode(text);myBox.appendChild(myTextNode);myBox.setAttributeNode(myIdAttribute);myBox.setAttributeNode(myClassAttribute);myBox.onclick=Hyphenator.toggleHyphenation;myBox.style.position='absolute';myBox.style.top='0px';myBox.style.right='0px';myBox.style.margin='0';myBox.style.backgroundColor='#AAAAAA';myBox.style.color='#FFFFFF';myBox.style.font='6pt Arial';myBox.style.letterSpacing='0.2em';myBox.style.padding='3px';myBox.style.cursor='pointer';myBox.style.WebkitBorderBottomLeftRadius='4px';myBox.style.MozBorderRadiusBottomleft='4px';bdy.appendChild(myBox);}},hyphenateWord=function(lang,word){var lo=Hyphenator.languages[lang],parts,l,subst,w,characters,originalCharacters,wordLength,i,j,k,node,points=[],characterPoints=[],nodePoints,nodePointsLength,m=Math.max,trie,result=[''],pattern;if(word===''){return'';}if(word.indexOf(hyphen)!==-1){return word;}if(enableCache&&lo.cache.hasOwnProperty(word)){return lo.cache[word];}if(lo.exceptions.hasOwnProperty(word)){return lo.exceptions[word].replace(/-/g,hyphen);}if(word.indexOf('-')!==-1){parts=word.split('-');for(i=0,l=parts.length;i<l;i++){parts[i]=hyphenateWord(lang,parts[i]);}return parts.join('-');}w=word='_'+word+'_';if(!!lo.charSubstitution){for(subst in lo.charSubstitution){if(lo.charSubstitution.hasOwnProperty(subst)){w=w.replace(new RegExp(subst,'g'),lo.charSubstitution[subst]);}}}if(word.indexOf("'")!==-1){w=w.replace("'","’");}characters=w.toLowerCase().split('');originalCharacters=word.split('');wordLength=characters.length;trie=lo.patterns;for(i=0;i<wordLength;i+=1){points[i]=0;characterPoints[i]=characters[i].charCodeAt(0);}for(i=0;i<wordLength;i+=1){pattern='';node=trie;for(j=i;j<wordLength;j+=1){node=node[characterPoints[j]];if(node){if(enableReducedPatternSet){pattern+=String.fromCharCode(characterPoints[j]);}nodePoints=node.tpoints;if(nodePoints){if(enableReducedPatternSet){if(!lo.redPatSet){lo.redPatSet={};}lo.redPatSet[pattern]=recreatePattern(pattern,nodePoints);}for(k=0,nodePointsLength=nodePoints.length;k<nodePointsLength;k+=1){points[i+k]=m(points[i+k],nodePoints[k]);}}}else{break;}}}for(i=1;i<wordLength-1;i+=1){if(i>lo.leftmin&&i<(wordLength-lo.rightmin)&&points[i]%2){result.push(originalCharacters[i]);}else{result[result.length-1]+=originalCharacters[i];}}return result.join(hyphen);},hyphenateURL=function(url){return url.replace(/([:\/\.\?#&_,;!@]+)/gi,'$&'+urlhyphen);},removeHyphenationFromElement=function(el){var h,i=0,n;switch(hyphen){case'|':h='\\|';break;case'+':h='\\+';break;case'*':h='\\*';break;default:h=hyphen;}while(!!(n=el.childNodes[i++])){if(n.nodeType===3){n.data=n.data.replace(new RegExp(h,'g'),'');n.data=n.data.replace(new RegExp(zeroWidthSpace,'g'),'');}else if(n.nodeType===1){removeHyphenationFromElement(n);}}},registerOnCopy=function(el){var body=el.ownerDocument.getElementsByTagName('body')[0],shadow,selection,range,rangeShadow,restore,oncopyHandler=function(e){e=e||window.event;var target=e.target||e.srcElement,currDoc=target.ownerDocument,body=currDoc.getElementsByTagName('body')[0],targetWindow='defaultView'in currDoc?currDoc.defaultView:currDoc.parentWindow;if(target.tagName&&dontHyphenate[target.tagName.toLowerCase()]){return;}shadow=currDoc.createElement('div');shadow.style.color=window.getComputedStyle?targetWindow.getComputedStyle(body).backgroundColor:'#FFFFFF';shadow.style.fontSize='0px';body.appendChild(shadow);if(!!window.getSelection){e.stopPropagation();selection=targetWindow.getSelection();range=selection.getRangeAt(0);shadow.appendChild(range.cloneContents());removeHyphenationFromElement(shadow);selection.selectAllChildren(shadow);restore=function(){shadow.parentNode.removeChild(shadow);selection.removeAllRanges();selection.addRange(range);};}else{e.cancelBubble=true;selection=targetWindow.document.selection;range=selection.createRange();shadow.innerHTML=range.htmlText;removeHyphenationFromElement(shadow);rangeShadow=body.createTextRange();rangeShadow.moveToElementText(shadow);rangeShadow.select();restore=function(){shadow.parentNode.removeChild(shadow);if(range.text!==""){range.select();}};}window.setTimeout(restore,0);};if(!body){return;}el=el||body;if(window.addEventListener){el.addEventListener("copy",oncopyHandler,true);}else{el.attachEvent("oncopy",oncopyHandler);}},unhideElement=function(elo){var el=elo.element,hyphenatorSettings=elo.data;el.style.visibility='visible';elo.data.isHidden=false;if(!hyphenatorSettings.hasOwnStyle){el.setAttribute('style','');el.removeAttribute('style');}else{if(el.style.removeProperty){el.style.removeProperty('visibility');}else if(el.style.removeAttribute){el.style.removeAttribute('visibility');}}},checkIfAllDone=function(){var allDone=true;elements.each(function(lang,list){var i,l=list.length;for(i=0;i<l;i++){allDone=allDone&&list[i].hyphenated;if(intermediateState==='hidden'&&unhide==='wait'){unhideElement(list[i]);}}});if(allDone){state=3;onHyphenationDone();}},hyphenateElement=function(lang,elo){var hyphenatorSettings=elo.data,el=elo.element,hyphenate,n,i,controlOrphans=function(part){var h,r;switch(hyphen){case'|':h='\\|';break;case'+':h='\\+';break;case'*':h='\\*';break;default:h=hyphen;}if(orphanControl>=2){r=part.split(' ');r[1]=r[1].replace(new RegExp(h,'g'),'');r[1]=r[1].replace(new RegExp(zeroWidthSpace,'g'),'');r=r.join(' ');}if(orphanControl===3){r=r.replace(/[ ]+/g,String.fromCharCode(160));}return r;};if(Hyphenator.languages.hasOwnProperty(lang)){hyphenate=function(word){if(!Hyphenator.doHyphenation){return word;}else if(urlOrMailRE.test(word)){return hyphenateURL(word);}else{return hyphenateWord(lang,word);}};if(safeCopy&&(el.tagName.toLowerCase()!=='body')){registerOnCopy(el);}i=0;while(!!(n=el.childNodes[i++])){if(n.nodeType===3&&n.data.length>=min){n.data=n.data.replace(Hyphenator.languages[lang].genRegExp,hyphenate);if(orphanControl!==1){n.data=n.data.replace(/[\S]+ [\S]+$/,controlOrphans);}}}}if(hyphenatorSettings.isHidden&&intermediateState==='hidden'&&unhide==='progressive'){unhideElement(elo);}elo.hyphenated=true;elements.hyCount+=1;if(elements.count<=elements.hyCount){checkIfAllDone();}},hyphenateLanguageElements=function(lang){function bind(fun,arg1,arg2){return function(){return fun(arg1,arg2);};}var el,i,l;if(lang==='*'){elements.each(function(lang,langels){var i,l=langels.length;for(i=0;i<l;i++){window.setTimeout(bind(hyphenateElement,lang,langels[i]),0);}});}else{if(elements.list.hasOwnProperty(lang)){l=elements.list[lang].length;for(i=0;i<l;i++){window.setTimeout(bind(hyphenateElement,lang,elements.list[lang][i]),0);}}}},removeHyphenationFromDocument=function(){elements.each(function(lang,elo){var i,l=elo.length,el;for(i=0;i<l;i++){removeHyphenationFromElement(elo[i].element);elo[i].hyphenated=false;}});state=4;},createStorage=function(){try{if(storageType!=='none'&&typeof(window.localStorage)!=='undefined'&&typeof(window.sessionStorage)!=='undefined'&&typeof(window.JSON.stringify)!=='undefined'&&typeof(window.JSON.parse)!=='undefined'){switch(storageType){case'session':storage=window.sessionStorage;break;case'local':storage=window.localStorage;break;default:storage=undefined;break;}}}catch(f){}},storeConfiguration=function(){if(!storage){return;}var settings={'STORED':true,'classname':hyphenateClass,'donthyphenateclassname':dontHyphenateClass,'minwordlength':min,'hyphenchar':hyphen,'urlhyphenchar':urlhyphen,'togglebox':toggleBox,'displaytogglebox':displayToggleBox,'remoteloading':enableRemoteLoading,'enablecache':enableCache,'onhyphenationdonecallback':onHyphenationDone,'onerrorhandler':onError,'intermediatestate':intermediateState,'selectorfunction':selectorFunction,'safecopy':safeCopy,'doframes':doFrames,'storagetype':storageType,'orphancontrol':orphanControl,'dohyphenation':Hyphenator.doHyphenation,'persistentconfig':persistentConfig,'defaultlanguage':defaultLanguage};storage.setItem('Hyphenator_config',window.JSON.stringify(settings));},restoreConfiguration=function(){var settings;if(storage.getItem('Hyphenator_config')){settings=window.JSON.parse(storage.getItem('Hyphenator_config'));Hyphenator.config(settings);}};return{version:'4.0.0',doHyphenation:true,languages:{},config:function(obj){var assert=function(name,type){if(typeof obj[name]===type){return true;}else{onError(new Error('Config onError: '+name+' must be of type '+type));return false;}},key;if(obj.hasOwnProperty('storagetype')){if(assert('storagetype','string')){storageType=obj.storagetype;}if(!storage){createStorage();}}if(!obj.hasOwnProperty('STORED')&&storage&&obj.hasOwnProperty('persistentconfig')&&obj.persistentconfig===true){restoreConfiguration();}for(key in obj){if(obj.hasOwnProperty(key)){switch(key){case'STORED':break;case'classname':if(assert('classname','string')){hyphenateClass=obj[key];}break;case'donthyphenateclassname':if(assert('donthyphenateclassname','string')){dontHyphenateClass=obj[key];}break;case'minwordlength':if(assert('minwordlength','number')){min=obj[key];}break;case'hyphenchar':if(assert('hyphenchar','string')){if(obj.hyphenchar==='­'){obj.hyphenchar=String.fromCharCode(173);}hyphen=obj[key];}break;case'urlhyphenchar':if(obj.hasOwnProperty('urlhyphenchar')){if(assert('urlhyphenchar','string')){urlhyphen=obj[key];}}break;case'togglebox':if(assert('togglebox','function')){toggleBox=obj[key];}break;case'displaytogglebox':if(assert('displaytogglebox','boolean')){displayToggleBox=obj[key];}break;case'remoteloading':if(assert('remoteloading','boolean')){enableRemoteLoading=obj[key];}break;case'enablecache':if(assert('enablecache','boolean')){enableCache=obj[key];}break;case'enablereducedpatternset':if(assert('enablereducedpatternset','boolean')){enableReducedPatternSet=obj[key];}break;case'onhyphenationdonecallback':if(assert('onhyphenationdonecallback','function')){onHyphenationDone=obj[key];}break;case'onerrorhandler':if(assert('onerrorhandler','function')){onError=obj[key];}break;case'intermediatestate':if(assert('intermediatestate','string')){intermediateState=obj[key];}break;case'selectorfunction':if(assert('selectorfunction','function')){selectorFunction=obj[key];}break;case'safecopy':if(assert('safecopy','boolean')){safeCopy=obj[key];}break;case'doframes':if(assert('doframes','boolean')){doFrames=obj[key];}break;case'storagetype':if(assert('storagetype','string')){storageType=obj[key];}break;case'orphancontrol':if(assert('orphancontrol','number')){orphanControl=obj[key];}break;case'dohyphenation':if(assert('dohyphenation','boolean')){Hyphenator.doHyphenation=obj[key];}break;case'persistentconfig':if(assert('persistentconfig','boolean')){persistentConfig=obj[key];}break;case'defaultlanguage':if(assert('defaultlanguage','string')){defaultLanguage=obj[key];}break;case'useCSS3hyphenation':if(assert('useCSS3hyphenation','boolean')){css3=obj[key];}break;case'unhide':if(assert('unhide','string')){unhide=obj[key];}break;default:onError(new Error('Hyphenator.config: property '+key+' not known.'));}}}if(storage&&persistentConfig){storeConfiguration();}},run:function(){documentCount=0;var process=function(){try{if(contextWindow.document.getElementsByTagName('frameset').length>0){return;}documentCount++;autoSetMainLanguage(undefined);gatherDocumentInfos();prepare(hyphenateLanguageElements);if(displayToggleBox){toggleBox();}}catch(e){onError(e);}},i,haveAccess,fl=window.frames.length;if(!storage){createStorage();}if(!documentLoaded&&!isBookmarklet){runOnContentLoaded(window,process);}if(isBookmarklet||documentLoaded){if(doFrames&&fl>0){for(i=0;i<fl;i++){haveAccess=undefined;try{haveAccess=window.frames[i].document.toString();}catch(e){haveAccess=undefined;}if(!!haveAccess){contextWindow=window.frames[i];process();}}}contextWindow=window;process();}},addExceptions:function(lang,words){if(lang===''){lang='global';}if(exceptions.hasOwnProperty(lang)){exceptions[lang]+=", "+words;}else{exceptions[lang]=words;}},hyphenate:function(target,lang){var hyphenate,n,i;if(Hyphenator.languages.hasOwnProperty(lang)){if(!Hyphenator.languages[lang].prepared){prepareLanguagesObj(lang);}hyphenate=function(word){if(urlOrMailRE.test(word)){return hyphenateURL(word);}else{return hyphenateWord(lang,word);}};if(typeof target==='string'||target.constructor===String){return target.replace(Hyphenator.languages[lang].genRegExp,hyphenate);}else if(typeof target==='object'){i=0;while(!!(n=target.childNodes[i++])){if(n.nodeType===3&&n.data.length>=min){n.data=n.data.replace(Hyphenator.languages[lang].genRegExp,hyphenate);}else if(n.nodeType===1){if(n.lang!==''){Hyphenator.hyphenate(n,n.lang);}else{Hyphenator.hyphenate(n,lang);}}}}}else{onError(new Error('Language "'+lang+'" is not loaded.'));}},getRedPatternSet:function(lang){return Hyphenator.languages[lang].redPatSet;},isBookmarklet:function(){return isBookmarklet;},getConfigFromURI:function(){var loc=null,re={},jsArray=document.getElementsByTagName('script'),i,j,l,s,gp,option;for(i=0,l=jsArray.length;i<l;i++){if(!!jsArray[i].getAttribute('src')){loc=jsArray[i].getAttribute('src');}if(!loc){continue;}else{s=loc.indexOf('Hyphenator.js?');if(s===-1){continue;}gp=loc.substring(s+14).split('&');for(j=0;j<gp.length;j++){option=gp[j].split('=');if(option[0]==='bm'){continue;}if(option[1]==='true'){re[option[0]]=true;continue;}if(option[1]==='false'){re[option[0]]=false;continue;}if(isFinite(option[1])){re[option[0]]=parseInt(option[1],10);continue;}if(option[0]==='onhyphenationdonecallback'){re[option[0]]=new Function('',option[1]);continue;}re[option[0]]=option[1];}break;}}return re;},toggleHyphenation:function(){if(Hyphenator.doHyphenation){removeHyphenationFromDocument();Hyphenator.doHyphenation=false;storeConfiguration();toggleBox();}else{hyphenateLanguageElements('*');Hyphenator.doHyphenation=true;storeConfiguration();toggleBox();}}};}(window));Hyphenator['languages']=Hyphenator.languages;Hyphenator['config']=Hyphenator.config;Hyphenator['run']=Hyphenator.run;Hyphenator['addExceptions']=Hyphenator.addExceptions;Hyphenator['hyphenate']=Hyphenator.hyphenate;Hyphenator['getRedPatternSet']=Hyphenator.getRedPatternSet;Hyphenator['isBookmarklet']=Hyphenator.isBookmarklet;Hyphenator['getConfigFromURI']=Hyphenator.getConfigFromURI;Hyphenator['toggleHyphenation']=Hyphenator.toggleHyphenation;window['Hyphenator']=Hyphenator;if(Hyphenator.isBookmarklet()){Hyphenator.config({displaytogglebox:true,intermediatestate:'visible',doframes:true});Hyphenator.config(Hyphenator.getConfigFromURI());Hyphenator.run();}Hyphenator.languages['en-us']=Hyphenator.languages['en']={leftmin:2,rightmin:3,specialChars:"",patterns:{3:"x1qei2e1je1f1to2tlou2w3c1tue1q4tvtw41tyo1q4tz4tcd2yd1wd1v1du1ta4eu1pas4y1droo2d1psw24sv1dod1m1fad1j1su4fdo2n4fh1fi4fm4fn1fopd42ft3fu1fy1ga2sss1ru5jd5cd1bg3bgd44uk2ok1cyo5jgl2g1m4pf4pg1gog3p1gr1soc1qgs2oi2g3w1gysk21coc5nh1bck1h1fh1h4hk1zo1ci4zms2hh1w2ch5zl2idc3c2us2igi3hi3j4ik1cab1vsa22btr1w4bp2io2ipu3u4irbk4b1j1va2ze2bf4oar1p4nz4zbi1u2iv4iy5ja1jeza1y1wk1bk3fkh4k1ikk4k1lk1mk5tk1w2ldr1mn1t2lfr1lr3j4ljl1l2lm2lp4ltn1rrh4v4yn1q1ly1maw1brg2r1fwi24ao2mhw4kr1cw5p4mkm1m1mo4wtwy4x1ar1ba2nn5mx1ex1h4mtx3i1muqu2p3wx3o4mwa1jx3p1naai2x1ua2fxx4y1ba2dn1jy1cn3fpr2y1dy1i",4:"4dryn2itni4on1inn1im_up3nik4ni4dy5giye4tyes4_ye44ab_nhe4nha4abe2n2gyn1guy1ery5eep2pe4abry3lay3lone4wne4v1nesy3chn1erne2q3neo1nenp2seps4hy2cey5lu2nedne2cyme44nk2y5at2adine2b2ne_y5ac2p1tp2ten1den1cun1cryn5dp2th4adup4twpub3ae4rxu3ayn5gaff4pue4n2au4p1ppuf4n2atag1ipu4mag1na2gon4asx3tix1t2pu2na4gya3haa3heah4la3ho_ti2a5ian2an5puspu2tnak4_th2n1kl_te4_ta4mu4u4mupmun23mum2alex4ob_sy25ynxal1i_st4y1o4xi5cxi5a4alm_si2_sh2m5sixhu4m4sh4m3r4amam2py2rabm2pixhi2yo5dr2ai4m1pmo2vmos2x2edmo2r4n1la2mor2asx3c2xas5yom4x4apxam3nme44mokrbi2nne44andy4osp4ot3noemn4omn4a4m1n4nog4m1l2angws4l1posw3shwri4wra4yp3iwom11wo2m2izrb4ow4nopo4pr2cem2isrd2iano4mig4y3pomi3awiz55mi_no4n4m1fme4v2re_wir42mes1menme2mme2gre1o2med4me_4nop4m5c4m1bwil21noureu2whi4w3ev4maprev2w1era2plpo4crfu4r4fyy5pu2maha3pu2mab2a2rn1p4npi44lyb4lya2p3nwam42l1w1lut4luplu3or1glluf4lu5a2wacltu2y3rol1tr4vv4r3guyr4rl1te4rh_nru4ar1il2sel4sc4l1rl5prl4plys4c4lovri3ar4ib4lof3lo_ar2par3q_os3ll4oll2i4as_ri1o3vokl2levoi44p1mlka35vo_ns4cas4ll1izr4iqr2is3vivl1it3lika2tan2sen2slrle42l3hlgo3l5gal5frns3mvi4p3ley_od2r2meles24athr4myle2al3drv1inldi4l2de2vilnt2il3civik4lce42l1b4lavv3ifrno4r3nua1trr2ocnt4sy4sok4syks4la2tuk4sck3ouko5ryss4a2tyau4b4klyys1tnu1akis4au3rki4pro4ek4ima2va5ki_nu4dn4umn3uokes4k1erav1irok2ke4g1keek2ed_me2aw3ikal4aws4k5agk3ab3ka_aye4ays4veg3jo4p5ba_4vedjew3n1v24ve_ja4pzar23vatizi4n1w41batba4z2b1bb2beix4o4i5w4b1d4be_rox5nym4nyp4n3za4ittr3por1r4i1ti1bel2ith2itei2su4rs2r1sars4cr2seis1p3betvag4i2sor1shbe3wr1sioad34b3hbi2bbi4d3bie3isf4ise2is_1bilr1sp5va_r5sw_le2uz4eir1ibi2tuxu3r1tiu1v2i1raze4nze4pb2l2uu4mo1biip3iz1eripe4b4louts44b1m4b3no3br3bodi4osbo4eru3aio4mi1ol4io_3booo1ce4inyin1u2insru2n2inn4inl4inkrv4e2inioch42iner3vo4indpi2np4idbt4lb4tob3trry4cry3t2in_o4elbu4ni2muim1i5saiil3v4ilnil1iil5fs1apo3er4b5w5by_bys4_in1sau4i1lazet4u2suo3ev2z1ii2go4igius1p5saw4s5bo2fi4ifti3fl4if_i3etsch2usc22ie4i2dui4dri2diid5dpi3au3ruz4ils1cuz4is4s5d4se_se4a2ce_2ici4ich3ceii1bri5bo1ceni1blse2g5seiibe43cepi2aniam4ur2li2al2i1acet4hy2scew41phy4ch_5phuhu4thu4gche2h4tyh4shur1durc44hr44h5p5sev5sexu1ra4s3fup3p2s3gph3t2sh_ho4g2h1n_he23ciau3pl4h1mci5ch2lozo4m4ciihi2vhi4p2cim2cin4phsu1peu1ouo1geu5osheu4sho4he4th1es4shwun5zun5ysi1bunu45cizo4glck3ihep5he2nh4ed1sioph2l5hazsi2rcly4zte4_ge21siscoe22cog5siu1siv5siz_ga24skes1l2s2leha4m2s1ms3ma1ogyo1h2u1ni3gus3gun2guegu4acov1gth3_eu3g4ros1n4_es3u2nez4zyum2pu1mi3som_ev2oig4cri2gov15goos4opgon2ul5v5goeu3lugob53go_2c1t4ph_g1nog1nic2te4sov4ulsgn4ag4myc4twcud5c4ufc4uipe2t3glo1gleul2igla4_eg23giz3cun5givgi4u3gir5gio1cusul4e2spagil4g1ic5gi__eb4cze41d2a5da_u1laggo44daf2dagg2gege4v1geo1gen2ged3dato1la2ge_ol2dol2i5daypek4p4eed1d42de_4gazol2tuiv3ol2vo2lys1sa2gamgaf4o2meui4n2ui2pe2cd4em4fugi4jku3fl3ufaf2tyf4to1denu4du4pe_2f3sfri2de1ps1si4f5pfos5d3eqs4sls4snfo2rss2tdes25fon4p1b_ci23payss5w2st_de1tf4l2de1v2fin4dey4d1fd4gast2idg1id2gyd1h25di_ud5dfi3au4cy_ch4pav43didu3cud1iff2fyu3crd1inst4r4f1ffev4fer11dio2fedfe4bdir2s2ty4fe_dis1on1au3ca4f5bon1c2ondd5k25far4fagpa1peys45eyc1exps4ul2dlyp4ale3whon3s3do_e1wa5doee5vud4oge1visu2msu2nub4euav4su2rp4ai6rk_d4or3dosu1atdo4v3doxp4adoo4k4swoo2padre4eus4e3upe5un2ophet5z4syc3syl4y3hoy1ads4pd4swd4syd2tho4wo3ta_du2c4etn2tabta2luac4es4wdu4g2ess4uabdu4n4duptav4st5bow1io1pr5dyn2tawe1sp2t1bop1uead1tz4et4chopy5ea4l4t1d4te_2tyle1si4esh1tee4tyat1cr4twoteg4es2c4eru1teoer1s2eroea2tte4po1rat1wh3tusea2v3teu3texer1i2e1ber1h4tey2t1f4t1ge3br2th_th2e4thle1ce3tumec2i2ths2erb1tia4tueer1aou5vtud2tif22tige1potu1aou4lttu41timt5toos4le1cre2pat4swe5owe1cue4ottsh4eos4e1ort4sce3ol4edieo2ge5of1tio4eno4enn5tiq4edoti4u1tive3my1tiz4othee2ct5laee2ft5lo4t1mee2mtme4e1meem5bcoi4to3be5exo1ry2tof1effel2iel2ftos24t1pe1la1traos2ceig2ei5de5ico2soe1h45egyeg5n",5:"_ach4e4go_e4goseg1ule5gurtre5feg4iceher4eg5ibeger44egaltre4mei5gle3imbe3infe1ingtra3beir4deit3eei3the5ity5triae4jud3efiteki4nek4la2trime4la_e4lactri4v4toute4law5toure3leaefil45elece4ledto2rae5len4tonye1lestro3ve4fic4tonoto3mytom4bto2mato5ice5limto2gre3lioe2listru5i4todo4ellaee4tyello4e5locel5ogeest4el2shel4tae5ludel5uge4mace4mage5man2t1n2ee2s4ee4p1e2mele4metee4naemi4eee4lyeel3i3tled3tle_e4mistlan4eed3iem3iztrus4emo4gti3zaem3pie4mule4dulemu3ne4dritiv4aedon2e4dolti3tle5neae5neeen3emtis4pti5sotis4m3tisee3newti3sae5niee5nile3nioedi5zen3ite5niu5enized1ited3imeno4ge4nosen3oven4swti5oc4t1s2en3uaen5ufe3ny_4en3zed3ibe3diae4oi4ede4s3tini4ed3deo3ret2ina2e2dae4culeo4toe5outec4te4t3t2t4tes2t1ine5pel4timpe2corephe4e4plie2col5tigutu3arti5fytu4bie3pro3tienep4sh5tidie4putt4icoeci4t4tick2ti2bec3imera4bti4aber3ar4tuf45tu3ier4bler3che4cib2ere_4thooecca54thil3thet4thea3turethan4e4cade4bitere4qe4ben5turieret4tur5oeav5oeav5itu5ry4tess4tes_ter5ve1rio4eriter4iueri4v1terier3m4ter3cte5pe4t1waer3noeast3er5obe5rocero4rer1oue3assea5sp1tent4ertler3twtwis4eru4t3tende1s4a3tenc5telsear2te2scateli4e3scres5cue1s2ee2sec3tel_te5giear5kear4cte5diear3ae3sha2t1ede5ande2sice2sid5tecttece44teattype3ty5phesi4uea4gees4mie2sole3acte2sone1a4bdys5pdy4sedu4petaun4d3uleta5sytas4e4tare4tarctar4ata5pl2estrta5mo4talke2surtal3idu5eleta4bta5lae3teoua5naet1ic4taf4etin4ta5doe5tir4taciuan4id1ucad1u1ae3trae3tre2d1s2syn5ouar2d4drowet3uaet5ymdro4pdril4dri4b5dreneu3rouar3ieute44draieu5truar3te2vasdop4pe5veadoo3ddoni4u4belsum3iev1erdoli4do4laev3idevi4le4vinevi4ve5voc2d5ofdo5dee4wage5wee4d1n4ewil54d5lue3wit2d3lou3ber5eye_u1b4i3dledfa3blfab3rfa4ce3dle_fain4suit3su5issu2g34d5lasu4b3fa3tasu1al4fato1di1vd2iti5disiuci4bfeas4di1redi4pl4feca5fectdio5gfe3life4mofen2d4st3wuc4it5ferr5diniucle3f4fesf4fie4stry1dinaf4flydi3ge3dictd4icedia5bs4tops1tle5stirs3tifs4ties1ticfic4is5tias4ti_4ficsfi3cuud3ers3thefil5iste2w4filyudev45finas4tedfi2nes2talfin4ns2tagde2tode4suflin4u1dicf2ly5ud5isu5ditde1scd2es_der5sfon4tu4don5dermss4lid4erhfor4is4siede2pudepi4fra4tf5reade3pade3nufril4frol5ud4side3nou4eneuens4ug5infu5el5dem_s5setfu5nefu3rifusi4fus4s4futade5lode5if4dee_5gal_3galiga3lo2d1eds3selg5amos2s5cssas3u1ing4ganouir4mgass4gath3uita4deaf5dav5e5dav44dato4darygeez44spotspor4s4pon4gelydark5s4ply4spio4geno4genydard5ge3omg4ery5gesigeth54getoge4tydan3g4g1g2da2m2g3gergglu5dach4gh3inspil4gh4to4cutr1gi4agia5rula5bspho5g4icogien5s2pheulch42sperspa4n5spai3c4utu1lenul4gigir4lg3islcu5pycu3picu4mic3umecu2maso5vi5glasu5liagli4bg3lig5culiglo3r4ul3mctu4ru1l4og4na_c3terul1tig2ning4nio4ultug4noncta4b4c3s2cru4dul5ulsor5dgo3isum5absor5ccris4go3nic4rinson4gsona45gos_cri5fcre4vum4bi5credg4raigran25solvsoft3so4ceunat44graygre4nco5zi4gritcoz5egruf4cow5ag5stecove4cos4es5menun4ersmel44corbco4pl4gu4tco3pacon5tsman3gy5racon3ghach4hae4mhae4th5aguha3lac4onecon4aun4ims3latu2ninhan4gs3ket5colocol5ihan4kuni3vhap3lhap5ttras4co4grhar2dco5agsir5aclim45sionhas5shaun44clichaz3acle4m1head3hearun3s4s3ingun4sws2ina2s1in4silysil4eh5elohem4p4clarhena45sidiheo5r1c4l4h4eras5icc2c1itu4orsh3ernshor4h3eryci3phshon34cipecion45cinoc1ingc4inahi5anhi4cohigh5h4il2shiv5h4ina3ship3cilihir4lhi3rohir4phir4rsh3iohis4ssh1inci4lau5pia4h1l4hlan44cier5shevcia5rhmet4ch4tish1erh5ods3cho2hoge4chi2z3chitho4mahome3hon4aho5ny3hoodhoon45chiouptu44ura_ho5ruhos4esew4ihos1p1housu4ragses5tu4rasur4behree5se5shs1e4s4h1s24chedh4tarht1enht5esur4fru3rifser4os4erlhun4tsen5gur1inu3riosen4dhy3pehy3phu1ritces5tur3iz4cesa4sencur4no4iancian3i4semeia5peiass45selv5selfi4atu3centse1le4ceniib5iaib3inseg3ruros43cencib3li3cell5cel_s5edli5bun4icam5icap4icar4s4ed3secticas5i4cayiccu44iceour4pe4ced_i5cidsea5wi2cipseas4i4clyur4pi4i1cr5icrai4cryic4teictu2ccon4urti4ic4umic5uoi3curcci4ai4daiccha5ca4thscof4ide4s4casys4cliscle5i5dieid3ios4choid1itid5iui3dlei4domid3owu5sadu5sanid5uous4apied4ecany4ield3s4cesien4ei5enn4sceii1er_i3esci1estus3ciuse5as4cedscav5if4frsca4pi3fieu5siau3siccan4eiga5bcan5d4calous5sli3gibig3ilig3inig3iti4g4lus1trig3orig5oti5greigu5iig1ur2c5ah4i5i44cag4cach4ca1blusur4sat3usa5tab5utoi3legil1erilev4uta4b4butail3iail2ibil3io3sanc2ilitil2izsal4t5bustil3oqil4tyil5uru3tati4magsa5losal4m4ute_4imetbu3res3act5sack2s1ab4imitim4nii3mon4utelbumi4bu3libu4ga4inav4utenbsor42b5s2u4tis4briti3neervi4vr3vic4inga4inger3vey4ingir3ven4ingo4inguu4t1li5ni_i4niain3ioin1isbo4tor5uscrunk5both5b5ota5bos42i1no5boriino4si4not5borein3seru3in2int_ru4glbor5di5nusut5of5bor_uto5gioge4io2grbon4au5tonru3enu4touion3iio5phior3ibod3iio5thi5otiio4toi4ourbne5gb3lisrt4shblen4ip4icr3triip3uli3quar4tivr3tigrti4db4le_b5itzira4bi4racird5ert5ibi4refbi3tri4resir5gibi5ourte5oir4isr3tebr4tagbin4diro4gvac3uir5ul2b3ifis5agis3arisas52is1cis3chbi4eris3erbi5enrson3be5yor5shais3ibisi4di5sisbe3tw4is4krs3es4ismsbe5trr3secva4geis2piis4py4is1sbe3sp4bes4be5nuval5ois1teis1tirrys4rros44be5mis5us4ita_rron4i4tagrri4vi3tani3tatbe3lorri4or4reoit4esbe1libe5gu4itiarre4frre4cbe3giit3igbe3dii2tim2itio4itisrp4h4r3pet4itonr4peait5rybe3debe3dai5tudit3ul4itz_4be2dbeat3beak4ro4varo4tyros4sro5roiv5ioiv1itror3i5root1roomval1ub3berva5mo4izarva5piron4eban3ijac4qban4ebal1ajer5srom4prom4iba4geazz5i5judgay5alax4idax4ickais4aw4ly3awaya1vorav5ocav3igke5liv3el_ve4lov4elyro1feke4tyv4erdv4e2sa5vanav3ag5k2ick4illkilo5au1thk4in_4ves_ro3crkin4gve4teaun5dk5ishau4l2au3gu4kleyaugh3ve4tyk5nes1k2noat3ulkosh4at5uekro5n4k1s2at5uaat4that5te5vianat4sk5vidil4abolaci4l4adela3dylag4nlam3o3landrob3la4tosr4noular4glar3ilas4ea4topr3nivr3nita2tomr5nica4toglbin44l1c2vi5gnat3ifat1ica5tiar3neyr5net4ati_ld5isat4hol4driv2incle4bileft55leg_5leggr4nerr3nel4len_3lencr4nar1lentle3phle4prvin5dler4e3lergr3mitl4eroat5evr4mio5lesq3lessr3menl3eva4vingrma5cvio3lvi1ou4leyevi5rovi3so4l1g4vi3sulgar3l4gesate5cat5apli4agli2amr3lo4li4asr4lisli5bir4ligr2led4lics4vitil4icul3icyl3idaat5ac3lidirk4lel4iffli4flr3ket3lighvit3r4vityriv3iri2tulim3ili4moris4pl4inar3ishris4clin3ir4is_li5og4l4iqlis4pas1trl2it_as4shas5phri2pla4socask3ia3sicl3kallka4ta3sibl4lawashi4l5leal3lecl3legl3lel5riphas4abar2shrin4grin4ear4sarin4dr2inal5lowarre4l5met3rimol4modlmon42l1n2a3roorim5ilo4civo4la5rigil5ogo3loguri5et5longlon4iri1erlood5r4icolop3il3opmlora44ricir4icerib3a5los_v5oleri4agria4blos4tlo4taar2mi2loutar2izar3iolpa5bl3phal5phi4rhall3pit5voltar4im3volv2l1s2vom5ivori4l4siear4fllt5agar4fivo4rylten4vo4talth3ia3reeltis4ar4drw5ablrgo4naraw4lu3brluch4lu3cilu3enwag5olu5idlu4ma5lumia5raur5gitwait5luo3rw5al_luss4r5gisar4atl5venrgi4nara3pwar4tar3alwas4tly5mely3no2lys4l5ysewa1teaque5ma2car3gicma4clr3get5magnwed4nmaid54maldrg3erweet3wee5vwel4lapoc5re4whwest3ap3in4aphires2tr4es_mar3vre5rumas4emas1t5matemath3rero4r4eriap5atr1er4m5bilre1pumbi4vapar4a5nuran3ul4med_an3uare5lure1lian4twre5itmel4tan2trre4fy4antomen4are3fire2fe4menemen4imens4re1de3ment2r2edme5onre4awwin4g5reavme4tare3anme1tere1alm4etr3wiserdin4rdi4aan4stwith3an2span4snan2samid4amid4gan5otwl4esr4dalm4illmin4a3mindrcum3rc4itr3charcen4min4tm4inumiot4wl3ina3niumis5lan3ita3nip4mithan3ioan1gla3neuws4per2bina3nena5neem4ninw5s4tan1dl4mocrrbi4fmo2d1mo4gomois2xac5ex4agor4bagmo3mer4baba3narrau4ta5monrare4rar5cra5nor4aniam1inr2amiam5ifra4lomo3spmoth3m5ouf3mousam3icxer4ixe5roraf4tr5aclm3petra3bixhil5mpi4aam3ag3quetm5pirmp5is3quer2que_qua5vmpov5mp4tram5ab3alyz4m1s25alyt4alysa4ly_ali4exi5di5multx4ime4aldia4laral3adal5abak1enain5opu3trn4abu4nac_na4can5act5putexpe3dna4lia4i4n4naltai5lya3ic_pur4rag5ulnank4nar3c4narenar3inar4ln5arm3agognas4c4ag4l4ageupul3cage4oaga4na4gab3nautnav4e4n1b4ncar5ad5umn3chaa3ducptu4rpti3mnc1innc4itad4suad3owad4len4dain5dana5diua3ditndi4ba3dion1ditn3dizn5ducndu4rnd2we3yar4n3eara3dianeb3uac4um5neckac3ulp4siba3cio5negene4laac1inne5mine4moa3cie4nene4a2cine4poyc5erac1er2p1s2pro1tn2erepro3lner4rych4e2nes_4nesp2nest4neswpri4sycom4n5evea4carab3uln4gabn3gelpre3vpre3rycot4ng5han3gibng1inn5gitn4glangov4ng5shabi5an4gumy4erf4n1h4a5bannhab3a5bal3n4iani3anni4apni3bani4bl_us5ani5dini4erni2fip3petn5igr_ure3_un3up3per_un5op3pennin4g_un5k5nis_p5pel_un1en4ithp4ped_un1ani3tr_to4pympa3_til4n3ketnk3inyn5ic_se2ny4o5gy4onsnmet44n1n2_ru4d5pounnni4vnob4lpo4tan5ocly4ped_ro4qyper5noge4pos1s_ri4gpo4ry1p4or_res2no4mono3my_ree2po4ninon5ipoin2y4poc5po4gpo5em5pod_4noscnos4enos5tno5tayp2ta3noun_ra4cnowl3_pi2tyra5m_pi4eyr5ia_out3_oth32n1s2ns5ab_or3t_or1d_or3cplu4mnsid1nsig4y3s2eys3ion4socns4pen5spiploi4_odd5nta4bpli4n_ni4cn5tib4plignti2fpli3a3plannti4p1p2l23ysis2p3k2ys3ta_mis1nu5enpi2tun3uinp3ithysur4nu1men5umi3nu4nyt3icnu3trz5a2b_li4t_li3o_li2n_li4g_lev1_lep5_len4pion4oard3oas4e3pi1ooat5ip4inoo5barobe4l_la4mo2binpind4_ju3rob3ul_is4i_ir5rp4in_ocif3o4cil_in3so4codpi3lopi3enocre33piec5pidipi3dep5ida_in2kod3icodi3oo2do4odor3pi4cypian4_ine2o5engze3rooe4ta_im3m_id4l_hov5_hi3b_het3_hes3_go4r_gi4bpho4ro5geoo4gero3gie3phobog3it_gi5azo5ol3phizo4groogu5i4z1z22ogyn_fes3ohab5_eye55phieph1icoiff4_en3sph4ero3ing_en3go5ism_to2qans3v_el5d_eer4bbi4to3kenok5iebio5mo4lanper1v4chs_old1eol3erpe5ruo3letol4fi_du4co3liaper3op4ernp4erio5lilpe5ono5liop4encpe4la_do4tpee4do5livcin2q3pediolo4rol5pld3tabol3ub3pedeol3uno5lusedg1le1loaom5ahoma5l2p2edom2beom4bl_de3o3fich3pe4ao4met_co4ro3mia_co3ek3shao5midom1inll1fll3teapa2teo4monom3pi3pare_ca4tlue1pon4aco3nanm2an_pa4pum2en_on5doo3nenng1hoon4guon1ico3nioon1iso5niupa3nypan4ao3nou_bri2pain4ra1oronsu4rk1hopac4tpa4ceon5umonva5_ber4ood5eood5i6rks_oop3io3ordoost5rz1scope5dop1erpa4ca_ba4g_awn4_av4i_au1down5io3pito5pon1sync_as1s_as1p_as3ctch1c_ar5so5ra_ow3elo3visov4enore5auea1mor3eioun2d_ant4orew4or4guou5etou3blo5rilor1ino1rio_ang4o3riuor2miorn2eo5rofoto5sor5pe3orrhor4seo3tisorst4o3tif_an5cor4tyo5rum_al3tos3al_af1tos4ceo4teso4tano5scros2taos4poos4paz2z3wosi4ue3pai",6:"os3ityos3itoz3ian_os4i4ey1stroos5tilos5titxquis3_am5atot3er_ot5erso3scopor3thyweek1noth3i4ot3ic_ot5icao3ticeor3thiors5enor3ougor3ityor3icaouch5i4o5ria_ani5mv1ativore5sho5realus2er__an3teover3sov4erttot3icoviti4o5v4olow3dero4r3agow5esto4posiop3ingo5phero5phanthy3sc3operaontif5on3t4ionten45paganp3agattele2gonspi4on3omyon4odipan3elpan4tyon3keyon5est3oncil_ar4tyswimm6par5diompro5par5elp4a4ripar4isomo4gepa5terst5scrpa5thy_atom5sta1tio5miniom3icaom3ic_ss3hatsky1scpear4lom3ena_ba5naol3umer1veilpedia4ped4icolli4er1treuo5liteol3ishpeli4epe4nano5lis_pen4thol3ingp4era_r1thoup4erago3li4f_bas4er1krauperme5ol5id_o3liceper3tio3lescolass4oi3terpe5tenpe5tiz_be5raoi5son_be3smphar5iphe3nooi5letph4es_oi3deroic3esph5ingr3ial_3ognizo5g2ly1o1gis3phone5phonio5geneo4gatora3mour2amenofit4tof5itera3chupi4ciepoly1eod5dedo5cureoc3ula1pole_5ocritpee2v1param4oc3raco4clamo3chetob5ingob3a3boast5eoke1st3nu3itpi5thanuf4fentu3meoerst2o3chasplas5tn3tinepli5ernti4ernter3sntre1pn4s3esplum4bnsati4npre4cns4moonon1eqnor5abpo3et5n5lessn5oniz5pointpoly5tnon4agnk3rup3nomicng1sprno5l4inois5i4n3o2dno3blenni3aln5keroppa5ran3itor3nitionis4ta5nine_ni3miznd3thrmu2dron3geripray4e5precipre5copre3emm3ma1bpre4lan5gerep3rese3press_can5cmedi2c5pri4e_ce4la3neticpris3op3rocal3chain4er5ipros3en4erarnera5bnel5iz_cit5rne4gatn5d2ifpt5a4bjanu3aign4itn3chisn5chiln5cheon4ces_nau3seid4iosna3talnas5tinan4itnanci4na5mitna5liahnau3zput3er2n1a2bhex2a3hatch1multi3hair1sm4pousg1utanmpo3rim4p1inmp5iesmphas4rach4empar5iraf5figriev1mpara5mo5seyram3et4mora_rane5oran4gemo3ny_monol4rap3er3raphymo3nizgno5morar5ef4raril1g2nacg1leadmoni3ara5vairav3elra5ziemon5gemon5etght1wemoi5sege3o1dmma5ryr5bine3fluoren1dixmis4ti_de3ra_de3rie3chasrch4err4ci4bm4inglm5ineedu2al_3miliame3tryrdi4er_des4crd3ingdi2rerme5thimet3alre5arr3mestim5ersadi2rende2ticdes3icre4cremen4temensu5re3disred5itre4facmen4dede2mosmen5acmem1o3reg3ismel5onm5e5dyme3died2d5ibren4te5mediare5pindd5a5bdata1bmba4t5cle4arma3tisma5scemar4lyre4spichs3huma5riz_dumb5re3strre4terbrus4qre3tribio1rhre5utiman3izre4valrev3elbi1orbbe2vie_eas3ire5vilba1thyman5is5maniamal4tymal4lima5linma3ligmag5inav3ioul5vet4rg3inglus3teanti1dl5umn_ltur3a_el3emltera4ltane5lp5ingloun5dans5gra2cabllos5etlor5ouric5aslo5rie_enam35ricidri4cie5lope_rid5erri3encri3ent_semi5lom3errig5an3logicril3iz5rimanlob5allm3ingrim4pell5out5rina__er4ril5linal2lin4l3le4tl3le4nriph5eliv3er_ge5og_han5k_hi3er_hon3olin3ea1l4inel4im4p_idol3_in3ci_la4cy_lath5rit3iclim4blrit5urriv5elriv3et4l4i4lli4gra_leg5elif3errk4linlid5er4lict_li4cor5licioli4atorl5ish_lig5a_mal5o_man5a_mer3c5less_rm5ersrm3ingy3thinle5sco3l4erilera5b5lene__mon3ele4matld4erild4erela4v4ar1nis44lativ_mo3rola5tanlan4telan5etlan4dllab3ic_mu5takin4dek3est_ro5filk3en4dro5ker5role__of5te4jestyys3icaron4al5izont_os4tlron4tai4v3ot_pe5tero3pelrop3ici5voreiv5il__pio5n_pre3mro4the_ran4tiv3en_rov5eliv3ellit3uati4tramr5pentrp5er__rit5ui4tismrp3ingit5ill_ros5tit3ica4i2tici5terirre4stit3era4ita5mita4bi_row5dist4lyis4ta_is4sesrsa5tiissen4is4sal_sci3erse4crrs5er_islan4rse5v2yo5netish5opis3honr4si4bis5han5iron_ir4minrtach4_self5iri3turten4diri5dei4rel4ire4de_sell5r4tieriq3uidrtil3irtil4lr4tilyr4tistiq5uefip4re4_sing4_ting4yn3chrru3e4lion3at2in4th_tin5krum3pli4no4cin3ityrun4ty_ton4aruti5nymbol5rvel4i_top5irv5er_r5vestin5geni5ness_tou5s_un3cein3cerincel45ryngei4n3auim3ulai5miniimi5lesac3riim5ida_ve5rasalar4ima5ryim3ageill5abil4istsan4deila5rai2l5am_wil5ii4ladeil3a4bsa5voright3iig3eraab5erd4ific_iff5enif5eroi3entiien5a45ie5gaidi5ou3s4cieab5latidi4arid5ianide3al4scopyab5rogid5ancic3ulaac5ardi2c5ocic3ipaic5inase2c3oi4carai4car_se4d4ei2b5riib5iteib5it_ib5ertib3eraac5aroi4ativ4ian4tse4molsen5ata5ceouh4warts5enedhus3t4s5enin4sentd4sentlsep3a34s1er_hun5kehu4min4servohro3poa5chethov5el5se5umhouse3sev3enho5senhort3eho5rishor5at3hol4ehol5arh5odizhlo3riac5robhis3elhion4ehimer4het4edsh5oldhe2s5ph5eroushort5here5aher4bahera3p3side_5sideshen5atsi5diz4signahel4lyact5ifhe3l4ihe5do55sine_h5ecathe4canad4dinsion5aad5er_har4lehard3e3sitioha5rasha3ranhan4tead3icahang5oadi4ersk5inesk5ing5hand_han4cyhan4cislith5hala3mh3ab4lsmall32g5y3n5gui5t3guard5smithad5ranaeri4eag5ellag3onia5guerso4labsol3d2so3licain5in4grada3s4on_gor5ougo5rizgondo5xpan4dait5ens5ophyal3end3g4o4ggnet4tglad5i5g4insgin5ge3g4in_spen4d2s5peog3imen5gies_3spher5giciagh5outsp5ingge5nizge4natge5lizge5lisgel4inxi5miz4gativgar5n4a5le5oga3nizgan5isga5mets5sengs4ses_fu4minfres5cfort5assi4erss5ilyfore5tfor5ayfo5ratal4ia_fon4dessur5aflo3ref5lessfis4tif1in3gstam4i5stands4ta4p5stat_fin2d5al5levs5tero4allicstew5afight5fi5del5ficie5ficiafi3cer5stickf3icena5log_st3ingf3icanama5ra5stockstom3a5stone2f3ic_3storef2f5iss4tradam5ascs4trays4tridf5fin_fend5efeath3fault5fa3thefar5thfam5is4fa4mafall5eew3inge5verbeven4ie5vengevel3oev3ellev5asteva2p5euti5let5roset3roget5rifsy5rinet3ricet5onaam5eraam5ilyami4noamor5ieti4noe5tidetai5loethod3eten4dtal5enes5urramp5enan3ageta5loge5strotan4detanta3ta5pere3ston4es2toes5times3tigta3rizestan43analy4taticta4tures4prean3arces3pertax4ises5onaes3olue5skintch5etanar4ies4i4ntead4ie2s5ima3natiande4sesh5enan3disan4dowang5iete5geres5ences5ecres5cana4n1icte2ma2tem3at3tenanwrita45erwau4tenesert3era3nieser3set5erniz4erniter4nis5ter3de4rivaan3i3fter3isan4imewo5vener3ineeri4ere3rient3ess_teth5e5ericke1ria4er3ester5esser3ent4erenea5nimier5enaer3emoth3easthe5atthe3iser5el_th5ic_th5icaere3in5thinkere5coth5odea5ninee3realan3ishan4klier4che5anniz4erandti4atoanoth5equi3lep5utat4ic1uan4scoe4probep3rehe4predans3poe4precan4surantal4e3penttim5ulep5anceo5rol3tine_eop3aran4tiewin4deap5eroen3ishen5icsen3etren5esten5esien5eroa3pheren3dicap3itae4nanten5amoem5ulaa3pituti3zen5emnize5missem5ishap5olaem5ine3tles_t5let_em1in2apor5iem3icaem5anael3op_el4labapos3te3liv3el5ishaps5esweath3e3lierel3icaar3actwa5verto3nate3libee4l1erel3egato3rietor5iza5radeelaxa4aran4gto3warelan4dej5udie5insttra5chtraci4ar5av4wa5gere5git5arbal4ar5easeg5ing4voteetrem5iar3enta5ressar5ial4tricsvor5abe3finetro5mitron5i4tronyar3iantro3sp5eficia3rieted5uloed3icae4d1erec3ulaec4tane4cremeco5roec3orae4concar5o5de4comme4cluse4clame5citeec5ifya5ronias3anta5sia_tu4nis2t3up_ecan5ce4belstur3ise4bel_eav3ene4a3tue5atifeath3ieat5eneart3eear4ilear4icear5eseam3ereal3oueal5erea5geread5iedum4be4ducts4duct_duc5eras3tenasur5adrea5rat3abl4d5outdo3natdom5izdo5lor4dlessu4bero3dles_at3alou3ble_d4is3tdirt5idi5niz3dine_at5ech5di3endi4cam1d4i3ad3ge4tud5estdev3ilde3strud3iedud3iesdes3tide2s5oat3egovis3itde4nardemor5at3en_uen4teuer4ilde5milat3eraugh3en3demicater5nuil5izdeli4ede5comde4cildecan4de4bonv3io4rdeb5it4dativ2d3a4bat3estu5laticu4tie5ulcheul3dercuss4icu5riaath5em3cultua5thenul3ingul5ishul4lar4vi4naul4liscu5ityctim3ic4ticuuls5esc5tantultra3ct5angcros4ecrop5ocro4pl5critiath5omum4blycre3at5vilitumor5oat5i5b5crat_cras5tcoro3ncop3iccom5ercol3orun5ishco3inc5clareat3ituunt3abat5ropun4tescit3iz4cisti4cista4cipicc5ing_cin3em3cinatuper5s5videsup3ingci2a5b5chini5videdupt5ib5vide_at4tag4ch1inch3ersch3er_ch5ene3chemiche5loure5atur4fercheap3vi5aliat3uravet3er4ch3abc5e4taau5sib3cessives4tece5ram2cen4e4cedenccou3turs5erur5tesur3theaut5enur4tiecav5al4cativave4nover3thcar5omca5percan4tycan3izcan5iscan4icus4lin3versecal4laver3ieca3latca5dencab3in3butiobuss4ebus5iebunt4iv4eresuten4i4u1t2iv3erenu3tineut3ingv4erelbroth35u5tizbound34b1orabon5at5vere_bom4bibol3icblun4t5blespblath5av3erav5enuebi3ogrbi5netven3om2v1a4bvac5ilbi3lizbet5izbe5strva5liebe5nigbbi4nabas4siva5nizbari4aav5ernbarbi5av5eryvel3liazi4eravi4er",7:"_dri5v4ban5dagvar5iedbina5r43bi3tio3bit5ua_ad4derution5auti5lizver5encbuf4ferus5terevermi4ncall5incast5ercas5tigccompa5z3o1phros5itiv5chanicuri4fico5stati5chine_y5che3dupport54v3iden5cific_un4ter_at5omiz4oscopiotele4g5craticu4m3ingv3i3liz4c3retaul4li4bcul4tiscur5a4b4c5utiva5ternauiv4er_del5i5qdem5ic_de4monsdenti5fdern5izdi4latou4b5ingdrag5on5drupliuar5ant5a5si4tec5essawo4k1enec5ifiee4compear5inate4f3eretro5phewide5sp5triciatri5cesefor5ese4fuse_oth5esiar5dinear4chantra5ventrac4tetrac4itar5ativa5ratioel5ativor5est_ar5adisel5ebraton4alie4l5ic_wea5rieel5igibe4l3ingto5cratem5igraem3i3niemoni5oench4erwave1g4a4pillavoice1ption5eewill5inent5age4enthesvaude3vtill5inep5recaep5ti5bva6guer4erati_tho5rizthor5it5thodicer5ence5ternitteri5zater5iesten4tage4sage_e4sagese4sert_an5est_e4sertse4servaes5idenes5ignaesis4tees5piraes4si4btal4lisestruc5e5titioounc5erxe4cutota5bleset5itiva4m5atoa4matis5stratu4f3ical5a5lyst4ficatefill5instern5isspend4gani5zasqual4la4lenti4g3o3nas5ophiz5sophicxpecto55graph_or5angeuri4al_4graphy4gress_smol5d4hang5erh5a5nizharp5enhar5terhel4lishith5erhro5niziam5eteia4tricic4t3uascour5au2r1al_5scin4dover4nescan4t55sa3tiou5do3ny_ven4de_under5ty2p5al_anti5sylla5bliner4arturn3ari5nite_5initioinsur5aion4eryiphras4_tim5o5_ten5an_sta5blrtroph4_se5rieiq3ui3t5i5r2izis5itiviso5mer4istral5i5ticki2t5o5mtsch3ie_re5mittro3fiti4v3er_i4vers_ros5per_pe5titiv3o3ro_ped5alro5n4is_or5ato4jestierom5ete_muta5bk5iness4latelitr4ial__mist5i_me5terr4ming_lev4er__mar5tilev4eralev4ers_mag5a5liar5iz5ligaterit5ers_lat5errit5er_r5ited__im5pinri3ta3blink5er_hon5ey5litica_hero5ior5aliz_hand5irip5lic_gen3t4tolo2gylloqui5_con5grt1li2erbad5ger4operag_eu4lertho3donter2ic__ar4tie_ge4ome_ge5ot1_he3mo1_he3p6a_he3roe_in5u2tpara5bl5tar2rht1a1mintalk1a5ta3gon_par5age_aster5_ne6o3f_noe1thstyl1is_poly1s5pathic_pre1ampa4tricl3o3niz_sem4ic_semid6_semip4_semir45ommend_semiv4lea4s1a_spin1oom5etryspher1o_to6poglo4ratospe3cio3s2paceso2lute_we2b1l_re1e4ca5bolicom5erseaf6fishside5swanal6ysano5a2cside5stl5ties_5lumniasid2ed_anti1reshoe1stscy4th1s4chitzsales5wsales3cat6tes_augh4tlau5li5fom5atizol5ogizo5litiorev5olure5vertre5versbi5d2ifbil2lab_earth5pera5blro1tronro3meshblan2d1blin2d1blon2d2bor1no5ro1bot1re4ti4zr5le5quperi5stper4malbut2ed_but4tedcad5e1moist5enre5stalress5ibchie5vocig3a3roint5er4matizariv1o1lcous2ticri3tie5phisti_be5stoog5ativo2g5a5rr3a3digm4b3ingre4posir4en4tade4als_od5uctsquasis6quasir6re5fer_p5trol3rec5olldic1aiddif5fra3pseu2dr5ebrat5metric2d1lead2d1li2epro2g1epre1neuod5uct_octor5apoin3came5triem5i5liepli5narpara3memin5glim5inglypi4grappal6matmis4er_m5istryeo3graporth1riop1ism__but4tio3normaonom1icfeb1ruafermi1o_de4moio5a5lesodit1icodel3lirb5ing_gen2cy_n4t3ingmo5lestration4get2ic_4g1lishobli2g1mon4ismnsta5blmon4istg2n1or_nov3el3ns5ceivno1vembmpa5rabno4rarymula5r4nom1a6lput4tinput4tedn5o5miz_cam4penag5er_nge5nesh2t1eoun1dieck2ne1skiifac1etncour5ane3backmono1s6mono3chmol1e5cpref5ac3militapre5tenith5i2lnge4n4end5est__capa5bje1re1mma1la1ply5styr1kovian_car5olprin4t3lo2ges_l2l3ishprof5it1s2tamp",8:"lead6er_url5ing_ces5si5bch5a5nis1le1noidlith1o5g_chill5ilar5ce1nym5e5trych5inessation5arload4ed_load6er_la4c3i5elth5i2lyneg5ativ1lunk3erwrit6er_wrap3arotrav5es51ke6linga5rameteman3u1scmar1gin1ap5illar5tisticamedio6c1me3gran3i1tesima3mi3da5bves1titemil2l1agv1er1eigmi6n3is_1verely_e4q3ui3s5tabolizg5rapher5graphicmo5e2lasinfra1s2mon4ey1lim3ped3amo4no1enab5o5liz_cor5nermoth4et2m1ou3sinm5shack2ppo5sitemul2ti5uab5it5abimenta5rignit1ernato5mizhypo1thani5ficatuad1ratu4n5i4an_ho6r1ic_ua3drati5nologishite3sidin5dling_trib5utin5glingnom5e1non1o1mistmpos5itenon1i4so_re5stattro1p2istrof4ic_g2norespgnet1ism5glo5binlem5aticflow2er_fla1g6elntrol5lifit5ted_treach1etra1versl5i5ticso3mecha6_for5mer_de5rivati2n3o1me3spac6i2t3i4an_thy4l1antho1k2er_eq5ui5to4s3phertha4l1amt3ess2es3ter1geiou3ba3dotele1r6ooxi6d1iceli2t1isonspir5apar4a1leed1ulingea4n3iesoc5ratiztch3i1er_kil2n3ipi2c1a3dpli2c1abt6ap6athdrom3e5d_le6icesdrif2t1a_me4ga1l1prema3cdren1a5lpres2plipro2cess_met4ala3do5word1syth3i2_non1e2m_post1ampto3mat4rec5ompepu5bes5cstrib5utqu6a3si31stor1ab_sem6is4star3tliqui3v4arr1abolic_sph6in1de5clar12d3aloneradi1o6gs3qui3tosports3wsports3cra5n2hascro5e2cor3bin1gespokes5wspi2c1il_te3legrcroc1o1d_un3at5t_dictio5cat1a1s2buss4ingbus6i2esbus6i2erbo2t1u1lro5e2las1s2pacinb1i3tivema5rine_r3pau5li_un5err5r5ev5er__vi2c3arback2er_ma5chinesi5resid5losophyan3ti1n2sca6p1ersca2t1olar2rangesep3temb1sci2uttse3mes1tar3che5tsem1a1ph",9:"re4t1ribuuto5maticl3chil6d1a4pe5able1lec3ta6bas5ymptotyes5ter1yl5mo3nell5losophizlo1bot1o1c5laratioba6r1onierse1rad1iro5epide1co6ph1o3nscrap4er_rec5t6angre2c3i1prlai6n3ess1lum5bia_3lyg1a1miec5ificatef5i5nites2s3i4an_1ki5neticjapan1e2smed3i3cinirre6v3ocde2c5linao3les3termil5li5listrat1a1gquain2t1eep5etitiostu1pi4d1v1oir5du1su2per1e6_mi1s4ers3di1methy_mim5i2c1i5nitely_5maph1ro15moc1ra1tmoro6n5isdu1op1o1l_ko6r1te1n3ar4chs_phi2l3ant_ga4s1om1teach4er_parag6ra4o6v3i4an_oth3e1o1sn3ch2es1to5tes3toro5test1eror5tively5nop5o5liha2p3ar5rttrib1ut1_eth1y6l1e2r3i4an_5nop1oly_graph5er_5eu2clid1o1lo3n4omtrai3tor1_ratio5na5mocratiz_rav5en1o",10:"se1mi6t5ic3tro1le1um5sa3par5iloli3gop1o1am1en3ta5bath3er1o1s3slova1kia3s2og1a1myo3no2t1o3nc2tro3me6c1cu2r1ance5noc3er1osth1o5gen1ih3i5pel1a4nfi6n3ites_ever5si5bs2s1a3chu1d1ri3pleg5_ta5pes1trproc3i3ty_s5sign5a3b3rab1o1loiitin5er5arwaste3w6a2mi1n2ut1erde3fin3itiquin5tes5svi1vip3a3r",11:"pseu3d6o3f2s2t1ant5shimi1n2ut1estpseu3d6o3d25tab1o1lismpo3lyph1onophi5lat1e3ltravers3a3bschro1ding12g1o4n3i1zat1ro1pol3it3trop1o5lis3trop1o5lesle3g6en2dreeth1y6l1eneor4tho3ni4t",12:"3ra4m5e1triz1e6p3i3neph1"}};Hyphenator.run(); +/* The following comment is for JSLint: */ +/*jslint browser: true */ + +/** + * @desc Provides all functionality to do hyphenation, except the patterns that are loaded externally + * @global + * @namespace Hyphenator + * @author Mathias Nater, <mathias@mnn.ch> + * @version X.Y.Z + * @example + * <script src = "Hyphenator.js" type = "text/javascript"></script> + * <script type = "text/javascript"> + * Hyphenator.run(); + * </script> + */ +var Hyphenator = (function (window) { + 'use strict'; + + /** + * @member Hyphenator~contextWindow + * @access private + * @desc + * contextWindow stores the window for the actual document to be hyphenated. + * If there are frames this will change. + * So use contextWindow instead of window! + */ + var contextWindow = window, + + + /** + * @member {Object.<string, Hyphenator~supportedLangs~supportedLanguage>} Hyphenator~supportedLangs + * @desc + * A generated key-value object that stores supported languages and meta data. + * The key is the {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language and the value + * is an object of type {@link Hyphenator~supportedLangs~supportedLanguage} + * @namespace Hyphenator~supportedLangs + * @access private + * //Check if language lang is supported: + * if (supportedLangs.hasOwnProperty(lang)) + */ + supportedLangs = (function () { + /** + * @typedef {Object} Hyphenator~supportedLangs~supportedLanguage + * @property {string} file - The name of the pattern file + * @property {number} script - The script type of the language (e.g. 'latin' for english), this type is abbreviated by an id + * @property {string} prompt - The sentence prompted to the user, if Hyphenator.js doesn't find a language hint + */ + + /** + * @lends Hyphenator~supportedLangs + */ + var r = {}, + /** + * @method Hyphenator~supportedLangs~o + * @desc + * Sets a value of Hyphenator~supportedLangs + * @access protected + * @param {string} code The {@link http://tools.ietf.org/rfc/bcp/bcp47.txt bcp47} code of the language + * @param {string} file The name of the pattern file + * @param {Number} script A shortcut for a specific script: latin:0, cyrillic: 1, arabic: 2, armenian:3, bengali: 4, devangari: 5, greek: 6 + * gujarati: 7, kannada: 8, lao: 9, malayalam: 10, oriya: 11, persian: 12, punjabi: 13, tamil: 14, telugu: 15 + * @param {string} prompt The sentence prompted to the user, if Hyphenator.js doesn't find a language hint + */ + o = function (code, file, script, prompt) { + r[code] = {'file': file, 'script': script, 'prompt': prompt}; + }; + + o('be', 'be.js', 1, 'Мова гэтага сайта не можа быць вызначаны аўтаматычна. Калі ласка пакажыце мову:'); + o('ca', 'ca.js', 0, ''); + o('cs', 'cs.js', 0, 'Jazyk této internetové stránky nebyl automaticky rozpoznán. Určete prosím její jazyk:'); + o('da', 'da.js', 0, 'Denne websides sprog kunne ikke bestemmes. Angiv venligst sprog:'); + o('bn', 'bn.js', 4, ''); + o('de', 'de.js', 0, 'Die Sprache dieser Webseite konnte nicht automatisch bestimmt werden. Bitte Sprache angeben:'); + o('el', 'el-monoton.js', 6, ''); + o('el-monoton', 'el-monoton.js', 6, ''); + o('el-polyton', 'el-polyton.js', 6, ''); + o('en', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); + o('en-gb', 'en-gb.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); + o('en-us', 'en-us.js', 0, 'The language of this website could not be determined automatically. Please indicate the main language:'); + o('eo', 'eo.js', 0, 'La lingvo de ĉi tiu retpaĝo ne rekoneblas aŭtomate. Bonvolu indiki ĝian ĉeflingvon:'); + o('es', 'es.js', 0, 'El idioma del sitio no pudo determinarse autom%E1ticamente. Por favor, indique el idioma principal:'); + o('et', 'et.js', 0, 'Veebilehe keele tuvastamine ebaõnnestus, palun valige kasutatud keel:'); + o('fi', 'fi.js', 0, 'Sivun kielt%E4 ei tunnistettu automaattisesti. M%E4%E4rit%E4 sivun p%E4%E4kieli:'); + o('fr', 'fr.js', 0, 'La langue de ce site n%u2019a pas pu %EAtre d%E9termin%E9e automatiquement. Veuillez indiquer une langue, s.v.p.%A0:'); + o('grc', 'grc.js', 6, ''); + o('gu', 'gu.js', 7, ''); + o('hi', 'hi.js', 5, ''); + o('hu', 'hu.js', 0, 'A weboldal nyelvét nem sikerült automatikusan megállapítani. Kérem adja meg a nyelvet:'); + o('hy', 'hy.js', 3, 'Չհաջողվեց հայտնաբերել այս կայքի լեզուն։ Խնդրում ենք նշեք հիմնական լեզուն՝'); + o('it', 'it.js', 0, 'Lingua del sito sconosciuta. Indicare una lingua, per favore:'); + o('kn', 'kn.js', 8, 'ಜಾಲ ತಾಣದ ಭಾಷೆಯನ್ನು ನಿರ್ಧರಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ಮುಖ್ಯ ಭಾಷೆಯನ್ನು ಸೂಚಿಸಿ:'); + o('la', 'la.js', 0, ''); + o('lt', 'lt.js', 0, 'Nepavyko automatiškai nustatyti šios svetainės kalbos. Prašome įvesti kalbą:'); + o('lv', 'lv.js', 0, 'Šīs lapas valodu nevarēja noteikt automātiski. Lūdzu norādiet pamata valodu:'); + o('ml', 'ml.js', 10, 'ഈ വെ%u0D2C%u0D4D%u200Cസൈറ്റിന്റെ ഭാഷ കണ്ടുപിടിയ്ക്കാ%u0D28%u0D4D%u200D കഴിഞ്ഞില്ല. ഭാഷ ഏതാണെന്നു തിരഞ്ഞെടുക്കുക:'); + o('nb', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); + o('no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); + o('nb-no', 'nb-no.js', 0, 'Nettstedets språk kunne ikke finnes automatisk. Vennligst oppgi språk:'); + o('nl', 'nl.js', 0, 'De taal van deze website kan niet automatisch worden bepaald. Geef de hoofdtaal op:'); + o('or', 'or.js', 11, ''); + o('pa', 'pa.js', 13, ''); + o('pl', 'pl.js', 0, 'Języka tej strony nie można ustalić automatycznie. Proszę wskazać język:'); + o('pt', 'pt.js', 0, 'A língua deste site não pôde ser determinada automaticamente. Por favor indique a língua principal:'); + o('ru', 'ru.js', 1, 'Язык этого сайта не может быть определен автоматически. Пожалуйста укажите язык:'); + o('sk', 'sk.js', 0, ''); + o('sl', 'sl.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); + o('sr-cyrl', 'sr-cyrl.js', 1, 'Језик овог сајта није детектован аутоматски. Молим вас наведите језик:'); + o('sr-latn', 'sr-latn.js', 0, 'Jezika te spletne strani ni bilo mogoče samodejno določiti. Prosim navedite jezik:'); + o('sv', 'sv.js', 0, 'Spr%E5ket p%E5 den h%E4r webbplatsen kunde inte avg%F6ras automatiskt. V%E4nligen ange:'); + o('ta', 'ta.js', 14, ''); + o('te', 'te.js', 15, ''); + o('tr', 'tr.js', 0, 'Bu web sitesinin dili otomatik olarak tespit edilememiştir. Lütfen dökümanın dilini seçiniz%A0:'); + o('uk', 'uk.js', 1, 'Мова цього веб-сайту не може бути визначена автоматично. Будь ласка, вкажіть головну мову:'); + o('ro', 'ro.js', 0, 'Limba acestui sit nu a putut fi determinată automat. Alege limba principală:'); + + return r; + }()), + + + /** + * @member {string} Hyphenator~basePath + * @desc + * A string storing the basepath from where Hyphenator.js was loaded. + * This is used to load the pattern files. + * The basepath is determined dynamically by searching all script-tags for Hyphenator.js + * If the path cannot be determined {@link http://hyphenator.googlecode.com/svn/trunk/} is used as fallback. + * @access private + * @see {@link Hyphenator~loadPatterns} + */ + basePath = (function () { + var s = contextWindow.document.getElementsByTagName('script'), i = 0, p, src, t = s[i], r = ''; + while (!!t) { + if (!!t.src) { + src = t.src; + p = src.indexOf('Hyphenator.js'); + if (p !== -1) { + r = src.substring(0, p); + } + } + i += 1; + t = s[i]; + } + return !!r ? r : '//hyphenator.googlecode.com/svn/trunk/'; + }()), + + /** + * @member {boolean} Hyphenator~isLocal + * @access private + * @desc + * isLocal is true, if Hyphenator is loaded from the same domain, as the webpage, but false, if + * it's loaded from an external source (i.e. directly from google.code) + */ + isLocal = (function () { + var re = false; + if (window.location.href.indexOf(basePath) !== -1) { + re = true; + } + return re; + }()), + + /** + * @member {boolean} Hyphenator~documentLoaded + * @access private + * @desc + * documentLoaded is true, when the DOM has been loaded. This is set by {@link Hyphenator~runWhenLoaded} + */ + documentLoaded = false, + + /** + * @member {boolean} Hyphenator~persistentConfig + * @access private + * @desc + * if persistentConfig is set to true (defaults to false), config options and the state of the + * toggleBox are stored in DOM-storage (according to the storage-setting). So they haven't to be + * set for each page. + * @default false + * @see {@link Hyphenator.config} + */ + persistentConfig = false, + + /** + * @member {boolean} Hyphenator~doFrames + * @access private + * @desc + * switch to control if frames/iframes should be hyphenated, too. + * defaults to false (frames are a bag of hurt!) + * @default false + * @see {@link Hyphenator.config} + */ + doFrames = false, + + /** + * @member {Object.<string,boolean>} Hyphenator~dontHyphenate + * @desc + * A key-value object containing all html-tags whose content should not be hyphenated + * @access private + */ + dontHyphenate = {'video': true, 'audio': true, 'script': true, 'code': true, 'pre': true, 'img': true, 'br': true, 'samp': true, 'kbd': true, 'var': true, 'abbr': true, 'acronym': true, 'sub': true, 'sup': true, 'button': true, 'option': true, 'label': true, 'textarea': true, 'input': true, 'math': true, 'svg': true, 'style': true}, + + /** + * @member {boolean} Hyphenator~enableCache + * @desc + * A variable to set if caching is enabled or not + * @default true + * @access private + * @see {@link Hyphenator.config} + */ + enableCache = true, + + /** + * @member {string} Hyphenator~storageType + * @desc + * A variable to define what html5-DOM-Storage-Method is used ('none', 'local' or 'session') + * @default 'local' + * @access private + * @see {@link Hyphenator.config} + */ + storageType = 'local', + + /** + * @member {Object|undefined} Hyphenator~storage + * @desc + * An alias to the storage defined in storageType. This is set by {@link Hyphenator~createStorage}. + * Set by {@link Hyphenator.run} + * @default null + * @access private + * @see {@link Hyphenator~createStorage} + */ + storage, + + /** + * @member {boolean} Hyphenator~enableReducedPatternSet + * @desc + * A variable to set if storing the used patterns is set + * @default false + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator.getRedPatternSet} + */ + enableReducedPatternSet = false, + + /** + * @member {boolean} Hyphenator~enableRemoteLoading + * @desc + * A variable to set if pattern files should be loaded remotely or not + * @default true + * @access private + * @see {@link Hyphenator.config} + */ + enableRemoteLoading = true, + + /** + * @member {boolean} Hyphenator~displayToggleBox + * @desc + * A variable to set if the togglebox should be displayed or not + * @default false + * @access private + * @see {@link Hyphenator.config} + */ + displayToggleBox = false, + + /** + * @method Hyphenator~onError + * @desc + * A function that can be called upon an error. + * @see {@link Hyphenator.config} + * @access private + */ + onError = function (e) { + window.alert("Hyphenator.js says:\n\nAn Error occurred:\n" + e.message); + }, + + /** + * @method Hyphenator~onWarning + * @desc + * A function that can be called upon a warning. + * @see {@link Hyphenator.config} + * @access private + */ + onWarning = function (e) { + window.console.log(e.message); + }, + + /** + * @method Hyphenator~createElem + * @desc + * A function alias to document.createElementNS or document.createElement + * @access private + */ + createElem = function (tagname, context) { + context = context || contextWindow; + var el; + if (window.document.createElementNS) { + el = context.document.createElementNS('http://www.w3.org/1999/xhtml', tagname); + } else if (window.document.createElement) { + el = context.document.createElement(tagname); + } + return el; + }, + + /** + * @member {boolean} Hyphenator~css3 + * @desc + * A variable to set if css3 hyphenation should be used + * @default false + * @access private + * @see {@link Hyphenator.config} + */ + css3 = false, + + /** + * @typedef {Object} Hyphenator~css3_hsupport + * @property {boolean} support - if css3-hyphenation is supported + * @property {string} property - the css property name to access hyphen-settings (e.g. -webkit-hyphens) + * @property {Object.<string, boolean>} supportedBrowserLangs - an object caching tested languages + * @property {function} checkLangSupport - a method that checks if the browser supports a requested language + */ + + /** + * @member {Hyphenator~css3_h9n} Hyphenator~css3_h9n + * @desc + * A generated object containing information for CSS3-hyphenation support + * This is set by {@link Hyphenator~css3_gethsupport} + * @default undefined + * @access private + * @see {@link Hyphenator~css3_gethsupport} + * @example + * //Check if browser supports a language + * css3_h9n.checkLangSupport(<lang>) + */ + css3_h9n, + + /** + * @method Hyphenator~css3_gethsupport + * @desc + * This function sets {@link Hyphenator~css3_h9n} for the current UA + * @type function + * @access private + * @see Hyphenator~css3_h9n + */ + css3_gethsupport = function () { + var s, + createLangSupportChecker = function (prefix) { + var testStrings = [ + //latin: 0 + 'aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz', + //cyrillic: 1 + 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя', + //arabic: 2 + 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', + //armenian: 3 + 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆ', + //bengali: 4 + 'ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ', + //devangari: 5 + 'ँंःअआइईउऊऋऌएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसहऽािीुूृॄेैोौ्॒॑ॠॡॢॣ', + //greek: 6 + 'αβγδεζηθικλμνξοπρσςτυφχψω', + //gujarati: 7 + 'બહઅઆઇઈઉઊઋૠએઐઓઔાિીુૂૃૄૢૣેૈોૌકખગઘઙચછજઝઞટઠડઢણતથદધનપફસભમયરલળવશષ', + //kannada: 8 + 'ಂಃಅಆಇಈಉಊಋಌಎಏಐಒಓಔಕಖಗಘಙಚಛಜಝಞಟಠಡಢಣತಥದಧನಪಫಬಭಮಯರಱಲಳವಶಷಸಹಽಾಿೀುೂೃೄೆೇೈೊೋೌ್ೕೖೞೠೡ', + //lao: 9 + 'ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮະັາິີຶືຸູົຼເແໂໃໄ່້໊໋ໜໝ', + //malayalam: 10 + 'ംഃഅആഇഈഉഊഋഌഎഏഐഒഓഔകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരറലളഴവശഷസഹാിീുൂൃെേൈൊോൌ്ൗൠൡൺൻർൽൾൿ', + //oriya: 11 + 'ଁଂଃଅଆଇଈଉଊଋଌଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଳଵଶଷସହାିୀୁୂୃେୈୋୌ୍ୗୠୡ', + //persian: 12 + 'أبتثجحخدذرزسشصضطظعغفقكلمنهوي', + //punjabi: 13 + 'ਁਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹਾਿੀੁੂੇੈੋੌ੍ੰੱ', + //tamil: 14 + 'ஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஷஸஹாிீுூெேைொோௌ்ௗ', + //telugu: 15 + 'ఁంఃఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡ' + ], + f = function (lang) { + var shadow, + computedHeight, + bdy, + r = false; + + //check if lang has already been tested + if (this.supportedBrowserLangs.hasOwnProperty(lang)) { + r = this.supportedBrowserLangs[lang]; + } else if (supportedLangs.hasOwnProperty(lang)) { + //create and append shadow-test-element + bdy = window.document.getElementsByTagName('body')[0]; + shadow = createElem('div', window); + shadow.id = 'Hyphenator_LanguageChecker'; + shadow.style.width = '5em'; + shadow.style[prefix] = 'auto'; + shadow.style.hyphens = 'auto'; + shadow.style.fontSize = '12px'; + shadow.style.lineHeight = '12px'; + shadow.style.visibility = 'hidden'; + shadow.lang = lang; + shadow.style['-webkit-locale'] = "'" + lang + "'"; + shadow.innerHTML = testStrings[supportedLangs[lang].script]; + bdy.appendChild(shadow); + //measure its height + computedHeight = shadow.offsetHeight; + //remove shadow element + bdy.removeChild(shadow); + r = (computedHeight > 12) ? true : false; + this.supportedBrowserLangs[lang] = r; + } else { + r = false; + } + return r; + }; + return f; + }, + r = { + support: false, + supportedBrowserLangs: {}, + property: '', + checkLangSupport: {} + }; + + if (window.getComputedStyle) { + s = window.getComputedStyle(window.document.getElementsByTagName('body')[0], null); + } else { + //ancient Browsers don't support CSS3 anyway + css3_h9n = r; + return; + } + + if (s.hyphens !== undefined) { + r.support = true; + r.property = 'hyphens'; + r.checkLangSupport = createLangSupportChecker('hyphens'); + } else if (s['-webkit-hyphens'] !== undefined) { + r.support = true; + r.property = '-webkit-hyphens'; + r.checkLangSupport = createLangSupportChecker('-webkit-hyphens'); + } else if (s.MozHyphens !== undefined) { + r.support = true; + r.property = '-moz-hyphens'; + r.checkLangSupport = createLangSupportChecker('MozHyphens'); + } else if (s['-ms-hyphens'] !== undefined) { + r.support = true; + r.property = '-ms-hyphens'; + r.checkLangSupport = createLangSupportChecker('-ms-hyphens'); + } + css3_h9n = r; + }, + + /** + * @member {string} Hyphenator~hyphenateClass + * @desc + * A string containing the css-class-name for the hyphenate class + * @default 'hyphenate' + * @access private + * @example + * <p class = "hyphenate">Text</p> + * @see {@link Hyphenator.config} + */ + hyphenateClass = 'hyphenate', + + /** + * @member {string} Hyphenator~urlHyphenateClass + * @desc + * A string containing the css-class-name for the urlhyphenate class + * @default 'urlhyphenate' + * @access private + * @example + * <p class = "urlhyphenate">Text</p> + * @see {@link Hyphenator.config} + */ + urlHyphenateClass = 'urlhyphenate', + + /** + * @member {string} Hyphenator~classPrefix + * @desc + * A string containing a unique className prefix to be used + * whenever Hyphenator sets a CSS-class + * @access private + */ + classPrefix = 'Hyphenator' + Math.round(Math.random() * 1000), + + /** + * @member {string} Hyphenator~hideClass + * @desc + * The name of the class that hides elements + * @access private + */ + hideClass = classPrefix + 'hide', + + /** + * @member {RegExp} Hyphenator~hideClassRegExp + * @desc + * RegExp to remove hideClass from a list of classes + * @access private + */ + hideClassRegExp = new RegExp("\\s?\\b" + hideClass + "\\b", "g"), + + /** + * @member {string} Hyphenator~hideClass + * @desc + * The name of the class that unhides elements + * @access private + */ + unhideClass = classPrefix + 'unhide', + + /** + * @member {RegExp} Hyphenator~hideClassRegExp + * @desc + * RegExp to remove unhideClass from a list of classes + * @access private + */ + unhideClassRegExp = new RegExp("\\s?\\b" + unhideClass + "\\b", "g"), + + /** + * @member {string} Hyphenator~css3hyphenateClass + * @desc + * The name of the class that hyphenates elements with css3 + * @access private + */ + css3hyphenateClass = classPrefix + 'css3hyphenate', + + /** + * @member {CSSEdit} Hyphenator~css3hyphenateClass + * @desc + * The var where CSSEdit class is stored + * @access private + */ + css3hyphenateClassHandle, + + /** + * @member {string} Hyphenator~dontHyphenateClass + * @desc + * A string containing the css-class-name for elements that should not be hyphenated + * @default 'donthyphenate' + * @access private + * @example + * <p class = "donthyphenate">Text</p> + * @see {@link Hyphenator.config} + */ + dontHyphenateClass = 'donthyphenate', + + /** + * @member {number} Hyphenator~min + * @desc + * A number wich indicates the minimal length of words to hyphenate. + * @default 6 + * @access private + * @see {@link Hyphenator.config} + */ + min = 6, + + /** + * @member {number} Hyphenator~orphanControl + * @desc + * Control how the last words of a line are handled: + * level 1 (default): last word is hyphenated + * level 2: last word is not hyphenated + * level 3: last word is not hyphenated and last space is non breaking + * @default 1 + * @access private + */ + orphanControl = 1, + + /** + * @member {boolean} Hyphenator~isBookmarklet + * @desc + * True if Hyphanetor runs as bookmarklet. + * @access private + */ + isBookmarklet = (function () { + var loc = null, + re = false, + scripts = contextWindow.document.getElementsByTagName('script'), + i = 0, + l = scripts.length; + while (!re && i < l) { + loc = scripts[i].getAttribute('src'); + if (!!loc && loc.indexOf('Hyphenator.js?bm=true') !== -1) { + re = true; + } + i += 1; + } + return re; + }()), + + /** + * @member {string|null} Hyphenator~mainLanguage + * @desc + * The general language of the document. In contrast to {@link Hyphenator~defaultLanguage}, + * mainLanguage is defined by the client (i.e. by the html or by a prompt). + * @access private + * @see {@link Hyphenator~autoSetMainLanguage} + */ + mainLanguage = null, + + /** + * @member {string|null} Hyphenator~defaultLanguage + * @desc + * The language defined by the developper. This language setting is defined by a config option. + * It is overwritten by any html-lang-attribute and only taken in count, when no such attribute can + * be found (i.e. just before the prompt). + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~autoSetMainLanguage} + */ + defaultLanguage = '', + + /** + * @member {ElementCollection} Hyphenator~elements + * @desc + * A class representing all elements (of type Element) that have to be hyphenated. This var is filled by + * {@link Hyphenator~gatherDocumentInfos} + * @access private + */ + elements = (function () { + /** + * @constructor Hyphenator~elements~ElementCollection~Element + * @desc represents a DOM Element with additional information + * @access private + */ + var Element = function (element) { + /** + * @member {Object} Hyphenator~elements~ElementCollection~Element~element + * @desc A DOM Element + * @access protected + */ + this.element = element; + /** + * @member {boolean} Hyphenator~elements~ElementCollection~Element~hyphenated + * @desc Marks if the element has been hyphenated + * @access protected + */ + this.hyphenated = false; + /** + * @member {boolean} Hyphenator~elements~ElementCollection~Element~treated + * @desc Marks if information of the element has been collected but not hyphenated (e.g. dohyphenation is off) + * @access protected + */ + this.treated = false; + }, + /** + * @constructor Hyphenator~elements~ElementCollection + * @desc A collection of Elements to be hyphenated + * @access protected + */ + ElementCollection = function () { + /** + * @member {number} Hyphenator~elements~ElementCollection~count + * @desc The Number of collected Elements + * @access protected + */ + this.count = 0; + /** + * @member {number} Hyphenator~elements~ElementCollection~hyCount + * @desc The Number of hyphenated Elements + * @access protected + */ + this.hyCount = 0; + /** + * @member {Object.<string, Array.<Element>>} Hyphenator~elements~ElementCollection~list + * @desc The collection of elements, where the key is a language code and the value is an array of elements + * @access protected + */ + this.list = {}; + }; + /** + * @member {Object} Hyphenator~elements~ElementCollection.prototype + * @augments Hyphenator~elements~ElementCollection + * @access protected + */ + ElementCollection.prototype = { + /** + * @method Hyphenator~elements~ElementCollection.prototype~add + * @augments Hyphenator~elements~ElementCollection + * @access protected + * @desc adds a DOM element to the collection + * @param {Object} el - The DOM element + * @param {string} lang - The language of the element + */ + add: function (el, lang) { + var elo = new Element(el); + if (!this.list.hasOwnProperty(lang)) { + this.list[lang] = []; + } + this.list[lang].push(elo); + this.count += 1; + return elo; + }, + + /** + * @method Hyphenator~elements~ElementCollection.prototype~remove + * @augments Hyphenator~elements~ElementCollection + * @access protected + * @desc removes a DOM element from the collection + * @param {Object} el - The DOM element + */ + remove: function (el) { + var lang, i, e, l; + for (lang in this.list) { + if (this.list.hasOwnProperty(lang)) { + for (i = 0; i < this.list[lang].length; i += 1) { + if (this.list[lang][i].element === el) { + e = i; + l = lang; + break; + } + } + } + } + this.list[l].splice(e, 1); + this.count -= 1; + this.hyCount -= 1; + }, + /** + * @callback Hyphenator~elements~ElementCollection.prototype~each~callback fn - The callback that is executed for each element + * @param {string} [k] The key (i.e. language) of the collection + * @param {Hyphenator~elements~ElementCollection~Element} element + */ + + /** + * @method Hyphenator~elements~ElementCollection.prototype~each + * @augments Hyphenator~elements~ElementCollection + * @access protected + * @desc takes each element of the collection as an argument of fn + * @param {Hyphenator~elements~ElementCollection.prototype~each~callback} fn - A function that takes an element as an argument + */ + each: function (fn) { + var k; + for (k in this.list) { + if (this.list.hasOwnProperty(k)) { + if (fn.length === 2) { + fn(k, this.list[k]); + } else { + fn(this.list[k]); + } + } + } + } + }; + return new ElementCollection(); + }()), + + + /** + * @member {Object.<sting, string>} Hyphenator~exceptions + * @desc + * An object containing exceptions as comma separated strings for each language. + * When the language-objects are loaded, their exceptions are processed, copied here and then deleted. + * Exceptions can also be set by the user. + * @see {@link Hyphenator~prepareLanguagesObj} + * @access private + */ + exceptions = {}, + + /** + * @member {Object.<string, boolean>} Hyphenator~docLanguages + * @desc + * An object holding all languages used in the document. This is filled by + * {@link Hyphenator~gatherDocumentInfos} + * @access private + */ + docLanguages = {}, + + /** + * @member {string} Hyphenator~url + * @desc + * A string containing a insane RegularExpression to match URL's + * @access private + */ + url = '(\\w*:\/\/)?((\\w*:)?(\\w*)@)?((([\\d]{1,3}\\.){3}([\\d]{1,3}))|((www\\.|[a-zA-Z]\\.)?[a-zA-Z0-9\\-\\.]+\\.([a-z]{2,4})))(:\\d*)?(\/[\\w#!:\\.?\\+=&%@!\\-]*)*', + // protocoll usr pwd ip or host tld port path + + /** + * @member {string} Hyphenator~mail + * @desc + * A string containing a RegularExpression to match mail-adresses + * @access private + */ + mail = '[\\w-\\.]+@[\\w\\.]+', + + /** + * @member {RegExp} Hyphenator~urlRE + * @desc + * A RegularExpressions-Object for url- and mail adress matching + * @access private + */ + urlOrMailRE = new RegExp('(' + url + ')|(' + mail + ')', 'i'), + + /** + * @member {string} Hyphenator~zeroWidthSpace + * @desc + * A string that holds a char. + * Depending on the browser, this is the zero with space or an empty string. + * zeroWidthSpace is used to break URLs + * @access private + */ + zeroWidthSpace = (function () { + var zws, ua = window.navigator.userAgent.toLowerCase(); + zws = String.fromCharCode(8203); //Unicode zero width space + if (ua.indexOf('msie 6') !== -1) { + zws = ''; //IE6 doesn't support zws + } + if (ua.indexOf('opera') !== -1 && ua.indexOf('version/10.00') !== -1) { + zws = ''; //opera 10 on XP doesn't support zws + } + return zws; + }()), + + /** + * @method Hyphenator~onBeforeWordHyphenation + * @desc + * This method is called just before a word is hyphenated. + * It is called with two parameters: the word and its language. + * The method must return a string (aka the word). + * @see {@link Hyphenator.config} + * @access private + * @param {string} word + * @param {string} lang + * @return {string} The word that goes into hyphenation + */ + onBeforeWordHyphenation = function (word) { + return word; + }, + + /** + * @method Hyphenator~onAfterWordHyphenation + * @desc + * This method is called for each word after it is hyphenated. + * Takes the word as a first parameter and its language as a second parameter. + * Returns a string that will replace the word that has been hyphenated. + * @see {@link Hyphenator.config} + * @access private + * @param {string} word + * @param {string} lang + * @return {string} The word that goes into hyphenation + */ + onAfterWordHyphenation = function (word) { + return word; + }, + + /** + * @method Hyphenator~onHyphenationDone + * @desc + * A method to be called, when the last element has been hyphenated. + * If there are frames the method is called for each frame. + * Therefore the location.href of the contextWindow calling this method is given as a parameter + * @see {@link Hyphenator.config} + * @param {string} context + * @access private + */ + onHyphenationDone = function (context) { + return context; + }, + + /** + * @name Hyphenator~selectorFunction + * @desc + * A function set by the user that has to return a HTMLNodeList or array of Elements to be hyphenated. + * By default this is set to false so we can check if a selectorFunction is set… + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~mySelectorFunction} + * @default false + * @type {function|boolean} + * @access private + */ + selectorFunction = false, + + /** + * @method Hyphenator~mySelectorFunction + * @desc + * A function that returns a HTMLNodeList or array of Elements to be hyphenated. + * By default it uses the classname ('hyphenate') to select the elements. + * @access private + */ + mySelectorFunction = function (hyphenateClass) { + var tmp, el = [], i, l; + if (window.document.getElementsByClassName) { + el = contextWindow.document.getElementsByClassName(hyphenateClass); + } else if (window.document.querySelectorAll) { + el = contextWindow.document.querySelectorAll('.' + hyphenateClass); + } else { + tmp = contextWindow.document.getElementsByTagName('*'); + l = tmp.length; + for (i = 0; i < l; i += 1) { + if (tmp[i].className.indexOf(hyphenateClass) !== -1 && tmp[i].className.indexOf(dontHyphenateClass) === -1) { + el.push(tmp[i]); + } + } + } + return el; + }, + + /** + * @method Hyphenator~selectElements + * @desc + * A function that uses either selectorFunction set by the user + * or the default mySelectorFunction. + * @access private + */ + selectElements = function () { + var elems; + if (selectorFunction) { + elems = selectorFunction(); + } else { + elems = mySelectorFunction(hyphenateClass); + } + return elems; + }, + + /** + * @member {string} Hyphenator~intermediateState + * @desc + * The visibility of elements while they are hyphenated: + * 'visible': unhyphenated text is visible and then redrawn when hyphenated. + * 'hidden': unhyphenated text is made invisible as soon as possible and made visible after hyphenation. + * @default 'hidden' + * @see {@link Hyphenator.config} + * @access private + */ + intermediateState = 'hidden', + + /** + * @member {string} Hyphenator~unhide + * @desc + * How hidden elements unhide: either simultaneous (default: 'wait') or progressively. + * 'wait' makes Hyphenator.js to wait until all elements are hyphenated (one redraw) + * With 'progressive' Hyphenator.js unhides elements as soon as they are hyphenated. + * @see {@link Hyphenator.config} + * @access private + */ + unhide = 'wait', + + /** + * @member {Array.<Hyphenator~CSSEdit>} Hyphenator~CSSEditors + * @desc A container array that holds CSSEdit classes + * For each window object one CSSEdit class is inserted + * @access private + */ + CSSEditors = [], + + /** + * @constructor Hyphenator~CSSEdit + * @desc + * This class handles access and editing of StyleSheets. + * Thanks to this styles (e.g. hiding and unhiding elements upon hyphenation) + * can be changed in one place instead for each element. + * @access private + */ + CSSEdit = function (w) { + w = w || window; + var doc = w.document, + /** + * @member {Object} Hyphenator~CSSEdit~sheet + * @desc + * A StyleSheet, where Hyphenator can write to. + * If no StyleSheet can be found, lets create one. + * @access private + */ + sheet = (function () { + var i, + l = doc.styleSheets.length, + s, + element, + r = false; + for (i = 0; i < l; i += 1) { + s = doc.styleSheets[i]; + try { + if (!!s.cssRules) { + r = s; + break; + } + } catch (ignore) {} + } + r = false; + if (r === false) { + element = doc.createElement('style'); + element.type = 'text/css'; + doc.getElementsByTagName('head')[0].appendChild(element); + r = doc.styleSheets[doc.styleSheets.length - 1]; + } + return r; + }()), + + /** + * @typedef {Object} Hyphenator~CSSEdit~changes + * @property {Object} sheet - The StyleSheet where the change was made + * @property {number} index - The index of the changed rule + */ + + /** + * @member {Array.<changes>} Hyphenator~CSSEdit~changes + * @desc + * Sets a CSS rule for a specified selector + * @access private + */ + changes = [], + + /** + * @typedef Hyphenator~CSSEdit~rule + * @property {number} index - The index of the rule + * @property {Object} rule - The style rule + */ + /** + * @method Hyphenator~CSSEdit~findRule + * @desc + * Searches the StyleSheets for a given selector and returns an object containing the rule. + * If nothing can be found, false is returned. + * @param {string} sel + * @return {Hyphenator~CSSEdit~rule|false} + * @access private + */ + findRule = function (sel) { + var s, rule, sheets = w.document.styleSheets, rules, i, j, r = false; + for (i = 0; i < sheets.length; i += 1) { + s = sheets[i]; + try { //FF has issues here with external CSS (s.o.p) + if (!!s.cssRules) { + rules = s.cssRules; + } else if (!!s.rules) { + // IE < 9 + rules = s.rules; + } + } catch (ignore) {} + if (!!rules && !!rules.length) { + for (j = 0; j < rules.length; j += 1) { + rule = rules[j]; + if (rule.selectorText === sel) { + r = { + index: j, + rule: rule + }; + } + } + } + } + return r; + }, + /** + * @method Hyphenator~CSSEdit~addRule + * @desc + * Adds a rule to the {@link Hyphenator~CSSEdit~sheet} + * @param {string} sel - The selector to be added + * @param {string} rulesStr - The rules for the specified selector + * @return {number} index of the new rule + * @access private + */ + addRule = function (sel, rulesStr) { + var i, r; + if (!!sheet.insertRule) { + if (!!sheet.cssRules) { + i = sheet.cssRules.length; + } else { + i = 0; + } + r = sheet.insertRule(sel + '{' + rulesStr + '}', i); + } else if (!!sheet.addRule) { + // IE < 9 + if (!!sheet.rules) { + i = sheet.rules.length; + } else { + i = 0; + } + sheet.addRule(sel, rulesStr, i); + r = i; + } + return r; + }, + /** + * @method Hyphenator~CSSEdit~removeRule + * @desc + * Removes a rule with the specified index from the specified sheet + * @param {Object} sheet - The style sheet + * @param {number} index - the index of the rule + * @access private + */ + removeRule = function (sheet, index) { + if (sheet.deleteRule) { + sheet.deleteRule(index); + } else { + // IE < 9 + sheet.removeRule(index); + } + }; + + return { + /** + * @method Hyphenator~CSSEdit.setRule + * @desc + * Sets a CSS rule for a specified selector + * @access public + * @param {string} sel - Selector + * @param {string} rulesString - CSS-Rules + */ + setRule: function (sel, rulesString) { + var i, existingRule, cssText; + existingRule = findRule(sel); + if (!!existingRule) { + if (!!existingRule.rule.cssText) { + cssText = existingRule.rule.cssText; + } else { + // IE < 9 + cssText = existingRule.rule.style.cssText.toLowerCase(); + } + if (cssText === '.' + hyphenateClass + ' { visibility: hidden; }') { + //browsers w/o IE < 9 and no additional style defs: + //add to [changes] for later removal + changes.push({sheet: existingRule.rule.parentStyleSheet, index: existingRule.index}); + } else if (cssText.indexOf('visibility: hidden') !== -1) { + // IE < 9 or additional style defs: + // add new rule + i = addRule(sel, rulesString); + //add to [changes] for later removal + changes.push({sheet: sheet, index: i}); + // clear existing def + existingRule.rule.style.visibility = ''; + } else { + i = addRule(sel, rulesString); + changes.push({sheet: sheet, index: i}); + } + } else { + i = addRule(sel, rulesString); + changes.push({sheet: sheet, index: i}); + } + }, + /** + * @method Hyphenator~CSSEdit.clearChanges + * @desc + * Removes all changes Hyphenator has made from the StyleSheets + * @access public + */ + clearChanges: function () { + var change = changes.pop(); + while (!!change) { + removeRule(change.sheet, change.index); + change = changes.pop(); + } + } + }; + }, + + /** + * @member {string} Hyphenator~hyphen + * @desc + * A string containing the character for in-word-hyphenation + * @default the soft hyphen + * @access private + * @see {@link Hyphenator.config} + */ + hyphen = String.fromCharCode(173), + + /** + * @member {string} Hyphenator~urlhyphen + * @desc + * A string containing the character for url/mail-hyphenation + * @default the zero width space + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~zeroWidthSpace} + */ + urlhyphen = zeroWidthSpace, + + /** + * @method Hyphenator~hyphenateURL + * @desc + * Puts {@link Hyphenator~urlhyphen} (default: zero width space) after each no-alphanumeric char that my be in a URL. + * @param {string} url to hyphenate + * @returns string the hyphenated URL + * @access public + */ + hyphenateURL = function (url) { + var tmp = url.replace(/([:\/\.\?#&\-_,;!@]+)/gi, '$&' + urlhyphen), + parts = tmp.split(urlhyphen), + i; + for (i = 0; i < parts.length; i += 1) { + if (parts[i].length > (2 * min)) { + parts[i] = parts[i].replace(/(\w{3})(\w)/gi, "$1" + urlhyphen + "$2"); + } + } + if (parts[parts.length - 1] === "") { + parts.pop(); + } + return parts.join(urlhyphen); + }, + + /** + * @member {boolean} Hyphenator~safeCopy + * @desc + * Defines wether work-around for copy issues is active or not + * @default true + * @access private + * @see {@link Hyphenator.config} + * @see {@link Hyphenator~registerOnCopy} + */ + safeCopy = true, + + /** + * @member {Object} Hyphenator~hyphRunFor + * @desc + * stores location.href for documents where run() has been executed + * to warn when Hyphenator.run() executed multiple times + * @access private + * @see {@link Hyphenator~runWhenLoaded} + */ + hyphRunFor = {}, + + /** + * @method Hyphenator~runWhenLoaded + * @desc + * A crossbrowser solution for the DOMContentLoaded-Event based on + * <a href = "http://jquery.com/">jQuery</a> + * I added some functionality: e.g. support for frames and iframes… + * @param {Object} w the window-object + * @param {function()} f the function to call when the document is ready + * @access private + */ + runWhenLoaded = function (w, f) { + var toplevel, + add = window.document.addEventListener ? 'addEventListener' : 'attachEvent', + rem = window.document.addEventListener ? 'removeEventListener' : 'detachEvent', + pre = window.document.addEventListener ? '' : 'on', + + init = function (context) { + if (hyphRunFor[context.location.href]) { + onWarning(new Error("Warning: multiple execution of Hyphenator.run() – This may slow down the script!")); + } + contextWindow = context || window; + f(); + hyphRunFor[contextWindow.location.href] = true; + }, + + doScrollCheck = function () { + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + w.document.documentElement.doScroll("left"); + } catch (error) { + window.setTimeout(doScrollCheck, 1); + return; + } + //maybe modern IE fired DOMContentLoaded + if (!hyphRunFor[w.location.href]) { + documentLoaded = true; + init(w); + } + }, + + doOnEvent = function (e) { + var i, fl, haveAccess; + if (!!e && e.type === 'readystatechange' && w.document.readyState !== 'interactive' && w.document.readyState !== 'complete') { + return; + } + + //DOM is ready/interactive, but frames may not be loaded yet! + //cleanup events + w.document[rem](pre + 'DOMContentLoaded', doOnEvent, false); + w.document[rem](pre + 'readystatechange', doOnEvent, false); + + //check frames + fl = w.frames.length; + if (fl === 0 || !doFrames) { + //there are no frames! + //cleanup events + w[rem](pre + 'load', doOnEvent, false); + documentLoaded = true; + init(w); + } else if (doFrames && fl > 0) { + //we have frames, so wait for onload and then initiate runWhenLoaded recursevly for each frame: + if (!!e && e.type === 'load') { + //cleanup events + w[rem](pre + 'load', doOnEvent, false); + for (i = 0; i < fl; i += 1) { + haveAccess = undefined; + //try catch isn't enough for webkit + try { + //opera throws only on document.toString-access + haveAccess = window.frames[i].document.toString(); + } catch (err) { + haveAccess = undefined; + } + if (!!haveAccess) { + runWhenLoaded(w.frames[i], f); + } + } + init(w); + } + } + }; + if (documentLoaded || w.document.readyState === 'complete') { + //Hyphenator has run already (documentLoaded is true) or + //it has been loaded after onLoad + documentLoaded = true; + doOnEvent({type: 'load'}); + } else { + //register events + w.document[add](pre + 'DOMContentLoaded', doOnEvent, false); + w.document[add](pre + 'readystatechange', doOnEvent, false); + w[add](pre + 'load', doOnEvent, false); + toplevel = false; + try { + toplevel = !window.frameElement; + } catch (ignore) {} + if (toplevel && w.document.documentElement.doScroll) { + doScrollCheck(); //calls init() + } + } + }, + + /** + * @method Hyphenator~getLang + * @desc + * Gets the language of an element. If no language is set, it may use the {@link Hyphenator~mainLanguage}. + * @param {Object} el The first parameter is an DOM-Element-Object + * @param {boolean} fallback The second parameter is a boolean to tell if the function should return the {@link Hyphenator~mainLanguage} + * if there's no language found for the element. + * @return {string} The language of the element + * @access private + */ + getLang = function (el, fallback) { + try { + return !!el.getAttribute('lang') ? el.getAttribute('lang').toLowerCase() : + !!el.getAttribute('xml:lang') ? el.getAttribute('xml:lang').toLowerCase() : + el.tagName.toLowerCase() !== 'html' ? getLang(el.parentNode, fallback) : + fallback ? mainLanguage : + null; + } catch (ignore) {} + }, + + /** + * @method Hyphenator~autoSetMainLanguage + * @desc + * Retrieves the language of the document from the DOM and sets the lang attribute of the html-tag. + * The function looks in the following places: + * <ul> + * <li>lang-attribute in the html-tag</li> + * <li><meta http-equiv = "content-language" content = "xy" /></li> + * <li><meta name = "DC.Language" content = "xy" /></li> + * <li><meta name = "language" content = "xy" /></li> + * </li> + * If nothing can be found a prompt using {@link Hyphenator~languageHint} and a prompt-string is displayed. + * If the retrieved language is in the object {@link Hyphenator~supportedLangs} it is copied to {@link Hyphenator~mainLanguage} + * @access private + */ + autoSetMainLanguage = function (w) { + w = w || contextWindow; + var el = w.document.getElementsByTagName('html')[0], + m = w.document.getElementsByTagName('meta'), + i, + getLangFromUser = function () { + var ml, + text = '', + dH = 300, + dW = 450, + dX = Math.floor((w.outerWidth - dW) / 2) + window.screenX, + dY = Math.floor((w.outerHeight - dH) / 2) + window.screenY, + ul = '', + languageHint; + if (!!window.showModalDialog && (w.location.href.indexOf(basePath) !== -1)) { + ml = window.showModalDialog(basePath + 'modalLangDialog.html', supportedLangs, "dialogWidth: " + dW + "px; dialogHeight: " + dH + "px; dialogtop: " + dY + "; dialogleft: " + dX + "; center: on; resizable: off; scroll: off;"); + } else { + languageHint = (function () { + var k, r = ''; + for (k in supportedLangs) { + if (supportedLangs.hasOwnProperty(k)) { + r += k + ', '; + } + } + r = r.substring(0, r.length - 2); + return r; + }()); + ul = window.navigator.language || window.navigator.userLanguage; + ul = ul.substring(0, 2); + if (!!supportedLangs[ul] && supportedLangs[ul].prompt !== '') { + text = supportedLangs[ul].prompt; + } else { + text = supportedLangs.en.prompt; + } + text += ' (ISO 639-1)\n\n' + languageHint; + ml = window.prompt(window.unescape(text), ul).toLowerCase(); + } + return ml; + }; + mainLanguage = getLang(el, false); + if (!mainLanguage) { + for (i = 0; i < m.length; i += 1) { + //<meta http-equiv = "content-language" content="xy"> + if (!!m[i].getAttribute('http-equiv') && (m[i].getAttribute('http-equiv').toLowerCase() === 'content-language')) { + mainLanguage = m[i].getAttribute('content').toLowerCase(); + } + //<meta name = "DC.Language" content="xy"> + if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase() === 'dc.language')) { + mainLanguage = m[i].getAttribute('content').toLowerCase(); + } + //<meta name = "language" content = "xy"> + if (!!m[i].getAttribute('name') && (m[i].getAttribute('name').toLowerCase() === 'language')) { + mainLanguage = m[i].getAttribute('content').toLowerCase(); + } + } + } + //get lang for frame from enclosing document + if (!mainLanguage && doFrames && (!!contextWindow.frameElement)) { + autoSetMainLanguage(window.parent); + } + //fallback to defaultLang if set + if (!mainLanguage && defaultLanguage !== '') { + mainLanguage = defaultLanguage; + } + //ask user for lang + if (!mainLanguage) { + mainLanguage = getLangFromUser(); + } + el.lang = mainLanguage; + }, + + /** + * @method Hyphenator~gatherDocumentInfos + * @desc + * This method runs through the DOM and executes the process()-function on: + * - every node returned by the {@link Hyphenator~selectorFunction}. + * @access private + */ + gatherDocumentInfos = function () { + var elToProcess, urlhyphenEls, tmp, i = 0, + /** + * @method Hyphenator~gatherDocumentInfos + * @desc + * This method copies the element to the elements-variable, sets its visibility + * to intermediateState, retrieves its language and recursivly descends the DOM-tree until + * the child-Nodes aren't of type 1 + * @param {Object} el a DOM element + * @param {string} plang the language of the parent element + * @param {boolean} isChild true, if the parent of el has been processed + */ + process = function (el, pLang, isChild) { + isChild = isChild || false; + var n, j = 0, hyphenate = true, eLang, + useCSS3 = function () { + css3hyphenateClassHandle = new CSSEdit(contextWindow); + css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); + css3hyphenateClassHandle.setRule('.' + dontHyphenateClass, css3_h9n.property + ': manual;'); + if ((eLang !== pLang) && css3_h9n.property.indexOf('webkit') !== -1) { + css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, '-webkit-locale : ' + eLang + ';'); + } + el.className = el.className + ' ' + css3hyphenateClass; + }, + useHyphenator = function () { + //quick fix for test111.html + //better: weight elements + if (isBookmarklet && eLang !== mainLanguage) { + return; + } + if (supportedLangs.hasOwnProperty(eLang)) { + docLanguages[eLang] = true; + } else { + if (supportedLangs.hasOwnProperty(eLang.split('-')[0])) { //try subtag + eLang = eLang.split('-')[0]; + docLanguages[eLang] = true; + } else if (!isBookmarklet) { + hyphenate = false; + onError(new Error('Language "' + eLang + '" is not yet supported.')); + } + } + if (hyphenate) { + if (intermediateState === 'hidden') { + el.className = el.className + ' ' + hideClass; + } + elements.add(el, eLang); + } + }; + + if (el.lang && typeof (el.lang) === 'string') { + eLang = el.lang.toLowerCase(); //copy attribute-lang to internal eLang + } else if (!!pLang && pLang !== '') { + eLang = pLang.toLowerCase(); + } else { + eLang = getLang(el, true); + } + + if (!isChild) { + if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { + useCSS3(); + } else { + useHyphenator(); + } + } else { + if (eLang !== pLang) { + if (css3 && css3_h9n.support && !!css3_h9n.checkLangSupport(eLang)) { + useCSS3(); + } else { + useHyphenator(); + } + } else { + if (!css3 || !css3_h9n.support || !css3_h9n.checkLangSupport(eLang)) { + useHyphenator(); + } // else do nothing + } + } + n = el.childNodes[j]; + while (!!n) { + if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && + n.className.indexOf(dontHyphenateClass) === -1 && + n.className.indexOf(urlHyphenateClass) === -1 && !elToProcess[n]) { + process(n, eLang, true); + } + j += 1; + n = el.childNodes[j]; + } + }, + processUrlStyled = function (el) { + var n, j = 0; + + n = el.childNodes[j]; + while (!!n) { + if (n.nodeType === 1 && !dontHyphenate[n.nodeName.toLowerCase()] && + n.className.indexOf(dontHyphenateClass) === -1 && + n.className.indexOf(hyphenateClass) === -1 && !urlhyphenEls[n]) { + processUrlStyled(n); + } else if (n.nodeType === 3) { + n.data = hyphenateURL(n.data); + } + j += 1; + n = el.childNodes[j]; + } + }; + + if (css3) { + css3_gethsupport(); + } + if (isBookmarklet) { + elToProcess = contextWindow.document.getElementsByTagName('body')[0]; + process(elToProcess, mainLanguage, false); + } else { + if (!css3 && intermediateState === 'hidden') { + CSSEditors.push(new CSSEdit(contextWindow)); + CSSEditors[CSSEditors.length - 1].setRule('.' + hyphenateClass, 'visibility: hidden;'); + CSSEditors[CSSEditors.length - 1].setRule('.' + hideClass, 'visibility: hidden;'); + CSSEditors[CSSEditors.length - 1].setRule('.' + unhideClass, 'visibility: visible;'); + } + elToProcess = selectElements(); + tmp = elToProcess[i]; + while (!!tmp) { + process(tmp, '', false); + i += 1; + tmp = elToProcess[i]; + } + + urlhyphenEls = mySelectorFunction(urlHyphenateClass); + i = 0; + tmp = urlhyphenEls[i]; + while (!!tmp) { + processUrlStyled(tmp); + i += 1; + tmp = urlhyphenEls[i]; + } + } + if (elements.count === 0) { + //nothing to hyphenate or all hyphenated by css3 + for (i = 0; i < CSSEditors.length; i += 1) { + CSSEditors[i].clearChanges(); + } + onHyphenationDone(contextWindow.location.href); + } + }, + + /** + * @method Hyphenator~convertPatterns + * @desc + * converts patterns of the given language to a trie + * @access private + * @param {Object} language object whose patterns shall be converted + */ + convertPatterns = function (lo) { + var size, + tree = {}, + convert = function (psize, patterns) { + var i = 0, + t = tree, + cc = 0, + points = [], + ppos = 0, + lastwasp = false, + len = 0; + while (i < patterns.length) { + if (len < psize) { + cc = patterns.charCodeAt(i); + if (cc >= 49 && cc <= 57) { + //this is a hpoint (1-9) + points[ppos] = cc - 48; + ppos += 1; + lastwasp = true; + } else { + //this is a alphabetic char --> extend the tree? + if (!t[cc]) { + t[cc] = {}; + } + t = t[cc]; //go to subtree + if (!lastwasp) { + points[ppos] = 0; + ppos += 1; + } + lastwasp = false; + } + len += 1; + i += 1; + } + + if (len === psize) { + //add last point (0) + if (!lastwasp) { + points[ppos] = 0; + } + //write points + t.tpoints = points; + //reset + t = tree; + points = []; + ppos = 0; + lastwasp = false; + len = 0; + } + } + }; + for (size in lo.patterns) { + if (lo.patterns.hasOwnProperty(size)) { + convert(parseInt(size, 10), lo.patterns[size]); + } + } + lo.patterns = tree; + }, + + /** + * @method Hyphenator~recreatePattern + * @desc + * Recreates the pattern for the reducedPatternSet + * @param {string} pattern The pattern (chars) + * @param {string} nodePoints The nodePoints (integers) + * @access private + * @return {string} The pattern (chars and numbers) + */ + recreatePattern = function (pattern, nodePoints) { + var r = [], c = pattern.split(''), i; + for (i = 0; i < nodePoints.length; i += 1) { + if (nodePoints[i] !== 0) { + r.push(nodePoints[i]); + } + if (c[i]) { + r.push(c[i]); + } + } + return r.join(''); + }, + + /** + * @method Hyphenator~convertExceptionsToObject + * @desc + * Converts a list of comma seprated exceptions to an object: + * 'Fortran,Hy-phen-a-tion' -> {'Fortran':'Fortran','Hyphenation':'Hy-phen-a-tion'} + * @access private + * @param {string} exc a comma separated string of exceptions (without spaces) + * @return {Object.<string, string>} + */ + convertExceptionsToObject = function (exc) { + var w = exc.split(', '), + r = {}, + i, + l, + key; + for (i = 0, l = w.length; i < l; i += 1) { + key = w[i].replace(/-/g, ''); + if (!r.hasOwnProperty(key)) { + r[key] = w[i]; + } + } + return r; + }, + + /** + * @method Hyphenator~loadPatterns + * @desc + * Checks if the requested file is available in the network. + * Adds a <script>-Tag to the DOM to load an externeal .js-file containing patterns and settings for the given language. + * If the given language is not in the {@link Hyphenator~supportedLangs}-Object it returns. + * One may ask why we are not using AJAX to load the patterns. The XMLHttpRequest-Object + * has a same-origin-policy. This makes the Bookmarklet impossible. + * @param {string} lang The language to load the patterns for + * @access private + * @see {@link Hyphenator~basePath} + */ + loadPatterns = function (lang) { + var location, xhr, head, script; + if (supportedLangs.hasOwnProperty(lang) && !Hyphenator.languages[lang]) { + location = basePath + 'patterns/' + supportedLangs[lang].file; + } else { + return; + } + if (isLocal && !isBookmarklet) { + //check if 'location' is available: + xhr = null; + try { + // Mozilla, Opera, Safari and Internet Explorer (ab v7) + xhr = new window.XMLHttpRequest(); + } catch (e) { + try { + //IE>=6 + xhr = new window.ActiveXObject("Microsoft.XMLHTTP"); + } catch (e2) { + try { + //IE>=5 + xhr = new window.ActiveXObject("Msxml2.XMLHTTP"); + } catch (e3) { + xhr = null; + } + } + } + + if (xhr) { + xhr.open('HEAD', location, true); + xhr.setRequestHeader('Cache-Control', 'no-cache'); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status === 404) { + onError(new Error('Could not load\n' + location)); + delete docLanguages[lang]; + return; + } + } + }; + xhr.send(null); + } + } + if (createElem) { + head = window.document.getElementsByTagName('head').item(0); + script = createElem('script', window); + script.src = location; + script.type = 'text/javascript'; + script.charset = 'utf8'; + head.appendChild(script); + } + }, + + /** + * @method Hyphenator~prepareLanguagesObj + * @desc + * Adds some feature to the language object: + * - cache + * - exceptions + * Converts the patterns to a trie using {@link Hyphenator~convertPatterns} + * If storage is active the object is stored there. + * @access private + * @param {string} lang The language of the language object + */ + prepareLanguagesObj = function (lang) { + var lo = Hyphenator.languages[lang], wrd; + + if (!lo.prepared) { + if (enableCache) { + lo.cache = {}; + //Export + //lo['cache'] = lo.cache; + } + if (enableReducedPatternSet) { + lo.redPatSet = {}; + } + //add exceptions from the pattern file to the local 'exceptions'-obj + if (lo.hasOwnProperty('exceptions')) { + Hyphenator.addExceptions(lang, lo.exceptions); + delete lo.exceptions; + } + //copy global exceptions to the language specific exceptions + if (exceptions.hasOwnProperty('global')) { + if (exceptions.hasOwnProperty(lang)) { + exceptions[lang] += ', ' + exceptions.global; + } else { + exceptions[lang] = exceptions.global; + } + } + //move exceptions from the the local 'exceptions'-obj to the 'language'-object + if (exceptions.hasOwnProperty(lang)) { + lo.exceptions = convertExceptionsToObject(exceptions[lang]); + delete exceptions[lang]; + } else { + lo.exceptions = {}; + } + convertPatterns(lo); + wrd = '[\\w' + lo.specialChars + '@' + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + lo.genRegExp = new RegExp('(' + url + ')|(' + mail + ')|(' + wrd + ')', 'gi'); + lo.prepared = true; + } + if (!!storage) { + storage.setItem(lang, window.JSON.stringify(lo)); + } + + }, + + /**** + * @method Hyphenator~prepare + * @desc + * This funtion prepares the Hyphenator~Object: If RemoteLoading is turned off, it assumes + * that the patternfiles are loaded, all conversions are made and the callback is called. + * If storage is active the object is retrieved there. + * If RemoteLoading is on (default), it loads the pattern files and waits until they are loaded, + * by repeatedly checking Hyphenator.languages. If a patternfile is loaded the patterns are + * converted to their object style and the lang-object extended. + * Finally the callback is called. + * @access private + */ + prepare = function (callback) { + var lang, interval, tmp1, tmp2, + languagesLoaded = function () { + var finishedLoading = true, l; + for (l in docLanguages) { + if (docLanguages.hasOwnProperty(l)) { + finishedLoading = false; + if (!!Hyphenator.languages[l]) { + delete docLanguages[l]; + //do conversion while other patterns are loading: + prepareLanguagesObj(l); + callback(l); + } + } + } + return finishedLoading; + }; + + if (!enableRemoteLoading) { + for (lang in Hyphenator.languages) { + if (Hyphenator.languages.hasOwnProperty(lang)) { + prepareLanguagesObj(lang); + } + } + callback('*'); + return; + } + // get all languages that are used and preload the patterns + for (lang in docLanguages) { + if (docLanguages.hasOwnProperty(lang)) { + if (!!storage && storage.test(lang)) { + Hyphenator.languages[lang] = window.JSON.parse(storage.getItem(lang)); + if (exceptions.hasOwnProperty('global')) { + tmp1 = convertExceptionsToObject(exceptions.global); + for (tmp2 in tmp1) { + if (tmp1.hasOwnProperty(tmp2)) { + Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; + } + } + } + //Replace exceptions since they may have been changed: + if (exceptions.hasOwnProperty(lang)) { + tmp1 = convertExceptionsToObject(exceptions[lang]); + for (tmp2 in tmp1) { + if (tmp1.hasOwnProperty(tmp2)) { + Hyphenator.languages[lang].exceptions[tmp2] = tmp1[tmp2]; + } + } + delete exceptions[lang]; + } + //Replace genRegExp since it may have been changed: + tmp1 = '[\\w' + Hyphenator.languages[lang].specialChars + '@' + String.fromCharCode(173) + String.fromCharCode(8204) + '-]{' + min + ',}'; + Hyphenator.languages[lang].genRegExp = new RegExp('(' + url + ')|(' + mail + ')|(' + tmp1 + ')', 'gi'); + + delete docLanguages[lang]; + callback(lang); + } else { + loadPatterns(lang); + } + } + } + // else async wait until patterns are loaded, then hyphenate + if (!languagesLoaded()) { + interval = window.setInterval(function () { + var loadingDone = languagesLoaded(); + if (loadingDone) { + window.clearInterval(interval); + } + }, 100); + } + }, + + /** + * @method Hyphenator~toggleBox + * @desc + * Creates the toggleBox: a small button to turn off/on hyphenation on a page. + * @see {@link Hyphenator.config} + * @access private + */ + toggleBox = function () { + var bdy, myTextNode, + text = (Hyphenator.doHyphenation ? 'Hy-phen-a-tion' : 'Hyphenation'), + myBox = contextWindow.document.getElementById('HyphenatorToggleBox'); + if (!!myBox) { + myBox.firstChild.data = text; + } else { + bdy = contextWindow.document.getElementsByTagName('body')[0]; + myBox = createElem('div', contextWindow); + myBox.setAttribute('id', 'HyphenatorToggleBox'); + myBox.setAttribute('class', dontHyphenateClass); + myTextNode = contextWindow.document.createTextNode(text); + myBox.appendChild(myTextNode); + myBox.onclick = Hyphenator.toggleHyphenation; + myBox.style.position = 'absolute'; + myBox.style.top = '0px'; + myBox.style.right = '0px'; + myBox.style.margin = '0'; + myBox.style.backgroundColor = '#AAAAAA'; + myBox.style.color = '#FFFFFF'; + myBox.style.font = '6pt Arial'; + myBox.style.letterSpacing = '0.2em'; + myBox.style.padding = '3px'; + myBox.style.cursor = 'pointer'; + myBox.style.WebkitBorderBottomLeftRadius = '4px'; + myBox.style.MozBorderRadiusBottomleft = '4px'; + myBox.style.borderBottomLeftRadius = '4px'; + bdy.appendChild(myBox); + } + }, + + + /** + * @method Hyphenator~hyphenateWord + * @desc + * This function is the heart of Hyphenator.js. It returns a hyphenated word. + * + * If there's already a {@link Hyphenator~hypen} in the word, the word is returned as it is. + * If the word is in the exceptions list or in the cache, it is retrieved from it. + * If there's a '-' hyphenate the parts. + * The hyphenated word is returned and (if acivated) cached. + * Both special Events onBeforeWordHyphenation and onAfterWordHyphenation are called for the word. + * @param {Object} lo A language object (containing the patterns) + * @param {string} lang The language of the word + * @param {string} word The word + * @returns string The hyphenated word + * @access public + */ + hyphenateWord = function (lo, lang, word) { + var parts, + i, + pattern, + ww, + wwlen, + wwhp = [], + pstart, + plen, + trie = lo.patterns, + node, + nodePoints, + hp, + wordLength = word.length, + hw = '', + doCharSubst = function (w) { + var subst, r; + for (subst in lo.charSubstitution) { + if (lo.charSubstitution.hasOwnProperty(subst)) { + r = w.replace(new RegExp(subst, 'g'), lo.charSubstitution[subst]); + } + } + return r; + }; + word = onBeforeWordHyphenation(word, lang); + if (word === '') { + hw = ''; + } else if (enableCache && lo.cache.hasOwnProperty(word)) { //the word is in the cache + hw = lo.cache[word]; + } else if (word.indexOf(hyphen) !== -1) { + //word already contains shy; -> leave at it is! + hw = word; + } else if (lo.exceptions.hasOwnProperty(word)) { //the word is in the exceptions list + hw = lo.exceptions[word].replace(/-/g, hyphen); + } else if (word.indexOf('-') !== -1) { + //word contains '-' -> hyphenate the parts separated with '-' + parts = word.split('-'); + for (i = 0; i < parts.length; i += 1) { + parts[i] = hyphenateWord(lo, lang, parts[i]); + } + hw = parts.join('-'); + } else { + ww = word.toLowerCase(); + + if (!!lo.charSubstitution) { + ww = doCharSubst(ww); + } + if (word.indexOf("'") !== -1) { + ww = ww.replace("'", "’"); //replace APOSTROPHE with RIGHT SINGLE QUOTATION MARK (since the latter is used in the patterns) + } + ww = '_' + ww + '_'; + wwlen = ww.length; + for (hp = 0; hp < wwlen + 1; hp += 1) { + wwhp[hp] = 0; + } + for (pstart = 0; pstart < wwlen; pstart += 1) { + node = trie; + pattern = ''; + for (plen = pstart; plen < wwlen; plen += 1) { + node = node[ww.charCodeAt(plen)]; //go sub trie + if (node) { + if (enableReducedPatternSet) { + pattern += ww.charAt(plen); + } + nodePoints = node.tpoints; + if (nodePoints) { + if (enableReducedPatternSet) { + if (!lo.redPatSet) { + lo.redPatSet = {}; + } + lo.redPatSet[pattern] = recreatePattern(pattern, nodePoints); + } + for (hp = 0; hp < nodePoints.length; hp += 1) { + wwhp[pstart + hp] = Math.max(wwhp[pstart + hp], nodePoints[hp]); + } + } + } else { + break; + } + } + } + //return wwhp + for (hp = 0; hp < wordLength; hp += 1) { + if (hp >= lo.leftmin && hp <= (wordLength - lo.rightmin) && (wwhp[hp + 1] % 2) !== 0) { + hw += hyphen + word.charAt(hp); + } else { + hw += word.charAt(hp); + } + } + } + hw = onAfterWordHyphenation(hw, lang); + if (enableCache) { //put the word in the cache + lo.cache[word] = hw; + } + return hw; + }, + + /** + * @method Hyphenator~removeHyphenationFromElement + * @desc + * Removes all hyphens from the element. If there are other elements, the function is + * called recursively. + * Removing hyphens is usefull if you like to copy text. Some browsers are buggy when the copy hyphenated texts. + * @param {Object} el The element where to remove hyphenation. + * @access public + */ + removeHyphenationFromElement = function (el) { + var h, u, i = 0, n; + switch (hyphen) { + case '|': + h = '\\|'; + break; + case '+': + h = '\\+'; + break; + case '*': + h = '\\*'; + break; + default: + h = hyphen; + } + switch (urlhyphen) { + case '|': + u = '\\|'; + break; + case '+': + u = '\\+'; + break; + case '*': + u = '\\*'; + break; + default: + u = urlhyphen; + } + n = el.childNodes[i]; + while (!!n) { + if (n.nodeType === 3) { + n.data = n.data.replace(new RegExp(h, 'g'), ''); + n.data = n.data.replace(new RegExp(u, 'g'), ''); + } else if (n.nodeType === 1) { + removeHyphenationFromElement(n); + } + i += 1; + n = el.childNodes[i]; + } + }, + + copy = (function () { + var Copy = function () { + + this.oncopyHandler = function (e) { + e = e || window.event; + var shadow, selection, range, rangeShadow, restore, + target = e.target || e.srcElement, + currDoc = target.ownerDocument, + bdy = currDoc.getElementsByTagName('body')[0], + targetWindow = currDoc.defaultView || currDoc.parentWindow; + if (target.tagName && dontHyphenate[target.tagName.toLowerCase()]) { + //Safari needs this + return; + } + //create a hidden shadow element + shadow = currDoc.createElement('div'); + //Moving the element out of the screen doesn't work for IE9 (https://connect.microsoft.com/IE/feedback/details/663981/) + //shadow.style.overflow = 'hidden'; + //shadow.style.position = 'absolute'; + //shadow.style.top = '-5000px'; + //shadow.style.height = '1px'; + //doing this instead: + shadow.style.color = window.getComputedStyle ? targetWindow.getComputedStyle(bdy, null).backgroundColor : '#FFFFFF'; + shadow.style.fontSize = '0px'; + bdy.appendChild(shadow); + if (!!window.getSelection) { + //FF3, Webkit, IE9 + e.stopPropagation(); + selection = targetWindow.getSelection(); + range = selection.getRangeAt(0); + shadow.appendChild(range.cloneContents()); + removeHyphenationFromElement(shadow); + selection.selectAllChildren(shadow); + restore = function () { + shadow.parentNode.removeChild(shadow); + selection.removeAllRanges(); //IE9 needs that + selection.addRange(range); + }; + } else { + // IE<9 + e.cancelBubble = true; + selection = targetWindow.document.selection; + range = selection.createRange(); + shadow.innerHTML = range.htmlText; + removeHyphenationFromElement(shadow); + rangeShadow = bdy.createTextRange(); + rangeShadow.moveToElementText(shadow); + rangeShadow.select(); + restore = function () { + shadow.parentNode.removeChild(shadow); + if (range.text !== "") { + range.select(); + } + }; + } + window.setTimeout(restore, 0); + }; + + this.removeOnCopy = function (el) { + var body = el.ownerDocument.getElementsByTagName('body')[0]; + if (!body) { + return; + } + el = el || body; + if (window.removeEventListener) { + el.removeEventListener("copy", this.oncopyHandler, true); + } else { + el.detachEvent("oncopy", this.oncopyHandler); + } + }; + + this.registerOnCopy = function (el) { + var body = el.ownerDocument.getElementsByTagName('body')[0]; + if (!body) { + return; + } + el = el || body; + if (window.addEventListener) { + el.addEventListener("copy", this.oncopyHandler, true); + } else { + el.attachEvent("oncopy", this.oncopyHandler); + } + }; + }; + + return (safeCopy ? new Copy() : false); + }()), + + + /** + * @method Hyphenator~checkIfAllDone + * @desc + * Checks if all elements in {@link Hyphenator~elements} are hyphenated, unhides them and fires onHyphenationDone() + * @access private + */ + checkIfAllDone = function () { + var allDone = true, i, doclist = {}, doc; + elements.each(function (ellist) { + var j, l = ellist.length; + for (j = 0; j < l; j += 1) { + allDone = allDone && ellist[j].hyphenated; + if (!doclist.hasOwnProperty(ellist[j].element.baseURI)) { + doclist[ellist[j].element.ownerDocument.location.href] = true; + } + doclist[ellist[j].element.ownerDocument.location.href] = doclist[ellist[j].element.ownerDocument.location.href] && ellist[j].hyphenated; + } + }); + if (allDone) { + if (intermediateState === 'hidden' && unhide === 'progressive') { + elements.each(function (ellist) { + var j, l = ellist.length, el; + for (j = 0; j < l; j += 1) { + el = ellist[j].element; + el.className = el.className.replace(unhideClassRegExp, ''); + if (el.className === '') { + el.removeAttribute('class'); + } + } + }); + } + for (i = 0; i < CSSEditors.length; i += 1) { + CSSEditors[i].clearChanges(); + } + for (doc in doclist) { + if (doclist.hasOwnProperty(doc)) { + onHyphenationDone(doc); + } + } + } + }, + + + /** + * @method Hyphenator~hyphenateElement + * @desc + * Takes the content of the given element and - if there's text - replaces the words + * by hyphenated words. If there's another element, the function is called recursively. + * When all words are hyphenated, the visibility of the element is set to 'visible'. + * @param {string} lang - The language-code of the element + * @param {Element} elo - The element to hyphenate {@link Hyphenator~elements~ElementCollection~Element} + * @access private + */ + hyphenateElement = function (lang, elo) { + var el = elo.element, + hyphenate, + n, + i, + lo, + controlOrphans = function (part) { + var h, r; + switch (hyphen) { + case '|': + h = '\\|'; + break; + case '+': + h = '\\+'; + break; + case '*': + h = '\\*'; + break; + default: + h = hyphen; + } + //strip off blank space at the end (omitted closing tags) + part = part.replace(/[\s]*$/, ''); + if (orphanControl >= 2) { + //remove hyphen points from last word + r = part.split(' '); + r[1] = r[1].replace(new RegExp(h, 'g'), ''); + r[1] = r[1].replace(new RegExp(zeroWidthSpace, 'g'), ''); + r = r.join(' '); + } + if (orphanControl === 3) { + //replace spaces by non breaking spaces + r = r.replace(/[ ]+/g, String.fromCharCode(160)); + } + return r; + }; + if (Hyphenator.languages.hasOwnProperty(lang)) { + lo = Hyphenator.languages[lang]; + hyphenate = function (word) { + var r; + if (!Hyphenator.doHyphenation) { + r = word; + } else if (urlOrMailRE.test(word)) { + r = hyphenateURL(word); + } else { + r = hyphenateWord(lo, lang, word); + } + return r; + }; + if (safeCopy && (el.tagName.toLowerCase() !== 'body')) { + copy.registerOnCopy(el); + } + i = 0; + n = el.childNodes[i]; + while (!!n) { + if (n.nodeType === 3 && n.data.length >= min) { //type 3 = #text -> hyphenate! + n.data = n.data.replace(lo.genRegExp, hyphenate); + if (orphanControl !== 1) { + n.data = n.data.replace(/[\S]+ [\S]+[\s]*$/, controlOrphans); + } + } + i += 1; + n = el.childNodes[i]; + } + } + if (intermediateState === 'hidden' && unhide === 'wait') { + el.className = el.className.replace(hideClassRegExp, ''); + if (el.className === '') { + el.removeAttribute('class'); + } + } + if (intermediateState === 'hidden' && unhide === 'progressive') { + el.className = el.className.replace(hideClassRegExp, ' ' + unhideClass); + } + elo.hyphenated = true; + elements.hyCount += 1; + if (elements.count <= elements.hyCount) { + checkIfAllDone(); + } + }, + + /** + * @method Hyphenator~hyphenateLanguageElements + * @desc + * Calls hyphenateElement() for all elements of the specified language. + * If the language is '*' then all elements are hyphenated. + * This is done with a setTimout + * to prevent a "long running Script"-alert when hyphenating large pages. + * Therefore a tricky bind()-function was necessary. + * @param {string} lang The language of the elements to hyphenate + * @access private + */ + hyphenateLanguageElements = function (lang) { + function bind(fun, arg1, arg2) { + return function () { + return fun(arg1, arg2); + }; + } + var i, l; + if (lang === '*') { + elements.each(function (lang, ellist) { + var j, le = ellist.length; + for (j = 0; j < le; j += 1) { + window.setTimeout(bind(hyphenateElement, lang, ellist[j]), 0); + } + }); + } else { + if (elements.list.hasOwnProperty(lang)) { + l = elements.list[lang].length; + for (i = 0; i < l; i += 1) { + window.setTimeout(bind(hyphenateElement, lang, elements.list[lang][i]), 0); + } + } + } + }, + + /** + * @method Hyphenator~removeHyphenationFromDocument + * @desc + * Does what it says and unregisters the onCopyEvent from the elements + * @access private + */ + removeHyphenationFromDocument = function () { + elements.each(function (ellist) { + var i, l = ellist.length; + for (i = 0; i < l; i += 1) { + removeHyphenationFromElement(ellist[i].element); + if (safeCopy) { + copy.removeOnCopy(ellist[i].element); + } + ellist[i].hyphenated = false; + } + }); + }, + + /** + * @method Hyphenator~createStorage + * @desc + * inits the private var {@link Hyphenator~storage) depending of the setting in {@link Hyphenator~storageType} + * and the supported features of the system. + * @access private + */ + createStorage = function () { + var s; + try { + if (storageType !== 'none' && + window.localStorage !== undefined && + window.sessionStorage !== undefined && + window.JSON.stringify !== undefined && + window.JSON.parse !== undefined) { + switch (storageType) { + case 'session': + s = window.sessionStorage; + break; + case 'local': + s = window.localStorage; + break; + default: + s = undefined; + break; + } + //check for private mode + s.setItem('storageTest', '1'); + s.removeItem('storageTest'); + } + } catch (e) { + //FF throws an error if DOM.storage.enabled is set to false + s = undefined; + } + if (s) { + storage = { + prefix: 'Hyphenator_' + Hyphenator.version + '_', + store: s, + test: function (name) { + var val = this.store.getItem(this.prefix + name); + return (!!val) ? true : false; + }, + getItem: function (name) { + return this.store.getItem(this.prefix + name); + }, + setItem: function (name, value) { + try { + this.store.setItem(this.prefix + name, value); + } catch (e) { + onError(e); + } + } + }; + } else { + storage = undefined; + } + }, + + /** + * @method Hyphenator~storeConfiguration + * @desc + * Stores the current config-options in DOM-Storage + * @access private + */ + storeConfiguration = function () { + if (!storage) { + return; + } + var settings = { + 'STORED': true, + 'classname': hyphenateClass, + 'urlclassname': urlHyphenateClass, + 'donthyphenateclassname': dontHyphenateClass, + 'minwordlength': min, + 'hyphenchar': hyphen, + 'urlhyphenchar': urlhyphen, + 'togglebox': toggleBox, + 'displaytogglebox': displayToggleBox, + 'remoteloading': enableRemoteLoading, + 'enablecache': enableCache, + 'enablereducedpatternset': enableReducedPatternSet, + 'onhyphenationdonecallback': onHyphenationDone, + 'onerrorhandler': onError, + 'onwarninghandler': onWarning, + 'intermediatestate': intermediateState, + 'selectorfunction': selectorFunction || mySelectorFunction, + 'safecopy': safeCopy, + 'doframes': doFrames, + 'storagetype': storageType, + 'orphancontrol': orphanControl, + 'dohyphenation': Hyphenator.doHyphenation, + 'persistentconfig': persistentConfig, + 'defaultlanguage': defaultLanguage, + 'useCSS3hyphenation': css3, + 'unhide': unhide, + 'onbeforewordhyphenation': onBeforeWordHyphenation, + 'onafterwordhyphenation': onAfterWordHyphenation + }; + storage.setItem('config', window.JSON.stringify(settings)); + }, + + /** + * @method Hyphenator~restoreConfiguration + * @desc + * Retrieves config-options from DOM-Storage and does configuration accordingly + * @access private + */ + restoreConfiguration = function () { + var settings; + if (storage.test('config')) { + settings = window.JSON.parse(storage.getItem('config')); + Hyphenator.config(settings); + } + }; + + return { + + /** + * @member {string} Hyphenator.version + * @desc + * String containing the actual version of Hyphenator.js + * [major release].[minor releas].[bugfix release] + * major release: new API, new Features, big changes + * minor release: new languages, improvements + * @access public + */ + version: '4.3.0', + + /** + * @member {boolean} Hyphenator.doHyphenation + * @desc + * If doHyphenation is set to false, hyphenateDocument() isn't called. + * All other actions are performed. + * @default true + */ + doHyphenation: true, + + /** + * @typedef {Object} Hyphenator.languages.language + * @property {Number} leftmin - The minimum of chars to remain on the old line + * @property {Number} rightmin - The minimum of chars to go on the new line + * @property {string} specialChars - Non-ASCII chars in the alphabet. + * @property {Object.<number, string>} patterns - the patterns in a compressed format. The key is the length of the patterns in the value string. + * @property {Object.<string, string>} charSubstitution - optional: a hash table with chars that are replaced during hyphenation + * @property {string | Object.<string, string>} exceptions - optional: a csv string containing exceptions + */ + + /** + * @member {Object.<string, Hyphenator.languages.language>} Hyphenator.languages + * @desc + * Objects that holds key-value pairs, where key is the language and the value is the + * language-object loaded from (and set by) the pattern file. + * @namespace Hyphenator.languages + * @access public + */ + languages: {}, + + + /** + * @method Hyphenator.config + * @desc + * The Hyphenator.config() function that takes an object as an argument. The object contains key-value-pairs + * containig Hyphenator-settings. + * @param {Hyphenator.config} obj + * @access public + * @example + * <script src = "Hyphenator.js" type = "text/javascript"></script> + * <script type = "text/javascript"> + * Hyphenator.config({'minwordlength':4,'hyphenchar':'|'}); + * Hyphenator.run(); + * </script> + */ + config: function (obj) { + var assert = function (name, type) { + var r, t; + t = typeof obj[name]; + if (t === type) { + r = true; + } else { + onError(new Error('Config onError: ' + name + ' must be of type ' + type)); + r = false; + } + return r; + }, + key; + + if (obj.hasOwnProperty('storagetype')) { + if (assert('storagetype', 'string')) { + storageType = obj.storagetype; + } + if (!storage) { + createStorage(); + } + } + if (!obj.hasOwnProperty('STORED') && storage && obj.hasOwnProperty('persistentconfig') && obj.persistentconfig === true) { + restoreConfiguration(); + } + + for (key in obj) { + if (obj.hasOwnProperty(key)) { + switch (key) { + case 'STORED': + break; + case 'classname': + if (assert('classname', 'string')) { + hyphenateClass = obj[key]; + } + break; + case 'urlclassname': + if (assert('urlclassname', 'string')) { + urlHyphenateClass = obj[key]; + } + break; + case 'donthyphenateclassname': + if (assert('donthyphenateclassname', 'string')) { + dontHyphenateClass = obj[key]; + } + break; + case 'minwordlength': + if (assert('minwordlength', 'number')) { + min = obj[key]; + } + break; + case 'hyphenchar': + if (assert('hyphenchar', 'string')) { + if (obj.hyphenchar === '­') { + obj.hyphenchar = String.fromCharCode(173); + } + hyphen = obj[key]; + } + break; + case 'urlhyphenchar': + if (obj.hasOwnProperty('urlhyphenchar')) { + if (assert('urlhyphenchar', 'string')) { + urlhyphen = obj[key]; + } + } + break; + case 'togglebox': + if (assert('togglebox', 'function')) { + toggleBox = obj[key]; + } + break; + case 'displaytogglebox': + if (assert('displaytogglebox', 'boolean')) { + displayToggleBox = obj[key]; + } + break; + case 'remoteloading': + if (assert('remoteloading', 'boolean')) { + enableRemoteLoading = obj[key]; + } + break; + case 'enablecache': + if (assert('enablecache', 'boolean')) { + enableCache = obj[key]; + } + break; + case 'enablereducedpatternset': + if (assert('enablereducedpatternset', 'boolean')) { + enableReducedPatternSet = obj[key]; + } + break; + case 'onhyphenationdonecallback': + if (assert('onhyphenationdonecallback', 'function')) { + onHyphenationDone = obj[key]; + } + break; + case 'onerrorhandler': + if (assert('onerrorhandler', 'function')) { + onError = obj[key]; + } + break; + case 'onwarninghandler': + if (assert('onwarninghandler', 'function')) { + onWarning = obj[key]; + } + break; + case 'intermediatestate': + if (assert('intermediatestate', 'string')) { + intermediateState = obj[key]; + } + break; + case 'selectorfunction': + if (assert('selectorfunction', 'function')) { + selectorFunction = obj[key]; + } + break; + case 'safecopy': + if (assert('safecopy', 'boolean')) { + safeCopy = obj[key]; + } + break; + case 'doframes': + if (assert('doframes', 'boolean')) { + doFrames = obj[key]; + } + break; + case 'storagetype': + if (assert('storagetype', 'string')) { + storageType = obj[key]; + } + break; + case 'orphancontrol': + if (assert('orphancontrol', 'number')) { + orphanControl = obj[key]; + } + break; + case 'dohyphenation': + if (assert('dohyphenation', 'boolean')) { + Hyphenator.doHyphenation = obj[key]; + } + break; + case 'persistentconfig': + if (assert('persistentconfig', 'boolean')) { + persistentConfig = obj[key]; + } + break; + case 'defaultlanguage': + if (assert('defaultlanguage', 'string')) { + defaultLanguage = obj[key]; + } + break; + case 'useCSS3hyphenation': + if (assert('useCSS3hyphenation', 'boolean')) { + css3 = obj[key]; + } + break; + case 'unhide': + if (assert('unhide', 'string')) { + unhide = obj[key]; + } + break; + case 'onbeforewordhyphenation': + if (assert('onbeforewordhyphenation', 'function')) { + onBeforeWordHyphenation = obj[key]; + } + break; + case 'onafterwordhyphenation': + if (assert('onafterwordhyphenation', 'function')) { + onAfterWordHyphenation = obj[key]; + } + break; + default: + onError(new Error('Hyphenator.config: property ' + key + ' not known.')); + } + } + } + if (storage && persistentConfig) { + storeConfiguration(); + } + }, + + /** + * @method Hyphenator.run + * @desc + * Bootstrap function that starts all hyphenation processes when called: + * Tries to create storage if required and calls {@link Hyphenator~runWhenLoaded} on 'window' handing over the callback 'process' + * @access public + * @example + * <script src = "Hyphenator.js" type = "text/javascript"></script> + * <script type = "text/javascript"> + * Hyphenator.run(); + * </script> + */ + run: function () { + /** + *@callback Hyphenator.run~process process - The function is called when the DOM has loaded (or called for each frame) + */ + var process = function () { + try { + if (contextWindow.document.getElementsByTagName('frameset').length > 0) { + return; //we are in a frameset + } + autoSetMainLanguage(undefined); + gatherDocumentInfos(); + prepare(hyphenateLanguageElements); + if (displayToggleBox) { + toggleBox(); + } + } catch (e) { + onError(e); + } + }; + + if (!storage) { + createStorage(); + } + runWhenLoaded(window, process); + }, + + /** + * @method Hyphenator.addExceptions + * @desc + * Adds the exceptions from the string to the appropriate language in the + * {@link Hyphenator~languages}-object + * @param {string} lang The language + * @param {string} words A comma separated string of hyphenated words WITH spaces. + * @access public + * @example <script src = "Hyphenator.js" type = "text/javascript"></script> + * <script type = "text/javascript"> + * Hyphenator.addExceptions('de','ziem-lich, Wach-stube'); + * Hyphenator.run(); + * </script> + */ + addExceptions: function (lang, words) { + if (lang === '') { + lang = 'global'; + } + if (exceptions.hasOwnProperty(lang)) { + exceptions[lang] += ", " + words; + } else { + exceptions[lang] = words; + } + }, + + /** + * @method Hyphenator.hyphenate + * @access public + * @desc + * Hyphenates the target. The language patterns must be loaded. + * If the target is a string, the hyphenated string is returned, + * if it's an object, the values are hyphenated directly and undefined (aka nothing) is returned + * @param {string|Object} target the target to be hyphenated + * @param {string} lang the language of the target + * @returns {string|undefined} + * @example <script src = "Hyphenator.js" type = "text/javascript"></script> + * <script src = "patterns/en.js" type = "text/javascript"></script> + * <script type = "text/javascript"> + * var t = Hyphenator.hyphenate('Hyphenation', 'en'); //Hy|phen|ation + * </script> + */ + hyphenate: function (target, lang) { + var hyphenate, n, i, lo; + lo = Hyphenator.languages[lang]; + if (Hyphenator.languages.hasOwnProperty(lang)) { + if (!lo.prepared) { + prepareLanguagesObj(lang); + } + hyphenate = function (word) { + var r; + if (urlOrMailRE.test(word)) { + r = hyphenateURL(word); + } else { + r = hyphenateWord(lo, lang, word); + } + return r; + }; + if (typeof target === 'object' && !(typeof target === 'string' || target.constructor === String)) { + i = 0; + n = target.childNodes[i]; + while (!!n) { + if (n.nodeType === 3 && n.data.length >= min) { //type 3 = #text -> hyphenate! + n.data = n.data.replace(lo.genRegExp, hyphenate); + } else if (n.nodeType === 1) { + if (n.lang !== '') { + Hyphenator.hyphenate(n, n.lang); + } else { + Hyphenator.hyphenate(n, lang); + } + } + i += 1; + n = target.childNodes[i]; + } + } else if (typeof target === 'string' || target.constructor === String) { + return target.replace(lo.genRegExp, hyphenate); + } + } else { + onError(new Error('Language "' + lang + '" is not loaded.')); + } + }, + + /** + * @method Hyphenator.getRedPatternSet + * @desc + * Returns the reduced pattern set: an object looking like: {'patk': pat} + * @param {string} lang the language patterns are stored for + * @returns {Object.<string, string>} + * @access public + */ + getRedPatternSet: function (lang) { + return Hyphenator.languages[lang].redPatSet; + }, + + /** + * @method Hyphenator.isBookmarklet + * @desc + * Returns {@link Hyphenator~isBookmarklet}. + * @returns {boolean} + * @access public + */ + isBookmarklet: function () { + return isBookmarklet; + }, + + /** + * @method Hyphenator.getConfigFromURI + * @desc + * reads and sets configurations from GET parameters in the URI + * @access public + */ + getConfigFromURI: function () { + /*jslint evil: true*/ + var loc = null, re = {}, jsArray = contextWindow.document.getElementsByTagName('script'), i, j, l, s, gp, option; + for (i = 0, l = jsArray.length; i < l; i += 1) { + if (!!jsArray[i].getAttribute('src')) { + loc = jsArray[i].getAttribute('src'); + } + if (loc && (loc.indexOf('Hyphenator.js?') !== -1)) { + s = loc.indexOf('Hyphenator.js?'); + gp = loc.substring(s + 14).split('&'); + for (j = 0; j < gp.length; j += 1) { + option = gp[j].split('='); + if (option[0] !== 'bm') { + if (option[1] === 'true') { + option[1] = true; + } else if (option[1] === 'false') { + option[1] = false; + } else if (isFinite(option[1])) { + option[1] = parseInt(option[1], 10); + } + if (option[0] === 'togglebox' || + option[0] === 'onhyphenationdonecallback' || + option[0] === 'onerrorhandler' || + option[0] === 'selectorfunction' || + option[0] === 'onbeforewordhyphenation' || + option[0] === 'onafterwordhyphenation') { + option[1] = new Function('', option[1]); + } + re[option[0]] = option[1]; + } + } + break; + } + } + return re; + }, + + /** + * @method Hyphenator.toggleHyphenation + * @desc + * Checks the current state of the ToggleBox and removes or does hyphenation. + * @access public + */ + toggleHyphenation: function () { + if (Hyphenator.doHyphenation) { + if (!!css3hyphenateClassHandle) { + css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': none;'); + } + removeHyphenationFromDocument(); + Hyphenator.doHyphenation = false; + storeConfiguration(); + toggleBox(); + } else { + if (!!css3hyphenateClassHandle) { + css3hyphenateClassHandle.setRule('.' + css3hyphenateClass, css3_h9n.property + ': auto;'); + } + hyphenateLanguageElements('*'); + Hyphenator.doHyphenation = true; + storeConfiguration(); + toggleBox(); + } + } + }; +}(window)); + +//Export properties/methods (for google closure compiler) +/**** to be moved to external file +Hyphenator['languages'] = Hyphenator.languages; +Hyphenator['config'] = Hyphenator.config; +Hyphenator['run'] = Hyphenator.run; +Hyphenator['addExceptions'] = Hyphenator.addExceptions; +Hyphenator['hyphenate'] = Hyphenator.hyphenate; +Hyphenator['getRedPatternSet'] = Hyphenator.getRedPatternSet; +Hyphenator['isBookmarklet'] = Hyphenator.isBookmarklet; +Hyphenator['getConfigFromURI'] = Hyphenator.getConfigFromURI; +Hyphenator['toggleHyphenation'] = Hyphenator.toggleHyphenation; +window['Hyphenator'] = Hyphenator; +*/ + +/* + * call Hyphenator if it is a Bookmarklet + */ +if (Hyphenator.isBookmarklet()) { + Hyphenator.config({displaytogglebox: true, intermediatestate: 'visible', storagetype: 'local', doframes: true, useCSS3hyphenation: true}); + Hyphenator.config(Hyphenator.getConfigFromURI()); + Hyphenator.run(); +}