// stupid little workaround so modes can be set without magic numbers in tag definitions // now made moot by being unable to use variables as a key var MARKUP_MODE_COMMENT = 1, MARKUP_MODE_ARTICLE = 2, MARKUP_MODE_QUICKFACTS = 3, MARKUP_MODE_SIGNATURE = 4, MARKUP_MODE_REPLY = 5, MARKUP_CLASS_ADMIN = 40, MARKUP_CLASS_STAFF = 30, MARKUP_CLASS_PREMIUM = 20, MARKUP_CLASS_USER = 10, MARKUP_CLASS_PENDING = 1; var MARKUP_SOURCE_LIVE = 1, MARKUP_SOURCE_PTR = 2, MARKUP_SOURCE_BETA = 3; var MarkupModeMap = {}; MarkupModeMap[MARKUP_MODE_COMMENT] = 'comment'; MarkupModeMap[MARKUP_MODE_REPLY] = 'reply'; MarkupModeMap[MARKUP_MODE_ARTICLE] = 'article'; MarkupModeMap[MARKUP_MODE_QUICKFACTS] = 'quickfacts'; MarkupModeMap[MARKUP_MODE_SIGNATURE] = 'signature'; var MarkupSourceMap = {}; MarkupSourceMap[MARKUP_SOURCE_LIVE] = 'live'; MarkupSourceMap[MARKUP_SOURCE_PTR] = 'ptr'; MarkupSourceMap[MARKUP_SOURCE_BETA] = 'beta'; var Markup = { MODE_COMMENT: MARKUP_MODE_COMMENT, MODE_REPLY: MARKUP_MODE_REPLY, MODE_ARTICLE: MARKUP_MODE_ARTICLE, MODE_QUICKFACTS: MARKUP_MODE_QUICKFACTS, MODE_SIGNATURE: MARKUP_MODE_SIGNATURE, SOURCE_LIVE: MARKUP_SOURCE_LIVE, SOURCE_PTR: MARKUP_SOURCE_PTR, SOURCE_BETA: MARKUP_SOURCE_BETA, CLASS_ADMIN: MARKUP_CLASS_ADMIN, CLASS_STAFF: MARKUP_CLASS_STAFF, CLASS_PREMIUM: MARKUP_CLASS_PREMIUM, CLASS_USER: MARKUP_CLASS_USER, CLASS_PENDING: MARKUP_CLASS_PENDING, /* aowow custom: first element */ whitelistedWebsites: [new RegExp('(.*\\.)?' + location.hostname, 'i'), /(.*\.)?wowhead.com/i, /(.*\.)?thottbot.com/i, /(.*\.)?torhead.com/i, /(.*\.)?mmoui.com/i, /(.*\.)?tankspot.com/i, /(.*\.)?guildfans.com/i, /(.*\.)?allakhazam.com/i, /(.*\.)?zam.com/i, /(.*\.)?blizzard.com/i, /(.*\.)?worldofwarcraft.com/i, /(.*\.)?wow-europe.com/i, /(.*\.)?battle.net/i, /(.*\.)?sc2ranks.com/i, /(.*\.)?torchlightarmory.com/i, /(.*\.)?vindictusdb.com/i, /(.*\.)?wowinterface.com/i, /(.*\.)?vginterface.com/i, /(.*\.)?lotrointerface.com/i, /(.*\.)?eq2interface.com/i, /(.*\.)?eqinterface.com/i, /(.*\.)?mmo-champion.com/i, /(.*\.)?joystiq.com/i, /(.*\.)?wow-heroes.com/i, /(.*\.)?be-imba.hu/i, /(.*\.)?wowpedia.org/i, /(.*\.)?curse.com/i, /(.*\.)?elitistjerks.com/i, /(.*\.)?wowwiki.com/i, /(.*\.)?worldoflogs.com/i, /(.*\.)?wowinsider.com/i, /(.*\.)?guildwork.com/i], rolesToClass: function(roles) { if(roles & (U_GROUP_ADMIN|U_GROUP_VIP|U_GROUP_DEV)) return Markup.CLASS_ADMIN; else if(roles & U_GROUP_STAFF) return Markup.CLASS_STAFF; else if(roles & U_GROUP_PREMIUM) return Markup.CLASS_PREMIUM; else if(roles & U_GROUP_PENDING) return Markup.CLASS_PENDING; else return Markup.CLASS_USER; }, defaultSource: false, nameCol: 'name_enus', domainToLocale: { 'www': 'enus', 'ptr': 'ptr', 'beta': 'beta', 'mop': 'beta', 'fr': 'frfr', 'de': 'dede', 'es': 'eses', 'ru': 'ruru', 'pt': 'ptbr' }, maps: [], firstTags: {}, postTags: [], collectTags: {}, excludeTags: {}, tooltipTags: {}, tooltipBare: {}, attributes: { id: { req: false, valid: /^[a-z0-9_-]+$/i }, title: { req: false, valid: /[\S ]+/ }, 'class': { req: false, valid: /\S+/ } }, youtube: { players: [], APIIsReady: false, readyTimeout: undefined, APIReady: function () { var UNK_INITED = false; Markup.youtube.readyTimeout = undefined; Markup.youtube.APIIsReady = true; for (var i in Markup.youtube.players) { if (!Markup.youtube.players.hasOwnProperty(i)) continue; if (Markup.youtube.players[i].loaded) continue; if ($WH.ge(Markup.youtube.players[i].containerId)) { Markup.youtube.players[i].loaded = true; Markup.youtube.players[i].player = new YT.Player(Markup.youtube.players[i].containerId, Markup.youtube.players[i].yt); } else UNK_INITED = true; } if (UNK_INITED) Markup.youtube.readyTimeout = window.setTimeout(Markup.youtube.APIReady, 500); } }, IsLinkAllowed: function(link) { var matches = link.match('[a-z]+:\/\/([a-z0-9\.\-]+)'); if(!matches) return true; var domain = matches[1]; var allowed = false; for(var i in Markup.whitelistedWebsites) { var r = Markup.whitelistedWebsites[i]; if(domain.search(r) == 0) allowed = true; } return allowed; }, tags: { '': { empty: true, noHelp: true, allowInReplies: true, toHtml: function(attr, extra) { extra = extra || $.noop; if(attr._text == ' ' && !extra.noNbsp) attr._text = ' '; attr._text = attr._text.replace(/\\\[/g, '['); if(extra && extra.noLink) return attr._text; else if(extra && extra.needsRaw) return attr._rawText; else { var link = []; var text = Markup._preText(attr._rawText.replace(/(https?:\/\/|www\.)([\/_a-z0-9\%\?#@\-\+~&=;:']|\.[a-z0-9\-])+/gi, function(match) { matchUrl = Markup._preText(match.replace(/^www/, 'http://www')); match = Markup._preText(match); var i = link.length; link.push([matchUrl, match]); return '$L' + i; })); text = text.replace(/\$L([\d+]) /gi, '$L$1 '); for(var i in link) { text = text.replace('$L' + i, function(match) { if(Markup.allow < Markup.CLASS_USER && !Markup.IsLinkAllowed(link[i][0])) return $WH.sprintf('[$1]', LANG.linkremoved); var url = ''; return url; }); } return text; } }, toText: function(attr) { return attr._text; } }, achievement: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, diff: { req: false, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, tempname: { req: false } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; var rel = []; var tempname = null; if(attr.diff) rel.push('diff=' + attr.diff); if(attr.tempname) tempname = attr.tempname; if(g_achievements[id] && g_achievements[id][nameCol]) { var ach = g_achievements[id]; return ' ' + Markup._safeHtml(ach[nameCol]) + ''; } return '' + (tempname ? tempname : ('(' + LANG.types[10][0] + ' #' + id + ')')) + ''; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_achievements[id] && g_achievements[id][nameCol]) return Markup._safeHtml(g_achievements[id][nameCol]); return LANG.types[10][0] + ' #' + id; } }, achievementpoints: { empty: true, attr: { unnamed: {req: true, valid: /^[0-9]+$/ } }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { var str = '' + attr.unnamed + ''; return str; } }, anchor: { empty: true, ltrim: true, rtrim: true, attr: { unnamed: { req: false, valid: /\S+/ } }, validate: function(attr) { if(!attr.unnamed && !attr.id) return false; return true; }, toHtml: function(attr) { if(!attr.unnamed && attr.id) { attr.unnamed = attr.id; attr.id = null; } return ''; } }, acronym: { empty: false, attr: { unnamed: { req: false } }, toHtml: function(attr) { return ['', '']; } }, b: { empty: false, allowInReplies: true, toHtml: function(attr) { return ['', '']; }, fromHtml: function(str) { return str.replace(/<(b|big|strong)\b[\s\S]*?>([\s\S]*?)<\/\1>/gi, '[b]$2[/b]'); } }, blip: { empty: true, attr: { unnamed: { req: true, valid: /\S+/ } }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { var url = 'http://blip.tv/play/' + attr.unnamed; var width = 600; var height = 368; var html = ''; // object tag causing issues in chrome? /*html += ''; html += ''; html += ''; html += '';*/ html += ''; //html += ''; return html; } }, br: { empty: true, toHtml: function(attr) { return '
'; }, fromHtml: function(str) { return str.replace(//gi, "\n"); } }, 'class': { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/i }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; if(attr.unnamed >= 1 && attr.unnamed <= 11) return true; return false; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_classes[id] && g_classes[id][nameCol]) { var cls = g_classes[id]; return ' ' + Markup._safeHtml(cls[nameCol]) + ''; } return '(' + LANG.types[13][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_classes[id] && g_classes[id][nameCol]) return Markup._safeHtml(g_classes[id][nameCol]); return LANG.types[13][0] + ' #' + id; } }, code: { block: true, empty: false, rtrim: true, itrim: true, helpText: true, allowedChildren: { '': 1 }, toHtml: function(attr) { var open = '
';
                return [open, '
']; } }, color: { empty: false, attr: { unnamed: { req: true, valid: /^.*/i } }, allowedClass: MARKUP_CLASS_STAFF, /* Syntax: name: class */ extraColors: {deathknight: 'c6', dk: 'c6', druid: 'c11', hunter: 'c3', mage: 'c8', paladin: 'c2', priest: 'c5', rogue: 'c4', shaman: 'c7', warlock: 'c9', warrior: 'c1', poor: 'q0', common: 'q1', uncommon: 'q2', rare: 'q3', epic: 'q4', legendary: 'q5', artifact: 'q6', heirloom: 'q7'}, toHtml: function(attr) { var valid = /^(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow|c\d+|r\d+|q\d*?|#[a-f0-9]{6})$/i; var str = '']; } }, currency: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, amount: { req: false, valid: /^[0-9\:]+$/ }, icon: { req: false, valid: /^false$/i }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, allowedClass: MARKUP_CLASS_STAFF, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_gatheredcurrencies[id] && g_gatheredcurrencies[id][nameCol]) { var curr = g_gatheredcurrencies[id]; if(attr.amount) return ' ' + attr.amount.split(':').join(' - ') + ''; else return ' ' + Markup._safeHtml(curr[nameCol]) + ''; } return '(' + LANG.types[17][0] + ' #' + id + ')' + (attr.amount > 0 ? ' x' + attr.amount : ''); }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_gatheredcurrencies[id] && g_gatheredcurrencies[id][nameCol]) return Markup._safeHtml(g_gatheredcurrencies[id][nameCol]); return LANG.types[17][0] + ' #' + id; } }, db: { empty: true, attr: { unnamed: { req: true, valid: /^(live|ptr|beta|mop)$/ } }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { if(attr.unnamed == 'live') Markup.defaultSource = Markup.SOURCE_LIVE; else if(attr.unnamed == 'ptr') Markup.defaultSource = Markup.SOURCE_PTR; else if(attr.unnamed == 'beta' || attr.unnamed == 'mop') Markup.defaultSource = Markup.SOURCE_BETA; return ''; }, toText: function(attr) { if(attr.unnamed == 'live') Markup.defaultSource = Markup.SOURCE_LIVE; else if(attr.unnamed == 'ptr') Markup.defaultSource = Markup.SOURCE_PTR; else if(attr.unnamed == 'beta' || attr.unnamed == 'mop') Markup.defaultSource = Markup.SOURCE_BETA; return ''; } }, del: { empty: false, attr: { copy: { req: false, valid: /^true$/ } }, toHtml: function(attr) { var str = '']; } }, div: { empty: false, block: true, ltrim: true, rtrim: true, itrim: true, attr: { clear: { req: false, valid: /^(left|right|both)$/i }, unnamed: { req: false, valid: /^hidden$/i }, 'float': { req: false, valid: /^(left|right)$/i }, align: { req: false, valid: /^(left|right|center)$/i }, margin: { req: false, valid: /^\d+(px|em|\%)$/ }, style: { req: false, valid: /^[^"<>]+$/ }, width: { req: false, valid: /^[0-9]+(px|em|\%)$/ } }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { var str = '= Markup.CLASS_STAFF) styles.push(attr.style) if(attr.first) classes.push('first'); if(attr.last) classes.push('last'); if(styles.length > 0) str += ' style="' + styles.join(';') + '"'; if(classes.length > 0) str += ' class="' + classes.join(' ') + '"'; str += '>'; return [str, '']; }, fromHtml: function(str, depth) { depth = depth || 0; var m; if(m = Markup.matchOuterTags(str, '', '', 'g')) { for(var i = 0; i < m.length; ++i) { var align = m[i][1].match(/float:\s*(left|right)"/i), width = m[i][1].match(/width[:="]+\s*([0-9]+)/i); str = str.replace(m[i][1] + m[i][0] + m[i][2], "\n" + Array(depth + 1).join("\t") + '[div' + (align ? ' float=' + align[1] : '') + (width ? ' width=' + width[1] : '') + ']' + Markup.tags.div.fromHtml(m[i][0], depth + 1) + '[/div]'); } } return str; } }, emote: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_emotes[id] && g_emotes[id][nameCol]) { return '' + Markup._safeHtml(g_emotes[id][nameCol]) + ''; } return '(' + LANG.types[501][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_emotes[id] && g_emotes[id][nameCol]) return Markup._safeHtml(g_emotes[id][nameCol]); return LANG.types[501][0] + ' #' + id; } }, enchantment: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_enchantments[id] && g_enchantments[id][nameCol]) { return '' + Markup._safeHtml(g_enchantments[id][nameCol]) + ''; } return '(' + LANG.types[502][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_enchantments[id] && g_enchantments[id][nameCol]) return Markup._safeHtml(g_enchantments[id][nameCol]); return LANG.types[502][0] + ' #' + id; } }, event: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^-?[0-9]+$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, allowedClass: MARKUP_CLASS_STAFF, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_holidays[id] && g_holidays[id][nameCol]) { var evt = g_holidays[id]; return '' + Markup._safeHtml(evt[nameCol]) + ''; } return '(' + LANG.types[12][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_holidays[id] && g_holidays[id][nameCol]) return Markup._safeHtml(g_holidays[id][nameCol]); return LANG.types[12][0] + ' #' + id; } }, faction: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_factions[id] && g_factions[id][nameCol]) { var fac = g_factions[id]; return '' + Markup._safeHtml(fac[nameCol]) + ''; } return '(' + LANG.types[8][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_factions[id] && g_factions[id][nameCol]) return Markup._safeHtml(g_factions[id][nameCol]); return LANG.types[8][0] + ' #' + id; } }, feedback: { empty: true, allowedClass: MARKUP_CLASS_STAFF, attr: { mailto: { req: false, valid: /^true$/i } }, toHtml: function(attr) { return 'feedback@wowhead.com'; } }, forumrules: { empty: true, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { return 'forum rules'; } }, hr: { empty: true, trim: true, allowedModes: { article: 1, quickfacts: 1, comment: 1 }, toHtml: function(attr) { return '
'; }, fromHtml: function(str) { return str.replace(//gi, '[hr]'); } }, h2: { block: true, empty: false, ltrim: true, rtrim: true, itrim: true, allowedClass: MARKUP_CLASS_STAFF, attr: { unnamed: { req: false, valid: /^first$/i }, clear: { req: false, valid: /^(true|both|left|right)$/i }, style: { req: false, valid: /^[^"<>]+$/ }, toc: { req: false, valid: /^false$/i } }, toHtml: function(attr) { if(!attr.id) attr.id = g_urlize(attr._textContents); str = ' 0) str += ' class="' + classes.join(' ') + '"'; var styles = []; if(attr.clear) { if(attr.clear == 'true' || attr.clear == 'both') styles.push('clear: both'); else styles.push('clear: ' + attr.clear); } if(attr.style && Markup.allow >= Markup.CLASS_STAFF) styles.push(attr.style); if(styles.length) str += ' styles="' + styles.join(';') + '"'; return [str + '>', '']; }, fromHtml: function(str) { return str.replace(/([\s\S]*?)<\/h2>/gi, "\n[h2]$1[/h2]"); } }, h3: { block: true, empty: false, ltrim: true, rtrim: true, itrim: true, attr: { unnamed: { req: false, valid: /^first$/i }, style: { req: false, valid: /^[^"<>]+$/ }, toc: { req: false, valid: /^false$/i } }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { if(!attr.id) attr.id = g_urlize(attr._textContents); var str = ' 0) str += ' class="' + classes.join(' ') + '"'; var styles = []; if(attr.style && Markup.allow >= Markup.CLASS_STAFF) styles.push(attr.style); if(styles.length) str += ' styles="' + styles.join(';') + '"'; return [str + '>', '']; }, fromHtml: function(str) { return str.replace(/([\s\S]*?)<\/h3>/gi, "\n[h3]$1[/h3]"); } }, html: { empty: false, allowedClass: MARKUP_CLASS_ADMIN, allowedChildren: { '': 1 }, rawText: true, taglessSkip: true, toHtml: function(attr) { return [attr._contents]; } }, i: { empty: false, allowInReplies: true, toHtml: function(attr) { return ['', '']; }, fromHtml: function(str) { return str.replace(/<(i|em)\b[\s\S]*?>([\s\S]*?)<\/\1>/gi, '[i]$1[/i]'); } }, icon: { empty: false, itrim: true, attr: { align: { req: false, valid: /^right$/i }, 'float': { req: false, valid: /^(left|right)$/i }, name: { req: false, valid: /\S+/ }, size: { req: false, valid: /^(tiny|small|medium|large)$/ }, unnamed: { req: false, valid: /^class$/i }, url: { req: false, valid: /\S+/ }, preset : { req: false, valid: /\S+/ } }, allowedClass: MARKUP_CLASS_STAFF, presets: { boss: g_staticUrl + '/images/icons/boss.gif', heroic: g_staticUrl + '/images/icons/heroic.gif' }, validate: function(attr) { if(!attr.name && !attr.url && !attr.preset) return false; if(attr.preset && !Markup.tags.icon.presets[attr.preset]) return false; return true; }, toHtml: function(attr) { var size = (attr.size ? attr.size : "tiny"); if(!attr.name) attr.name = ''; if(size == "tiny") { var str = ''; } else str += attr.name + '">'; return [str, '
']; } else { var str = '' : '">' ); var sizes = {'small': 0, 'medium': 1, 'large': 2}; var url = null; if(attr.url && Markup._isUrlSafe(attr.url)) url = attr.url; else if(attr._textContents && Markup._isUrlSafe(attr._textContents)) url = attr._textContents; icon = Icon.create(attr.name.toLowerCase(), sizes[size], null, url); str += icon.innerHTML + ''; return [str]; } } }, iconlist: { empty: false, block: true, ltrim: true, rtrim: true, attr: { domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, taglessSkip: true, allowedClass: MARKUP_CLASS_STAFF, allowedChildren: { b: 1, achievement: 1, currency: 1, faction: 1, holiday: 1, item: 1, itemset: 1, npc: 1, object: 1, pet: 1, quest: 1, spell: 1, title: 1, zone: 1 }, toHtml: function(attr) { var domain = Markup._getDatabaseDomainInfo(attr)[2]; var str = '', m; for(var i = 0; i < attr._nodes.length; ++i) { var node = $WH.dO(attr._nodes[i]); node.attr.domain = domain; var html = Markup.tags[node.name].toHtml(node.attr), type = node.name, href = '', icon = ''; if(typeof html != 'string') // Bold open/close tags html = html[0] + node.attr._contents + html[1]; else if(typeof html == 'string' && (m = html.match(/href="(.+?)".+?url\(\/images\/wow\/icons\/tiny\/(.+?)\.gif\)/))) { node.attr.icon = 'false'; html = Markup.tags[node.name].toHtml(node.attr); href = m[1]; icon = m[2]; } if(html) str += '' + (icon ? Markup.toHtml('[icon name=' + icon + ' size=small url=' + href + ']', { skipReset: true }) : '
  •  
') + '' + html + ''; } if(str) str = '
' + str + '
'; return [str]; } }, img: { empty: true, attr: { src: { req: false, valid: /\S+/ }, icon: { req: false, valid: /\S+/ }, id: { req: false, valid: /^[0-9]+$/ }, blog: { req: false, valid: /^[0-9]+$/ }, size: { req: false, valid: /^(thumb|resized|normal|large|medium|small|tiny)$/i }, width: { req: false, valid: /^[0-9]+$/ }, height: { req: false, valid: /^[0-9]+$/ }, 'float': { req: false, valid: /^(left|right|center)$/i }, border: { req: false, valid: /^[0-9]+$/ }, shadow: { req: false, valid: /^(true|false)$/ }, margin: { req: false, valid: /^[0-9]+$/ } }, blogSize: /^(thumb|normal)$/i, idSize: /^(thumb|resized|normal)$/i, iconSize: /^(large|medium|small|tiny)$/i, allowedClass: MARKUP_CLASS_STAFF, validate: function(attr) { if(attr.src) return true; else if(attr.id) return (attr.size ? Markup.tags.img.idSize.test(attr.size) : true); else if(attr.icon) return (attr.size ? Markup.tags.img.iconSize.test(attr.size) : true); else if(attr.blog) return (attr.size ? Markup.tags.img.blogSize.test(attr.size) : true); return false; }, toHtml: function(attr) { var str = '' + str; post = ''; var screenshot = { url: url, caption: img.alt, width: img.width, height: img.height, noMarkup: true }; g_screenshots[Markup.uid].push(screenshot); } else str += ' src="' + g_staticUrl + '/uploads/blog/images/' + attr.blog + (img.type == 3 ? '.png' : '.jpg') + '" alt="' + Markup._safeHtml(img.alt) + '" width="' + img.width + '" height="' + img.height + '"'; } else return ('Image #' + attr.blog); } if(attr.width) str += ' width="' + attr.width + '"'; if(attr.height) str += ' height="' + attr.height + '"'; if(attr['float']) { if(attr['float'] == 'center') { str = '
' + str + ' style="margin: 10px auto"'; post = '
'; } else { styles.push('float: ' + attr['float']); if(!attr.margin) attr.margin = 10; if(attr['float'] == 'left') styles.push('margin: 0 ' + attr.margin + 'px ' + attr.margin + 'px 0'); else styles.push('margin: 0 0 ' + attr.margin + 'px ' + attr.margin + 'px'); } } if(attr.border) { if (attr.border == 0) classes.push('no-border'); else { classes.push('border'); styles.push('border-width:' + attr.border + 'px'); } } else { classes.push('content-image'); if (attr.shadow == 'true') classes.push('content-image-shadowed'); } if(attr.title) str += ' alt="' + attr.title + '"'; else str += ' alt=""'; if (classes.length) str += ' class="' + classes.join(' ') + '"'; if (styles.length) str += ' style="' + styles.join(';') + '"'; str += ' />' + post; return str; }, fromHtml: function(str) { var m; if(m = str.match(//gi)) { for(var i = 0; i < m.length; ++i) { var source = m[i].match(/src="([\s\S]+?)"/i), width = m[i].match(/width[:="]+\s*([0-9]+)/i), height = m[i].match(/height[:="]+\s*([0-9]+)/i), border = m[i].match(/border[:="]+\s*([0-9]+)/i); str = str.replace(m[i], '[img src=' + source[1] + (width ? ' width=' + width[1] : '') + (height ? ' height=' + height[1] : '') + ' border=' + (border ? border[1] : 0) + ']'); } } return str; } }, ins: { empty: false, toHtml: function(attr) { return ['', '']; } }, item: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/i }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, tempname: { req: false } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; var tempname = null; if(attr.tempname) tempname = attr.tempname; if(g_items[id] && g_items[id][nameCol]) { var item = g_items[id]; var str = ' '; str += Markup._safeHtml(item[nameCol]) + ''; return str; } return '' + (tempname ? tempname : ('(' + LANG.types[3][0] + ' #' + id + ')')) + ''; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_items[id] && g_items[id][nameCol]) return Markup._safeHtml(g_items[id][nameCol]); return LANG.types[3][0] + ' #' + id; } }, itemset: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^-?[0-9]+$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_itemsets[id] && g_itemsets[id][nameCol]) { var set = g_itemsets[id]; return '' + Markup._safeHtml(set[nameCol]) + ''; } return '(' + LANG.types[4][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_itemsets[id] && g_itemsets[id][nameCol]) return Markup._safeHtml(g_itemsets[id][nameCol]); return LANG.types[4][0] + ' #' + id; } }, li: { empty: false, itrim: true, allowedParents: { ul: 1, ol: 1 }, attr: { "class": { req: false, valid: /^[a-z0-9 _-]+$/i }, style: { req: false, valid: /^[^<>]+$/ } }, helpText: function() { var str = ''; str += '[ul]'; for(var i = 0; i < 3; ++i) str += '\n[li]' + LANG.markup_li + '[/li]'; str += '\n[/ul]\n\n'; str += '[ol]'; for(var i = 0; i < 3; ++i) str += '\n[li]' + LANG.markup_li + '[/li]'; str += '\n[/ol]\n'; return str.toLowerCase(); }, toHtml: function(attr) { return ['
', '
']; }, fromHtml: function(str, depth) { depth = depth || 0; var m; if(m = Markup.matchOuterTags(str, '', '', 'g')) { for(var i = 0; i < m.length; ++i) str = str.replace(m[i][1] + m[i][0] + m[i][2], "\n\t" + Array(depth + 1).join("\t") + '[li]' + Markup.tags.li.fromHtml(m[i][0], depth + 1) + '[/li]'); } return str; } }, lightbox: { empty: false, allowedClass: MARKUP_CLASS_STAFF, attr: { unnamed: { req: true, valid: /^(map|model|screenshot)$/ }, zone: { req: false, valid: /^-?[0-9]+[a-z]?$/i }, floor: { req: false, valid: /^[0-9]+$/ }, pins: { req: false, valid: /^[0-9]+$/ } }, validate: function(attr) { switch(attr.unnamed) { case 'map': if(attr.zone) return true; break; case 'model': break; case 'screenshot': break; } return false; }, toHtml: function(attr) { var url = ''; var onclick = ''; switch(attr.unnamed) { case 'map': url = '?maps=' + attr.zone; if(attr.floor) url += '.' + attr.floor; if(attr.pins) url += ':' + attr.pins; var link = url.substr(6); onclick = 'if(!g_isLeftClick(event)) return; MapViewer.show({ link: \'' + link + '\' }); return false;'; break; } if(url && onclick) return ['', '']; return ''; } }, map: { empty: false, attr: { zone: { req: true, valid: /^-?[0-9a-z\-_]+$/i }, source: { req: false, valid: /\S+/ } }, allowedClass: MARKUP_CLASS_STAFF, allowedChildren: { pin: 1 }, toHtml: function(attr) { var coords = attr._contents; attr.id = 'dsgdfngjkfdg' + (Markup.maps.length); var str = '
'; Markup.maps.push([attr.id, attr.zone, coords]); return [ str ]; } }, n5: { empty: true, attr: { unnamed: { req: true, valid: /^[0-9\.]+$/ } }, toHtml: function(attr) { return GetN5(attr.unnamed); } }, pin: { empty: false, attr: { url: { req: false, valid: /\S+/ }, type: { req: false, valid: /^[0-9]+$/ }, x: { req: true, valid: /^[0-9]{1,2}(\.[0-9])?$/ }, y: { req: true, valid: /^[0-9]{1,2}(\.[0-9])?$/ }, path: { req: false, valid: /^([0-9]{1,2}(\.[0-9])?[,:]?)+$/ } }, taglessSkip: true, allowedClass: MARKUP_CLASS_STAFF, allowedParents: { map: 1 }, toHtml: function(attr) { if(attr.url && !Markup._isUrlSafe(attr.url)) attr.url = ''; var label = attr._contents; if(attr.url && attr.url.indexOf('npc=') != -1) label = '' + label + '
Click to view this NPC'; var lines = null; if(attr.path) { var coords = attr.path.split(':'), lines = []; for(var i = 0, len = coords.length; i < len; ++i) { var parts = coords[i].split(','); if(parts.length == 2) lines.push([parseFloat(parts[0] || 0), parseFloat(parts[1] || 0)]); } } return [ [parseFloat(attr.x || 0), parseFloat(attr.y || 0), { label: label, url: attr.url, type: attr.type, lines: lines }] ]; /*var str = '[' + parseFloat(attr.x || 0) + ',' + parseFloat(attr.y || 0) + ',{label: \'' + Markup._safeJsString(label) + '\''; if(attr.url) str += ', url: \'' + Markup._safeJsString(Markup._fixUrl(attr.url)) + '\''; if(attr.type) str += ', type: \'' + Markup._safeJsString(attr.type) + '\''; str += '}]'; return [ [str] ];*/ } }, markupdoc: { empty: true, attr: { tag: { req: false, valid: /[a-z0-9]+/i }, help: { req: false, valid: /^(admin|staff|premium|user|pending)$/ } }, allowedClass: MARKUP_CLASS_STAFF, validate: function(attr) { if(attr.tag && !Markup.tags[attr.tag]) return false; return true; }, toHtml: function(attr) { var str = '', helpClass = (attr.help ? Markup['CLASS_' + attr.help.toUpperCase()] : false); if(helpClass) str += LANG.markup_helpdoc + '
'; if(attr.tag) str = Markup._generateTagDocs(attr.tag, helpClass); else { for(var tag in Markup.tags) { if(!helpClass && str != '') str += '
'; str += Markup._generateTagDocs(tag, helpClass); } } return str + (helpClass ? '
' + LANG.markup_help1 + '' + LANG.markup_help2 + '
' : ''); } }, menu: { empty: true, trim: true, ltrim: true, rtrim: true, attr: { tab: { req: true, valid: /^[0-9]+$/ }, path: { req: true, valid: /\S+/ } }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { var path = attr.path.split(','); PageTemplate.set({activeTab: attr.tab, breadcrumb: path}); } }, minibox: { empty: false, rtrim: true, itrim: true, attr: { 'float': { req: false, valid: /^(left|right)$/i } }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { var str = ''; return [str, '']; } }, model: { empty: false, attr: { item: { req: false, valid: /^[0-9]+$/ }, object: { req: false, valid: /^[0-9]+$/ }, npc: { req: false, valid: /^[0-9]+$/ }, itemset: { req: false, valid: /^[0-9,]+$/ }, slot: { req: false, valid: /^[0-9]+$/ }, humanoid: { req: false, valid: /^1$/ }, 'float': { req: false, valid: /^(left|right)$/i }, border: { req: false, valid: /^[0-9]+$/ }, shadow: { req: false, valid: /^(true|false)$/ }, img: { req: false, valid: /\S+/ }, link: { req: false, valid: /\S+/ }, label: { req: false, valid: /[\S ]+/ } }, allowedClass: MARKUP_CLASS_STAFF, skipSlots: { 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1, 16: 1, 19: 1, 20: 1 }, toHtml: function(attr) { var str = ''; var classes = []; var styles = []; if(attr['float']) classes.push('markup-float-' + attr['float']); if(attr.border) { if(attr.border == 0) classes.push('no-border'); else { classes.push('border'); styles.push('border-width:' + attr.border + 'px'); } } else { classes.push('content-image'); if(attr.shadow == 'true') classes.push('content-image-shadowed'); } if(attr.npc) { str = '' + Markup._safeHtml(attr._contents) + '' + Markup._safeHtml(attr._contents) + '' + Markup._safeHtml(attr._contents) + ''; } else return ['[model]', '[/model]']; return [str, '']; } }, money: { empty: true, attr: { unnamed: { req: false, valid: /^[0-9]+$/ }, side: { req: false, valid: /^(alliance|horde|both)$/i }, items: { req: false, valid: /^[0-9,]+$/ }, currency: { req: false, valid: /^[0-9,]+$/ }, achievement: { req: false, valid: /\S+/ }, arena: { req: false, valid: /^[0-9]+$/ }, honor: { req: false, valid: /^[0-9]+$/ }, }, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { var items = [], currency = []; if(attr.items) { var split = attr.items.split(','); if(split.length >= 2) for(var i = 0; i < split.length-1; i += 2) items.push([split[i], split[i+1]]); } if(attr.currency) { var split = attr.currency.split(','); if(split.length >= 2) for(var i = 0; i < split.length-1; i += 2) currency.push([split[i], split[i+1]]); } // Backwards compatability if(attr.honor) currency.push([104, attr.honor]); if(attr.arena) currency.push([103, attr.arena]); return g_getMoneyHtml(attr.unnamed, attr.side, items, currency, attr.achievement); } }, npc: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_npcs[id] && g_npcs[id][nameCol]) { var npc = g_npcs[id]; return '' + Markup._safeHtml(npc[nameCol]) + ''; } return '(' + LANG.types[1][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_npcs[id] && g_npcs[id][nameCol]) return Markup._safeHtml(g_npcs[id][nameCol]); return LANG.types[1][0] + ' #' + id; } }, object: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_objects[id] && g_objects[id][nameCol]) { var obj = g_objects[id]; return '' + Markup._safeHtml(obj[nameCol]) + ''; } return '(' + LANG.types[2][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_objects[id] && g_objects[id][nameCol]) return Markup._safeHtml(g_objects[id][nameCol]); return LANG.types[2][0] + ' #' + id; } }, ol: { block: true, empty: false, ltrim: true, rtrim: true, itrim: true, allowedChildren: { li: 1 }, toHtml: function(attr) { var open = ' 0) open += ' class="' + classes.join(' ') + '"'; open += Markup._addGlobalAttributes(attr) + '>'; return [open, '']; }, fromHtml: function(str, depth) { depth = depth || 0; var m; if(m = Markup.matchOuterTags(str, '', '', 'g')) { for(var i = 0; i < m.length; ++i) { str = str.replace(m[i][1] + m[i][0] + m[i][2], "\n" + Array(depth + 1).join("\t") + '[ol]' + Markup.tags.ol.fromHtml(m[i][0], depth + 1) + "\n" + Array(depth + 1).join("\t") + '[/ol]'); } } return str; } }, p: { empty: false, ltrim: true, rtrim: true, itrim: true, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { return ['

','

']; }, fromHtml: function(str) { var m; if(m = str.match(/[\s\S]*?<\/p>/gi)) { for(var i = 0; i < m.length; ++i) { var align = m[i].match(/^([\s\S]*?)<\/p>/i); str = str.replace(m[i], '[pad][div' + (align ? ' align=' + align[1] : '') + ']' + (inside ? inside[1] : '') + '[/div][pad]'); } } return str; } }, pad: { empty: true, block: true, trim: true, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { var str = '
'; return str; } }, pet: { empty: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_pet_families && g_pet_families[id] && g_pets && g_pets[id]) { var str = ''; str += '' + Markup._safeHtml(g_pet_families[id]) + ''; return str; } return '(' + LANG.types[9][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; if(g_pet_families && g_pet_families[id]) return Markup._safeHtml(g_pet_families[id]); return LANG.types[9][0] + ' #' + id; } }, pre: { empty: false, block: true, rtrim: true, toHtml: function(attr) { var open = '
';
                return [open, '
']; }, fromHtml: function(str) { return str.replace(/([\s\S]*?)<\/pre>/gi, '[pre]$1[/pre]'); } }, quest: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_quests[id] && g_quests[id][nameCol]) { var quest = g_quests[id]; return ' ' + Markup._safeHtml(quest[nameCol]) + ''; } return '(' + LANG.types[5][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_quests[id] && g_quests[id][nameCol]) return Markup._safeHtml(g_quests[id][nameCol]); return LANG.types[5][0] + ' #' + id; } }, quote: { block: true, empty: false, rtrim: true, ltrim: true, itrim: true, attr: { unnamed: { req: false, valid: /[\S ]+/ }, url: { req: false, valid: /\S+/ }, blizzard: { req: false, valid: /^true$/ }, pname: { req: false }, wowhead: { req: false, valid: /^true$/ }, display: { req: false, valid: /^block$/ }, align: { req: false, valid: /^(left|right|center)$/i }, "float": { req: false, valid: /^(left|right|none)$/i }, clear: { req: false, valid: /^(left|right|both)$/i }, collapse: { req: false, valid: /^true$/ } }, allowedModes: { article: 1, quickfacts: 1, comment: 1 }, validate: function(attr) { if(attr.blizzard || attr.wowhead || attr.collapse || attr.url) { if(Markup.allow < Markup.CLASS_STAFF) return false; } return true; }, toHtml: function(attr) { var str = '= 0) pname = 'Blue Tracker'; // override with attr.pname if it exists if(typeof(attr.pname) != 'undefined') pname = attr.pname; var username = attr.unnamed.trim(); if(username.length <= 0) return ['','']; str = str.replace('class="quote', 'class="quote-blizz'); str += (attr.collapse ? ' collapse' : '') + '">
' var matches = url.match(/https?:\/\/(us|eu)\.battle\.net\/wow\/en\/blog\/([0-9]+)/i) || url.match(/https?:\/\/(us|eu)\.battle\.net\/wow\/en\/forum\/topic\/([0-9]+)/i); if(matches) { str += 'Originally posted by Blizzard (Official Post' var topicId = matches[2]; str += ' | Blue Tracker)' + '

' + username + '

'; } else str += ( attr.url && Markup._isUrlSafe(attr.url) ? 'Originally posted by Blizzard ' + '(' + pname + ')' + '

' :'

' + username + '

' ); return [str, '
']; } return ['','']; } else if(attr.wowhead /*Markup.inBlog*/) { str = str.replace('class="quote', 'class="quote-wh'); str += (attr.collapse ? ' collapse' : '') + '">'; str += '
'; return [str, '
']; } else { str += '">'; if(attr.unnamed) { var username = attr.unnamed.trim(); if(username.length > 0) { str += ''; if(attr.url && Markup._isUrlSafe(attr.url)) str += '' + username + ''; else if(g_isUsernameValid(username)) str += '' + username + ''; else str += username; str += ' '+ LANG.markup_said + '
'; } } return [str, '']; } } }, race: { empty: true, allowInReplies: true, valid: { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 22: true, 24: true, 25: true }, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, gender: { req: false, valid: /^(0|1)$/ }, icon: { req: false, valid: /^false$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; if(Markup.tags.race.valid[attr.unnamed]) return true; return false; }, toHtml: function(attr) { var id = attr.unnamed; var gender = attr.gender | 0; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_races[id] && g_races[id][nameCol]) { var race = g_races[id]; return ' ' + Markup._safeHtml(race[nameCol]) + ''; } return '(' + LANG.types[14][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_races[id] && g_races[id][nameCol]) return Markup._safeHtml(g_races[id][nameCol]); return LANG.types[14][0] + ' #' + id; } }, reveal: { empty: false, rtrim: true, ltrim: true, allowedClass: MARKUP_CLASS_STAFF, toHtml: function(attr) { if(!Markup.inBlog || Markup.inBlog > 1) return ['', '']; return [' (read more)']; Markup.reveals++; } }, s: { empty: false, allowInReplies: true, toHtml: function(attr) { return ['', '']; }, fromHtml: function(str) { return str.replace(/([\s\S]*?)<\/del>/gi, '[s]$1[/s]'); } }, screenshot: { empty: false, attr: { id: { req: false, valid: /^[0-9]+$/ }, url: { req: false, valid: /\S+/ }, thumb: { req: false, valid: /\S+/ }, size: { req: false, valid: /^(thumb|resized|normal)$/i }, width: { req: false, valid: /^[0-9]+$/ }, height: { req: false, valid: /^[0-9]+$/ }, 'float': { req: false, valid: /^(left|right)$/i }, border: { req: false, valid: /^[0-9]+$/ }, shadow: { req: false, valid: /^(true|false)$/ } }, taglessSkip: true, allowedClass: MARKUP_CLASS_STAFF, validate: function(attr) { if(attr.url && !attr.thumb) return false; else if(!attr.id && !attr.url) return false; return true; }, toHtml: function(attr) { var classes = []; var styles = []; var url = ''; var thumb = ''; if(attr.id) { url = g_staticUrl + '/uploads/screenshots/normal/' + attr.id + '.jpg'; var thumbId = attr.id; if(attr.thumb && attr.thumb.match(/^[0-9]+$/)) { thumbId = attr.thumb; attr.thumb = null; } thumb = g_staticUrl + '/uploads/screenshots/' + (attr.size ? attr.size : 'thumb') + '/' + thumbId + '.jpg'; } else if(attr.url) url = attr.url; if(attr.thumb) thumb = attr.thumb; var caption = attr._contents.replace(/\n/g, '
'); if(!g_screenshots[Markup.uid]) g_screenshots[Markup.uid] = []; var str = ''; str += '']; } }, script: { ltrim: true, rtrim: true, empty: false, attr: { src: { req: false, valid: /^\S+$/ } }, allowedClass: MARKUP_CLASS_ADMIN, allowedChildren: { '': 1 }, rawText: true, taglessSkip: true, toHtml: function(attr) { if(attr.src) { $.getScript(attr.src, function() { $.globalEval(attr._contents); }); } else $.globalEval(attr._contents); return ['']; } }, section: { empty: false, ltrim: true, rtrim: true, trim: true, allowedClass: MARKUP_CLASS_STAFF, attr: { }, toHtml: function(attr) { return ['
', '
']; } }, skill: { empty: true, allowInReplies: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function(attr) { if((attr.domain || attr.site) && Markup.dbpage) return false; return true; }, toHtml: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; var nameCol = domainInfo[1]; if(g_skills[id] && g_skills[id][nameCol]) { var skill = g_skills[id]; return ' ' + Markup._safeHtml(skill[nameCol]) + ''; } return '(' + LANG.types[15][0] + ' #' + id + ')'; }, toText: function(attr) { var id = attr.unnamed; var domainInfo = Markup._getDatabaseDomainInfo(attr); var nameCol = domainInfo[1]; if(g_skills[id] && g_skills[id][nameCol]) return Markup._safeHtml(g_skills[id][nameCol]); return LANG.types[15][0] + ' #' + id; } }, sig: { empty: true, attr: { unnamed: { req: true, valid: /^[0-9]+$/ } }, allowedClass: MARKUP_CLASS_PREMIUM, allowedModes: { signature: 1 }, toHtml: function(attr) { return; return ''; } }, small: { empty: false, toHtml: function(attr) { return ['', '']; }, fromHtml: function(str) { return str.replace(/([\s\S]*?)<\/small>/gi, '[small]$1[/small]'); } }, sound: { empty: true, attr: { unnamed: { req: false, valid: /^[0-9]+$/ }, src: { req: false, valid: /\S+/ }, title: { req: false, valid: /\S+/ }, type: { req: false, valid: /\S+/ }, src2: { req: false, valid: /\S+/ }, type2: { req: false, valid: /\S+/ }, domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } }, validate: function (attr) { if(attr.unnamed) return true; if(!attr.src) return false; return true; }, toHtml: function (attr) { var type, src, title, href, src2, type2; var domainInfo = Markup._getDatabaseDomainInfo(attr); var url = domainInfo[0]; if (attr.unnamed) { if (!(attr.unnamed in g_sounds)) return ''; if (!g_sounds[attr.unnamed].hasOwnProperty("files")) return ''; if (g_sounds[attr.unnamed].files.length == 0) return ''; if (!g_sounds[attr.unnamed].files[0].hasOwnProperty('type')) return ''; type = g_sounds[attr.unnamed].files[0].type; src = g_sounds[attr.unnamed].files[0].url; title = g_sounds[attr.unnamed].name ? g_sounds[attr.unnamed].name: g_sounds[attr.unnamed].files[0].title; href = url + '?sound=' + attr.unnamed; } else { if (Markup.allow < MARKUP_CLASS_STAFF) return ''; src = attr.src; title = attr.title ? attr.title: '(Unknown)'; if (attr.hasOwnProperty('type')) type = attr.type; else { switch (attr.src.toLowerCase().substr(-4)) { case '.mp3': type = 'audio/mpeg'; break; case '.ogg': type = 'audio/ogg; codecs="vorbis"'; break; } } if (attr.src2) { src2 = attr.src2; if (attr.hasOwnProperty('type2')) type2 = attr.type2; else { switch (attr.src2.toLowerCase().substr(-4)) { case '.mp3': type2 = 'audio/mpeg'; break; case '.ogg': type2 = 'audio/ogg; codecs="vorbis"'; break; } } } } var str = '