‘):”http://tecnoblog.net/”},t.getDefinedParams=function(n,e){return e.filter(function(e){return n[e]}).reduce(function(e,t){return l(e,function(e,t,n){t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n;return e}({},t,n[t]))},{})},t.isValidMediaTypes=function(e){var t=[“banner”,”native”,”video”];if(!Object.keys(e).every(function(e){return s()(t,e)}))return!1;if(e.video&&e.video.context)return s()([“instream”,”outstream”,”adpod”],e.video.context);return!0},t.getBidderRequest=function(e,t,n){return c()(e,function(e){return 0
“)}(r.script,r.impression_id);var o=f(b[r.size_id].split(“x”).map(function(e){return Number(e)}),2);n.width=o[0],n.height=o[1]}n.rubiconTargeting=(Array.isArray(r.targeting)?r.targeting:[]).reduce(function(e,r){return e[r.key]=r.values[0],e},{rpfl_elemid:i.adUnitCode}),e.push(n)}else d.logError(“Rubicon bid adapter Error: bidRequest undefined at index position:”.concat(t),s,a);return e},[]).sort(function(e,r){return(r.cpm”http://tecnoblog.net/”0)-(e.cpm”http://tecnoblog.net/”0)})},getUserSyncs:function(e,r,t){if(!w&&e.iframeEnabled){var i=”http://tecnoblog.net/”;return t&&”string”==typeof t.consentString&&(“boolean”==typeof t.gdprApplies?i+=”?gdpr=”.concat(Number(t.gdprApplies),”&gdpr_consent=”).concat(t.consentString):i+=”?gdpr_consent=”.concat(t.consentString)),w=!0,{type:”iframe”,url:o+i}}},transformBidParams:function(e,r){return d.convertTypes({accountId:”number”,siteId:”number”,zoneId:”number”},e)}};function y(e,r){var t,i=0
// Verifica se o GoogleTag está presente
window.googletag = window.googletag “http://tecnoblog.net/” { cmd: [] }
// Timer para refresh dos anúncios
function Timer (callback, delay) {
let timerId, start, remaining = delay;
this.running = false
this.finished = false
let callbackHandle = () => {
this.running = false
this.finished = true
if (callback) callback()
}
this.pause = function () {
if (this.finished “http://tecnoblog.net/” !this.running) return
window.clearTimeout(timerId)
remaining -= new Date() – start
this.running = false
}
this.resume = function () {
if (this.finished “http://tecnoblog.net/” this.running) return
start = new Date()
window.clearTimeout(timerId)
timerId = window.setTimeout(callback, remaining)
this.running = true
}
this.increaseBy = function (amount) {
this.pause()
if (!this.finished) {
this.remaining += amount
} else {
this.remaining = amount
this.finished = false
}
this.resume()
}
this.resume()
}
// Biblioteca de Prebidding do Tecnoblog
window.TecnoblogAdBidding = function (settings) {
const $this = this
const $$ = $this.$$ = Object.assign({
// Anúncios formatados irão nas arrays dentro desta variável
ads: {
slots: [],
prebid: [],
gpt: [],
gptInstant: [],
gptNonInstant: []
},
bidderCpmMultipliers: {
aol: (1 / 1.20),
rubicon: (1 / 1.20),
appnexus: (1 / 1.15),
smartadserver: (1 / 1.20),
},
lazyLoad: {
fetchMarginPercent: 150, // Fetch slots within 2 viewports.
renderMarginPercent: 150, // Render slots within 1.25 viewports.
mobileScaling: 1.5 // Double the above values on mobile.
},
// Configuração de tamanhos do Prebid
sizes: [],
// Timeout
timeout: 2000,
// Timeout para inserção de slots
slotLoadTimeout: 50,
// Labels ativas
enabledLabels: [],
// Slots do GPT
gpt_slots: {
slots: [],
define: [],
display: []
},
// Janela está visível?
windowVisible: true,
// Eventos
eventHandlers: {},
eventHandlersOnce: {},
// Ajustes do tracker de viewability
viewabilityTracker: {
maxRefreshes: 5,
minViewabilityPercent: 50,
timeoutRender: 15000,
timeoutRefresh: 40000,
timeoutRefreshRetry: 10000,
timeoutUserActivity: 10000,
},
// Status
hasBidded: false, // Já ocorreu o leilão?
isRefreshing: false // Estamos dentro de um refresh?
}, ((window.TecnoblogAdConfig && window.TecnoblogAdConfig.bidding) ? window.TecnoblogAdConfig.bidding : { }))
// Acompanha o viewability
$this.viewabilityTracker = new (function ViewabilityTracker() {
// Lista de slots
let adSlots = this.adSlots = {}
// Prefixo de debug
let db = ‘viewability-tracker’
// Visibilidade da página (está na mesma aba?)
setTimeout(() => {
this.isPageVisible = false
$this.on(‘windowVisibilityChanged’, isVisible => {
// Define se a página está visivel
this.isPageVisible = isVisible
// Debug
$this.debug(db, ‘Window is visible:’, isVisible)
// Pausa ou continua timers se necessário
if (isVisible) this.refreshResume()
else this.refreshPause()
})
// Acompanhar atividade do usuário na página
let validActivityEvents = [‘mousedown’, ‘mousemove’, ‘mouseup’, ‘scroll’, ‘touchstart’, ‘touchmove’, ‘touch’, ‘keydown’, ‘keypress’, ‘keyup’]
let isProcessingActivity = false
validActivityEvents.map(eventName => {
// Event handler de atividade
let eventHandler = event => {
// Throttling
if (isProcessingActivity) return
isProcessingActivity = true
setTimeout(() => { isProcessingActivity = false }, 100)
// Apenas quando o usuário ficar ativo novamente
if (!this.isUserActive) {
// Debug
$this.debug(db, ‘User active again.’)
// Continua timer dos anúncios
this.refreshResume()
}
// Definimos a variável de atividade do usuário como true
this.isUserActive = true
// Limpa o timeout de atividade e gera um novo
clearTimeout(this.isUserActiveTimeout)
this.isUserActiveTimeout = setTimeout(() => {
// Ao ocorrer timeout de atividade, definimos a variável como false
this.isUserActive = false
// Também pausamos o timer dos anúncios
this.refreshPause()
// Debug
$this.debug(db, ‘User went inactive.’)
}, $this.$$.viewabilityTracker.timeoutUserActivity)
}
// Registra o event handler
$(‘body’).on(eventName, eventHandler)
$(window).on(eventName, eventHandler)
})
}, 1)
// Pausa refresh de todos slots
this.refreshPause = function refreshPause() {
// Pausa ou continua timers se necessário
Object.values(adSlots).map(adSlot => {
// Não executar caso não exista timer
if (!adSlot.timerRefresh) return
// Pausa
adSlot.timerRefresh.pause()
})
// Debug
$this.debug(db, ‘Refresh paused for all slots.’)
}
// Continua refresh de todos slots
this.refreshResume = function refreshResume () {
// Armazenaremos quais slots deram refresh aqui
let slots = []
// Pausa ou continua timers se necessário
Object.values(adSlots).map(adSlot => {
// Não executar caso não exista timer
if (!adSlot.timerRefresh) return
// Testar se o slot já deu viewability
if (!adSlot.isAdViewed) return
// Coloca na lista de slots que estão sendo processados
slots.push(adSlot.id)
// Continua
adSlot.timerRefresh.resume()
})
// Debug
$this.debug(db, ‘Refresh resumed for slots:’, slots)
}
// Obtém um slot de uma definição de slot do GPT
this.getAdSlotFromGptSlot = function (gptSlot) {
return this.adSlots[gptSlot.$$.block]
}
// Registra um slot
this.registerAdSlot = function registerAdSlot (gptSlot) {
// Cria o slot
let adSlot = {
id: gptSlot.$$.block,
slot: gptSlot,
code: gptSlot.$$.code,
events: gptSlot.$$.events “http://tecnoblog.net/” { },
settings: gptSlot.$$,
refreshCount: 0,
timerRefresh: null,
timeoutRender: null,
isRendered: false,
isAdViewed: false,
isVisible: true,
isInstant: gptSlot.instantDFP,
getSetting: function getSetting (settingName, defaultValue) {
// Separamos os argumentos do setting
let settingArgs = settingName.split(‘.’)
// Guardaremos a variável atual aqui
let currentData = this.settings
// Processamos o walk aqui
for (let iSetting = 0, setting; setting = settingArgs[iSetting++];) {
// Obtemos o novo valor aqui
let newCurrentData = currentData[setting]
// Verificamos se é indefinido
if (typeof newCurrentData !== ‘undefined’) {
// Caso não seja, continuamos
currentData = newCurrentData
} else {
// Caso seja, retornamos o valor padrão
return defaultValue
}
}
// Após o loop, retornamos o valor atual
return currentData
}
}
// Registra
adSlots[adSlot.id] = adSlot
// Debug
$this.debug(db, ‘Register slot:’, adSlot)
}
// Registra o refresh dos slots
this.registerAdSlotRefresh = function registerAdSlotRefresh (slots) {
// Converte em array caso já não seja
if (!Array.isArray(slots)) slots = [slots]
// Processa o refresh, limpa timeouts existentes e configura os novos
slots.map(gptSlot => {
// Obtém o slot
let adSlot = this.getAdSlotFromGptSlot(gptSlot)
// Seta o slot para não visto
adSlot.isAdViewed = false
// Limpa os timeouts
clearTimeout(adSlot.timeoutRender)
// Limpa o timer
adSlot.timerRefresh.pause()
adSlot.timerRefresh = null
// Salva o slot
adSlots[adSlot.id] = adSlot
})
}
// Verifica se o slot renderizou
this.checkSlotRender = function checkSlotRender (gptSlot) {
return
// Obtém o slot
let adSlot = this.getAdSlotFromGptSlot(gptSlot)
// Debug
$this.debug(db, ‘Render for slot has timed out, doing nothing:’, adSlot.id)
// Não fazer mais nada, apenas deixar logado
return
// Checa se renderizou, se sim não fazemos nada
if (adSlot.isRendered) return;
// Debug
$this.debug(db, ‘Render timeout:’, adSlot.id)
// Caso não tenha renderizado, ativamos a rotina de refresh
this.handleSlotRefresh(gptSlot)
}
// Executa quando o slot está visível
this.handleSlotViewable = function handleSlotViewable (gptSlot) {
// Obtém o slot
let adSlot = this.getAdSlotFromGptSlot(gptSlot)
// Debug
$this.debug(db, ‘Impression viewable:’, adSlot.id)
// Garantir que o slot não vai ter um refresh precoce
adSlot.isRendered = true
// Registra o viewability
adSlot.isAdViewed = true
// Cria um timer para o refresh
adSlot.timerRefresh = new Timer(() => { this.handleSlotRefresh(gptSlot) }, adSlot.getSetting(‘bidding.timeoutRefresh’, $$.viewabilityTracker.timeoutRefresh))
// Caso a página esteja inativa, pausamos
if (!this.isPageVisible) adSlot.timerRefresh.pause()
// Salvamos o slot
adSlots[adSlot.id] = adSlot
// Caso o slot possua eventos e o evento vieawbility definidos, chamamos
if (adSlot.events.viewability) {
adSlot.events.viewability.call(adSlot)
}
}
// Realiza refresh do anúncio
this.handleSlotRefresh = function handleSlotRefresh (gptSlot) {
// Obtemos qual é o adSlot
let adSlot = this.getAdSlotFromGptSlot(gptSlot)
// Debug
$this.debug(db, ‘Refresh triggered:’, adSlot.id)
// Checamos o viewability
if (!!adSlot.getSetting(‘bidding.inViewEnable’) && !adSlot.inView) {
// Debug
$this.debug(db, ‘Slot percentage under minimum required. Not refreshing:’, adSlot.id)
// Criamos o timer novamente
adSlot.timerRefresh.increaseBy($$.viewabilityTracker.timeoutRefreshRetry)
// Encerrar
return
}
// Checamos se o slot não atingiu limite de refresh
if (adSlot.refreshCount >= adSlot.getSetting(‘bidding.maxRefreshes’, $$.viewabilityTracker.maxRefreshes)) {
// Debug
$this.debug(db, ‘Max refresh count for slot hit. Not refreshing:’, adSlot.id)
// Encerrar
return
}
// Checamos se ele está visível ou o usuário está ativo
if (!(this.isPageVisible “http://tecnoblog.net/” this.isUserActive) “http://tecnoblog.net/” (!adSlot.isVisible && adSlot.isRendered)) {
// Debug
$this.debug(db, ‘Page, user or slot not active or visible. Not refreshing:’, adSlot.id)
// Salvar
adSlots[adSlot.id] = adSlot
// Encerrar
return
}
// Atualiza contagem de refresh
adSlot.refreshCount++
adSlots[adSlot.id] = adSlot
// Criamos uma array com os slots que atualizaremos
let prebidSlots = [gptSlot.$$.block];
// Checamos se iremos utilizar diretamente Google
if (adSlot.isInstant) {
// Caso seja só Google, damos refresh direto
googletag.pubads().refresh([gptSlot])
$this.viewabilityTracker.registerAdSlotRefresh(prebidSlots)
} else {
// Caso seja Prebid, fazemos o bidding do refresh
pbjs.que.push(() => {
// Fazemos o leilão
$this.debug(db, ‘requestBids’, prebidSlots);
pbjs.requestBids({
timeout: $$.timeout,
adUnitCodes: prebidSlots,
bidsBackHandler: function () {
// Limpamos o slot para dar espaço ao novo anúncio
$(`#${gptSlot.$$.code}`).html(“http://tecnoblog.net/”)
// Enfileiramos os eventos
googletag.cmd.push(() => {
pbjs.que.push(() => {
// Debug
$this.debug(db, ‘Refeshing:’, prebidSlots)
// Setamos o targeting
pbjs.setTargetingForGPTAsync(prebidSlots)
googletag.pubads().refresh([gptSlot])
$this.registerAdSlotRefresh(prebidSlots)
$this.emit(‘pubadsReady’)
})
})
}
})
})
}
}
// Acompanha render e visibilidade usando a API do GPT
googletag.cmd.push(() => {
// Quando receber notificação de viewabiity
googletag.pubads().addEventListener(‘impressionViewable’, event => {
// Verificamos se temos controle sobre o slot
let adSlot = this.getAdSlotFromGptSlot(event.slot)
// Só executar rotina se ele existir
if (adSlot) this.handleSlotViewable(event.slot)
})
// Quando receber uma resposta do slot (começa a renderizar)
googletag.pubads().addEventListener(‘slotResponseReceived’, event => {
// Pegamos o slot
let adSlot = this.getAdSlotFromGptSlot(event.slot)
// Checar se o slot está registrado
if (!adSlot) return;
// Configura timeout de render, caso o anúncio não tenha renderizado neste tempo, forçar refresh
adSlot.timeoutRender = setTimeout(() => { this.checkSlotRender(event.slot) }, $$.viewabilityTracker.timeoutRender)
// Colocamos o status como não renderizado
adSlot.isRendered = false
// Debug
$this.debug(db, ‘Slot render started:’, adSlot.id)
// Salvamos o slot
adSlots[adSlot.id] = adSlot
})
// Quando receber um evento de render ended
googletag.pubads().addEventListener(‘slotRenderEnded’, event => {
// Obtemos o slot
let adSlot = this.getAdSlotFromGptSlot(event.slot)
// Checar se o slot está registrado
if (!adSlot) return;
// Debug
$this.debug(db, ‘Slot render ended:’, adSlot.id)
// Setamos como renderizado
// adSlot.isRendered = true
// Salvamos
adSlots[adSlot.id] = adSlot
})
// Quando receber um evento de load
googletag.pubads().addEventListener(‘slotOnload’, event => {
// Obtemos o slot
let adSlot = this.getAdSlotFromGptSlot(event.slot)
// Checar se o slot está registrado
if (!adSlot) return;
// Debug
$this.debug(db, ‘Slot finished loading:’, adSlot.id)
// Setamos como renderizado
adSlot.isRendered = true
// Salvamos
adSlots[adSlot.id] = adSlot
})
// Quando a visibilidade de um slot mudar
googletag.pubads().addEventListener(‘slotVisibilityChanged’, event => {
// Apenas logamos no slot o quanto está visível
let adSlot = this.getAdSlotFromGptSlot(event.slot)
adSlot.inView = event.inViewPercentage >= adSlot.getSetting(‘bidding.minViewabilityPercent’, $$.viewabilityTracker.minViewabilityPercent)
adSlot.inViewPercentage = event.inViewPercentage
// Salvamos
adSlots[adSlot.id] = adSlot
// Não estaremos usando este evento por enquanto
return
/*
// Obtemos o slot
let adSlot = this.getAdSlotFromGptSlot(event.slot)
// Checar se o slot está registrado
if (!adSlot) return;
// Status anterior
let lastStatus = adSlot.isVisible
// Mudamos a visibilidade aqui
adSlot.isVisible = event.inViewPercentage >= adSlot.getSetting(‘bidding.minViewabilityPercent’, $$.viewabilityTracker.minViewabilityPercent)
// Debug if changed
if (lastStatus != adSlot.isVisible)
$this.debug(db, ‘Slot visibility changed:’, adSlot.id, event.inViewPercentage, adSlot.isVisible)
// Verificamos se tem um timer de refrsh primeiro
if (adSlot.timerRefresh) {
// Controlamos estado de refresh aqui
if (adSlot.isVisible) {
// Verificamos se o slot já não expirou o refresh
if (adSlot.timerRefresh.finished) {
// Neste caso, criamos um novo Timer
adSlot.timerRefresh = new Timer(() => { this.handleSlotRefresh(adSlot.slot) }, adSlot.getSetting(‘bidding.timeoutRefresh’, $$.viewabilityTracker.timeoutRefresh))
}
// Continuamos o Timer aqui
adSlot.timerRefresh.resume()
// Debug
$this.debug(db, ‘Resuming slot refresh timer:’, adSlot.id)
} else {
// Pausamos o Timer
adSlot.timerRefresh.pause()
// Debug
$this.debug(db, ‘Pausing slot refresh timer:’, adSlot.id)
}
}
// Setamos como renderizado
adSlot.isRendered = true
// Salvamos
adSlots[adSlot.id] = adSlot*/
})
})
})
// Eventos
$this.on = function on(event, handler) {
if (typeof event != ‘string’) return;
event = event.toLowerCase();
// Cria array para o evento
if (!$$.eventHandlers[event])
$$.eventHandlers[event] = [];
$$.eventHandlers[event].push(handler);
}
$this.once = function once(event, handler) {
if (typeof event != ‘string’) return;
event = event.toLowerCase();
// Cria array para o evento
if (!$$.eventHandlersOnce[event])
$$.eventHandlersOnce[event] = [];
$$.eventHandlersOnce[event].push(handler);
}
$this.emit = function emit(event) {
if (typeof event != ‘string’) return;
event = event.toLowerCase();
var handlersOnce = $$.eventHandlersOnce[event];
var handlers = $$.eventHandlers[event];
var args = Array.prototype.slice.call(arguments, 1);
handlers = [].concat(handlers).concat(handlersOnce);
// Limpar o handlers once (executam uma só vez)
delete $$.eventHandlersOnce[event];
for (var i = 0, handler; handler = handlers[i++];) {
if (!handler) continue;
handler.apply($this, (args “http://tecnoblog.net/” []));
}
}
// Função para debugar
$this.debug = function debug() {
var args = [
‘TecnoblogAdBidding’,
].concat(Array.prototype.slice.call(arguments));
return console.log.apply(this, args);
}
// Função para testar se determinada media query bate
$this.testMediaQuery = function testMediaQuery(query) {
return window.matchMedia(query).matches;
}
// Função para criar tags para cada slot de anúncio
$this.createSlotHtml = function createSlotHtml(adSlot, cb) {
// Carregamos um HTML dummy para elementos que possuem display: none no :empty
$(adSlot.container).append($(“http://tecnoblog.net/”))
// Testamos a div
if ($(adSlot.container).length >= 1 &&
$(adSlot.container).is(‘:visible’) &&
$(adSlot.container + ‘ #’ + adSlot.code).length == 0
) {
$this.debug(‘createSlotHtml’, “http://tecnoblog.net/”, adSlot.container);
$($(adSlot.container)[0]).html(“http://tecnoblog.net/”);
// Callback quando o slot é criado
cb(adSlot);
} else {
$this.debug(‘createSlotHtml’, ‘failed to pass tests:’, adSlot.container);
}
}
// Função para carregar slot de anúncio individual
$this.loadAdSlot = function loadAdSlot(ad) {
// Testar pela propriedade “items”, que indica coleção de slots
if (ad.items) {
// No caso de coleção, fazer loop por cada um dos itens
for (var i = 0, adSlot; adSlot = ad.items[i++];) {
// Aplicar labels
if (ad.labels)
adSlot.labels = (adSlot.labels ? adSlot.labels : []).concat(ad.labels);
// Aplicar media queries
if (ad.mediaQuery)
adSlot.mediaQuery = (adSlot.mediaQuery ? adSlot.mediaQuery : []).concat(ad.mediaQuery);
// Inserir slot
$this.loadAdSlot(adSlot);
}
return this;
}
// Anúncion o Prebid, permitir apenas quando a propriedade ‘prebid’ existir (pode estar vazia)
if (ad.prebid && ad.prebid != undefined) {
// Inserir anúncio no Prebid
$$.ads.prebid.push($this.getPrebidSlot(ad));
} else {
// Como não está no Prebid, ativar o DFP instantaneamente para este slot
ad.instantDFP = true;
}
// Inserir anúncio nos slots disponíveis
$$.ads.slots.push(ad);
return this;
}
// Função para carregar slots de anúncios em lote
$this.loadAdSlots = function loadAdSlots(ads) {
for (var i = 0, ad; ad = ads[i++];) {
$this.loadAdSlot(ad);
}
}
// Função para converter AdSlot para o formato Prebid
$this.getPrebidSlot = function getPrebidSlot(slot) {
// Filtrar tamanhos para o Prebid
var prebidSizes = [];
for (var i = 0, size = slot.sizes; size = slot.sizes[i++];) {
// Condições para ser removido
if (
!Array.isArray(size) “http://tecnoblog.net/”
~size.indexOf(‘fluid’)
) continue;
// Inserir na array
prebidSizes.push(size);
}
return Object.assign({
code: slot.code,
mediaTypes: (slot.mediaTypes ? slot.mediaTypes : {
banner: {
sizes: prebidSizes
}
}),
bids: (slot.prebid && slot.prebid.bids ? slot.prebid.bids : [{}]),
labels: (slot.labels ? slot.labels : [])
}, (slot.prebid ? slot.prebid : {}));
}
// Converte lista de slots para o formato prebid
$this.getPrebidSlots = function getPrebidSlots(slots) {
var prebidSlots = [];
for (var i = 0, slot; slot = slots[i++];) {
if (slot.prebid)
prebidSlots.push($this.getPrebidSlot(slot));
}
return prebidSlots;
}
// Função para definir tamanhos dos anúncios
$this.sizeConfig = function sizeConfig(sizes) {
$$.sizes = sizes;
// Evento para quando trocar o tamanho da mídia, rodar outro bid
for (var i = 0, size; size = sizes[i++];) {
window.matchMedia(size.mediaQuery).addListener($this.onMediaQueryUpdated);
}
// Já carregar quais labels estão ativas
$this.updateMediaQueryLabels();
}
// Função wrapper para rodar função ‘fn’ quando determinado elemento entrar no HTML. Fallback para $(document).ready
$this.cbOnElementLoaded = [];
$this.onElementLoadedObserver = null;
$this.onElementLoaded = function onElementLoaded(elemento, fn) {
// Verificar se elemento já existe primeiro
if ($(elemento).length > 0) {
if (fn)
$(elemento).each((i, o) => fn(o))
return;
}
// Testar se o browser suporta MutationObserver
if (MutationObserver) {
// Caso nosso observer não exista, criar um
if ($this.onElementLoadedObserver == null) {
$this.onElementLoadedObserver = new MutationObserver((mutations) => {
// Loop em cada mutação
for (var i = 0; i {
$this.emit(‘biddingTimeout’)
$this.debug(‘Timeout do leilão.’)
pbjs.offEvent(‘bidRequested’, setAuctionTimeout)
isTimeoutStarted = false
}, $$.timeout + 200)
}
// Quando primeiro bidder terminar, definir timeout
pbjs.onEvent(‘bidRequested’, setAuctionTimeout)
// Se o GPT estiver presente, desativar o carregamento automático
if (googletag) {
$this.debug(‘prebid’, ‘Disabling DFP initial load’);
googletag.cmd = googletag.cmd “http://tecnoblog.net/” [];
googletag.cmd.push(function () {
googletag.pubads().disableInitialLoad();
});
}
pbjs.que = pbjs.que “http://tecnoblog.net/” [];
// Configuração do Prebid
pbjs.setConfig({
useBidCache: true,
bidderSequence: ‘random’,
priceGranularity: ‘high’,
enableSendAllBids: true,
bidderTimeout: $$.timeout,
userSync: {
// enabledBidders: [‘rubicon’],
syncDelay: 5000,
iframeEnabled: true
},
currency: {
adServerCurrency: ‘USD’
}
})
// Configuração de ajuste dos bids
let allBidderSettings = pbjs.bidderSettings “http://tecnoblog.net/” {}
for (let bidder in $$.bidderCpmMultipliers) {
// Obtemos o multiplier
let multiplier = $$.bidderCpmMultipliers[bidder]
// Obtemos os settings deste bidder
let bidderSettings = allBidderSettings[bidder] “http://tecnoblog.net/” {}
// COnfiguramos o ajuste de CPM
bidderSettings.bidCpmAdjustment = (bidCpm) => {
// Debug
$this.debug(‘bidCpmAdjustment:’, bidder, `$${bidCpm} => $${bidCpm * multiplier}`)
// Retorna o valor com multiplier aplicado
return bidCpm * multiplier
}
// Salvamos os settings deste bidder
allBidderSettings[bidder] = bidderSettings
}
// Salvamos todos os bidder settings
pbjs.bidderSettings = allBidderSettings
} else {
$this.debug(‘bid-init’, ‘Prebid (pbjs) não encontrado.’)
}
// Callback para realizar bids após os slots carregarem
var bidFunctionTimeout = null;
var bidFunction = () => {
googletag.cmd.push(function () {
// Debug
$this.debug(‘googletag.enableSingleRequest’, ‘googletag.enableLazyLoad’, ‘googletag.enableServices’)
// Ativa single request
googletag.pubads().enableSingleRequest()
// Ativar lazy loading
if ($this.$$.lazyLoad) {
$this.debug(‘googletag.enableLazyLoad’, $this.$$.lazyLoad)
googletag.pubads().enableLazyLoad($this.$$.lazyLoad)
}
// Ativa Google Ads
googletag.enableServices()
// Dispara anuncios sem Prebid
setTimeout(() => {
$this.$$.ads.gptInstant.map(gptSlot => {
$this.debug(‘gptInstant’, gptSlot.$$.code, gptSlot)
pbjs.setTargetingForGPTAsync([gptSlot.$$.code])
googletag.pubads().refresh([gptSlot])
})
}, $this.$$.slotLoadTimeout)
// Debug
$this.debug(‘bidFunction’, ‘Bidding…’)
// Realizar bids
if (pbjs) {
pbjs.que.push(function () {
// Obtém lista de slots
let prebidSlots = $this.$$.ads.gptNonInstant.map(slot => slot.$$.code)
// Pedir bids
$this.debug(‘requestBids’, prebidSlots)
$this.emit(‘requestBids’, prebidSlots)
pbjs.requestBids({
adUnitCodes: prebidSlots,
bidsBackHandler: prebidTimeout
})
})
}
})
}
// Loop de preparo
for (var i = 0, theSlot; theSlot = slots[i++];) {
let slot = theSlot;
let slotContainerID = slot.container;
let slotID = slot.container + ‘ #’ + slot.code;
// Idade mínima e máxima do conteúdo
let slotContentMinAge = slot.contentMinAge “http://tecnoblog.net/” 0
let slotContentMaxAge = slot.contentMaxAge “http://tecnoblog.net/” Infinity
// Só rodar validação caso exista alguma idade de post em primeiro lugar
if (window.currentContentAge && !(slotContentMinAge {
console.log(‘LOADED’, slot, slotContainerID, slotID);
// Criar HTML dos slots
$this.createSlotHtml(slot, function (slot) {
$this.debug(‘createSlotHtml’, slotID);
// Rodar código de criação do slot apenas quando o elemento carregar
$this.onElementLoaded(slotID, () => {
$this.debug(‘onElementLoaded’, slotContainerID);
// Preparar GPT
$$.ads.gpt.push(slot.code);
$this.debug(‘GPTslot’, slot);
if ($(slot.container).is(‘:visible’) &&
$(slotID).length == 1 &&
$(slotID).html() == “http://tecnoblog.net/”
) {
googletag.cmd.push(function () {
$this.debug(‘googletag.defineSlot’, slot);
var gptSlot = googletag.defineSlot(slot.block, slot.sizes, slot.code)
.addService(googletag.pubads());
// Targeting
if (slot.targeting) {
for (var target in slot.targeting) {
$this.debug(‘gptSlot.setTargeting’, target, slot.targeting[target]);
gptSlot.setTargeting(target, slot.targeting[target]);
}
}
// Evento callback para Branded Channel
$($this.cbOnSlotSetup).each((i, callback) => {
var output = callback.call($this, gptSlot);
// Quando houver return
if (output != undefined)
gptSlot = output;
});
// Chama a função display do GPT para iniciar o bid para o slot
googletag.cmd.push(function () {
googletag.display(slot.code);
});
// Seta informações do slot (meta)
gptSlot.$$ = slot;
// Registra o slot
$this.viewabilityTracker.registerAdSlot(gptSlot);
// Se o slot permitir exibição instantanea, exibir!
if (slot.instantDFP) {
// Carrregar os slots instantâneos
$this.debug(‘slot.instantDFP’, slot);
$this.$$.ads.gptInstant.push(gptSlot);
} else {
// Prebid
$this.debug(‘slot.nonInstantDFP’, slot);
$this.$$.ads.gptNonInstant.push(gptSlot);
// Prepara o Prebid
if (pbjs) {
// Insere slot no Prebid
if (slot.prebid && slot.prebid != undefined) pbjs.que.push(() => {
pbjs.addAdUnits($this.getPrebidSlot(slot));
$this.debug(‘pbjs.addAdUnits’, $this.getPrebidSlot(slot));
});
}
}
// Resetar timeout para realizar bids
clearTimeout(bidFunctionTimeout);
bidFunctionTimeout = setTimeout(bidFunction, $$.slotLoadTimeout);
});
}
});
});
});
}
/* // Loop de preparo
for (var i = 0, slot; slot = slots[i++];) {
// Criar HTML dos slots
$this.createSlotHtml(slot, function (slot) {
// Preparar GPT
$$.ads.gpt.push(slot.code);
// Prepara o Prebid
if (pbjs) {
// Insere slot no Prebid
if (slot.prebid && slot.prebid != undefined) pbjs.que.push(() => {
pbjs.addAdUnits($this.getPrebidSlot(slot));
$this.debug(‘pbjs.addAdUnits’, $this.getPrebidSlot(slot));
});
// Resetar timeout para realizar bids
clearTimeout(bidFunctionTimeout);
bidFunctionTimeout = setTimeout(bidFunction, $$.slotLoadTimeout);
}
});
}
// Realizar setup do GPT, porém não exibe nada
$this.debug(‘GPT’, googletag);
if (googletag) {
$this.debug(‘GPTslots’, slots);
googletag.cmd.push(function () {
$(slots).each(function (i, slot) {
var slotID = slot.container + ‘ #’ + slot.code;
// Rodar código de criação do slot apenas quando o elemento carregar
$this.onElementLoaded(slotID, () => {
$this.debug(‘GPTslot’, slot);
if ($(slot.container).is(‘:visible’) &&
$(slotID).length == 1 &&
$(slotID).html() == “http://tecnoblog.net/”
) {
googletag.cmd.push(function () {
$this.debug(‘googletag.defineSlot’, slot);
var gptSlot = googletag.defineSlot(slot.block, slot.sizes, slot.code)
.addService(googletag.pubads());
// Targeting
if (slot.targeting) {
for (var target in slot.targeting) {
$this.debug(‘gptSlot.setTargeting’, target, slot.targeting[target]);
gptSlot.setTargeting(target, slot.targeting[target]);
}
}
// Evento callback para Branded Channel
$($this.cbOnSlotSetup).each((i, callback) => {
var output = callback.call($this, gptSlot);
// Quando houver return
if (output != undefined)
gptSlot = output;
});
googletag.pubads().enableSingleRequest();
googletag.enableServices();
// Chama a função display do GPT para iniciar o bid para o slot
googletag.cmd.push(function () {
googletag.display(slot.code);
});
// Seta informações do slot (meta)
gptSlot.$$ = slot;
// Se o slot permitir exibição instantanea, exibir!
if (slot.instantDFP) {
googletag.cmd.push(function () {
pbjs.setTargetingForGPTAsync([slot.code]);
googletag.pubads().refresh([gptSlot]);
});
} else {
$this.$$.ads.gptNonInstant.push(gptSlot);
}
});
}
});
});
});
} */
return $this;
}
// Evento para customizar o targeting dos ads (branded channel, etc)
$this.cbOnSlotSetup = [];
$this.onSlotSetup = function onSlotSetup(fn) {
$this.cbOnSlotSetup.push(fn);
}
// Função para dizer quais slots estão ativos
$this.getEnabledSlots = function getEnabledSlots() {
// Função para testar se o slot vai ou não ser usado
var fnTest = function fnTest(slot) {
// Testar casos onde o slot tem media query específico
if (slot.mediaQuery && !$this.testMediaQuery(slot.mediaQuery))
return false;
// Testar labels
if (slot.labels && slot.labels.length > 0 && $$.enabledLabels.length > 0) {
for (var i = 0, label; label = slot.labels[i++];) {
// Caso encontrar
if (~$$.enabledLabels.indexOf(label))
return true;
}
// Caso nenhuma encontrada
return false;
}
// Testar se o slot existe e está visível
if ($(slot.container).length == 0 “http://tecnoblog.net/” !$(slot.container).is(‘:visible’))
return false;
// Padrão = true
return true;
}
// Testar todos slots disponíveis
var slots = [];
for (var i = 0, slot; slot = $$.ads.slots[i++];) {
if (fnTest(slot))
slots.push(slot);
}
return slots;
}
$this.updateMediaQueryLabels = function updateMediaQueryLabels() {
// Novas labels
var labels = [];
// Processar media queries
for (var i = 0, size; size = $$.sizes[i++];) {
if ($this.testMediaQuery(size.mediaQuery)) {
labels = labels.concat(size.labels);
}
}
// Mudar quais labels estão ativas
$$.enabledLabels = labels;
}
// Evento para quando a media query mudar (responsivo)
$this.onMediaQueryUpdated = function onMediaQueryUpdated() {
// Atualizar labels
$this.updateMediaQueryLabels();
// Recarregar anúncios
$this.refresh();
}
/**
* Construtor da biblioteca
*/
settings = settings “http://tecnoblog.net/” {};
// Calcula a idade atual do post, caso esta propriedade exista
window.currentContentAge = null
$this.onElementLoaded(‘meta[property=”article:published_time”]’, o => {
try {
let $obj = $(o)
let dateStr = $(o).prop(‘content’)
window.currentContentAge = Date.now() – Date.parse(dateStr)
if (window.currentContentAgeHook) window.currentContentAgeHook(window.currentContentAge)
$this.debug(‘init’, ‘Found content age via OG tag:’, window.currentContentAge)
} catch (e) { }
})
$this.onElementLoaded(‘script[type=”application/ld+json”]’, o => {
try {
let $obj = $(o)
let obj = JSON.parse($obj.text())
// Se for array, usamos o primeiro elemento
if (Array.isArray(obj)) obj = obj[0]
// Testar se existe o datePublished, se existir utilizamos
if (obj && obj.datePublished) {
window.currentContentAge = Date.now() – Date.parse(obj.datePublished)
if (window.currentContentAgeHook) window.currentContentAgeHook(window.currentContentAge)
$this.debug(‘init’, ‘Found content age via LD+JSON:’, window.currentContentAge)
}
} catch (e) { }
})
// Inicializa conteúdo
$this.debug(‘init’, settings);
// Aqui é onde a gente faz o A/B
if (settings.abBidding && settings.abBidding.enable) {
// Esta variável vai conter combinações de pesos que serão usados para fazer o A/B bidding
let weights = settings.abBidding.weights “http://tecnoblog.net/” []
// Aqui a gente processa os pesos, transformando em quais testes A/B venceram
weights = weights.map(ab => {
// Esta array vai conter os valores do teste A/B
let abValues = []
// Processar cada chave
for (let abKey in ab) {
// Pegamos o peso
let abWeight = ab[abKey]
// Inserimos a chave na array quantas vezes for passado o peso
for (let i = 0; i {
let items = []
// Processa os slots
adDefSize.items.map(slotDef => {
let slots = []
// Testa se o slot é um slot A/B
if (slotDef.abBidding) {
// Caso seja, processamos os resultados do A/B bidding
weights.map(ab => {
// Obtemos as extensões da definição de slot
let slotDefExtensions = slotDef.abBidding[ab]
// Caso não exista esta definição, pulamos
if (!slotDefExtensions) return
// Processamos as extensões
slotDefExtensions.map(slotDefExtension => {
// Extendemos com a definição de slot atual
let slot = Object.assign({}, slotDefExtension)
slot = Object.assign(slot, slotDefExtension)
// Remove a key abBidding
if (slot.abBidding)
delete slot.abBidding
// Inserimos na lista de slots
slots.push(slot)
})
})
} else {
// Caso não seja, retornamos o slot puro
slots.push(slotDef)
}
// Insere os slots processados
items = items.concat(slots)
})
// Salva
adDefSize.items = items
return adDefSize
})
}
// Pré-carregar configurações de tamanhos
if (settings.sizes) {
$this.debug(‘init’, ‘sizeConfig’, settings.sizes);
$this.sizeConfig(settings.sizes);
}
// Pré-carregar anúncios
if (settings.ads) {
$this.debug(‘init’, ‘loadAdSlots’, settings.ads);
$this.loadAdSlots(settings.ads);
}
// Detectar quando usuário sai da aba
$(window).on(“blur focus”, function (e) {
var prevType = $(this).data(“prevType”);
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case “blur”:
$$.windowVisible = false;
break;
case “focus”:
$$.windowVisible = true;
break;
}
$this.emit(‘windowVisibilityChanged’, $$.windowVisible);
}
$(this).data(“prevType”, e.type);
});
}
})(jQuery) })(); (() => { // Configuração dos anúncios
window.TecnoblogAdConfig = {
// Aqui vão todas configurações do arquivo tb-prebid.js, escolha uma variável e coloque o valor desejado neste objeto
bidding: {
// Ajustes do tracker de viewability
viewabilityTracker: {
maxRefreshes: 2000000000,
minViewabilityPercent: 40,
timeoutRender: 15000,
timeoutRefresh: 30000,
timeoutRefreshRetry: 1000,
timeoutUserActivity: 45000,
},
// Timeout
timeout: 1200,
lazyload: false
},
// Tamanhos pré-definidos para anúncios responsivos
sizes: [{
mediaQuery: ‘(max-width: 767px)’,
labels: [‘mobile’]
}, {
mediaQuery: ‘(max-width: 1024px)’,
labels: [‘tablet’]
}, {
mediaQuery: ‘(min-width: 1024px)’,
labels: [‘desktop’]
}],
// Bidding A/B
abBidding: {
enable: true,
weights: [{
large_format: 0,
small_format: 2,
}]
},
// Pré-carregar vários anúncios
ads: [
{
// Os anúncios dentro destes items só aparecerão quando estas labels baterem (Prebid)
labels: [‘desktop’],
items: [{
container: “#branded-channel-single-fullbanner”,
code: ‘div-gpt-ad-1526606801224-0’,
sizes: [
[1280, 390]
],
block: ‘/1774994/branded_header_desktop’,
}, {
container: “#branded-channel-home-background”,
code: ‘div-gpt-ad-1534015370690-0’,
sizes: [
[240, 1100]
],
block: ‘/1774994/background_desktop’,
}, {
container: “.branded-channel-button.branded-oracle-flag”,
code: ‘div-gpt-ad-1526856462720-0’,
sizes: [
[125, 33]
],
block: ‘/1774994/branded_botao_1’,
}, {
container: “.branded-channel-banner.branded-oracle-header”,
code: ‘div-gpt-ad-1527622613006-0’,
sizes: [
[340, 74]
],
block: ‘/1774994/branded_widget_1’,
}, {
container: ‘#fullbanner .container’,
code: ‘div-gpt-ad-1431729482673-0’,
sizes: [‘fluid’,
[728, 90],
[750, 200],
[930, 180],
[960, 90],
[968, 50],
[968, 120],
[970, 90],
[970, 250]
],
block: ‘/1774994/970_desktop_topo’,
events: {
viewability () {
// Remove a classe sticky banner quando der viewability
$(‘#fullbanner-container’).removeClass(‘sticky-top’)
}
},
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802861’ // Superbanner
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802865’ // 970×90
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357367’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269398 // Superbanner
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269400 // 968×120
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269401 // 970×90
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269402 // Masthead
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69077’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, {
container: ‘#portalfullblock-desktop.adfullblock .adfullblock-content’,
code: ‘div-gpt-ad-1522111047664-0’,
sizes: [
[970, 90],
[970, 250],
[968, 120],
[700, 150],
[700, 100],
[728, 90]
],
block: ‘/1774994/superbanner_r7’,
prebid: {
bids: [{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, {
container: ‘#sidebanner’,
code: ‘div-gpt-ad-1333493913691-0’,
sizes: [‘fluid’, [240, 400],
[300, 250],
//[300, 75],
//[300, 100],
//[320, 100],
[320, 480],
[336, 280],
[250, 250]
],
block: ‘/1774994/Sidebar_Home’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357364’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269392 // 320×480
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, {
abBidding: {
large_format: [{
container: ‘#sidecommentsbanner’,
code: ‘div-gpt-ad-1441934539293-0’,
block: ‘/1774994/meia_pagina’,
sizes: [‘fluid’,
[240, 400],
[300, 250],
// [300, 75],
// [300, 100],
// [320, 100],
[320, 480],
[336, 280],
// [250, 250],
[120, 600],
[160, 600],
[300, 600]
],
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802863’ // Skyscrapper
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802863’ // Meia Página
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘16773024’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269384 // Skyscrapper
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269384 // Skyscrapper
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269392 // 320×480
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269389 // Meia Página
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69075’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}],
small_format: [{
container: ‘#ad-side-small-1’,
code: ‘div-gpt-ad-1566323933714-0’,
block: ‘/1774994/desktop_retangulo_2’,
sizes: [‘fluid’,
[250, 250],
[300, 250],
[336, 280]
],
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357363’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, {
container: ‘#ad-side-small-2’,
code: ‘div-gpt-ad-1566324011968-0’,
block: ‘/1774994/desktop_retangulo_3’,
sizes: [‘fluid’,
[300, 250],
[300, 250],
[336, 280]
],
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘16773023’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}],
}
}, {
container: ‘#sidereview’,
code: ‘div-gpt-ad-1494459843039-0’,
sizes: [‘fluid’, [300, 250],
//[300, 75],
//[300, 100],
//[320, 100],
//[320, 480],
[336, 280],
[250, 250]
],
block: ‘/1774994/retangulo_review_tablet’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357364’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, {
contentMinAge: 1000 * 3600 * 24, // Idade mínima do post: 24h
container: ‘#ad-outstream-1’,
code: ‘div-gpt-ad-1533848354816-0’,
sizes: [‘fluid’,
[700, 150],
],
block: ‘/1774994/outstream_desktop’,
prebid: {
bids: [{
bidder: ‘criteo’,
params: {
zoneId: 1269397 // 700×150
}
},
]
}
}]
}, {
// Os anúncios dentro destes items só aparecerão quando estas labels baterem (Prebid)
labels: [‘tablet’],
items: [{
container: “.branded-channel-button.branded-oracle-flag”,
code: ‘div-gpt-ad-1526856462720-0’,
sizes: [
[125, 33]
],
block: ‘/1774994/branded_botao_1’,
}, {
container: ‘#fullbanner .container’,
code: ‘div-gpt-ad-1333493772336-0’,
sizes: [
[728, 90],
[600, 50],
[600, 200],
[700, 100],
[700, 150]
],
block: ‘/1774994/Top_Principal’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802861’ //Superbanner
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357367’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269398 // Superbanner
}
},
{
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69077’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, {
container: ‘#retangulo-tablet’,
code: ‘div-gpt-ad-1494459843039-0’,
sizes: [‘fluid’, [300, 250],
[300, 100],
//[320, 480],
[336, 280],
[250, 250]
],
block: ‘/1774994/retangulo_review_tablet’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357364’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}]
}, {
// Os anúncios dentro destes items só aparecerão quando estas labels baterem (Prebid)
labels: [‘mobile’],
items: [{
container: “#ad-mobile-sticky”,
code: ‘div-gpt-ad-1565989183597-0’,
sizes: [[320, 50], [300, 100], [300, 50], [320, 100]],
block: ‘/1774994/mobile_sticky’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘5129102’ // 320×50
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘16773022’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269387 // 300×100
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269390 // 320×50
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269391 // 320×100
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69078’
}
}
]
}
}, {
container: “#branded-channel-single-fullbanner”,
code: ‘div-gpt-ad-1526606801224-0’,
sizes: [
[375, 195]
],
block: ‘/1774994/branded_header_desktop’,
}, {
container: “.branded-channel-button.branded-oracle-flag”,
code: ‘div-gpt-ad-1526856462720-0’,
sizes: [
[125, 33]
],
block: ‘/1774994/branded_botao_1’,
}, {
container: ‘#fullbanner .container’,
code: ‘div-gpt-ad-1432677491607-0’,
sizes: [‘fluid’, [300, 250],
[336, 280],
/* [320, 50], */
// [320, 100],
[250, 250]
],
block: ‘/1774994/mobile_retangulo_medio’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357364’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
}, {
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, {
container: ‘#portalfullblock-mobile.adfullblock .adfullblock-content’,
code: ‘div-gpt-ad-1522111420187-0’,
sizes: [
[300, 250]
],
block: ‘/1774994/retangulo_mobile_portal’,
}, {
container: ‘#retangulo-mobile’,
code: ‘div-gpt-ad-1432677491607-0’,
sizes: [‘fluid’,
[300, 250],
[250, 250],
// [300, 100],
[336, 280]
],
block: ‘/1774994/mobile_retangulo_medio’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357364’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
},
/*{
container: ‘#precommentsmobile’,
code: ‘div-gpt-ad-1441953683365-0’,
sizes: [‘fluid’, [320, 480],
[300, 250],
[300, 75],
[300, 100],
[320, 100],
[336, 280],
[250, 250]
],
block: ‘/1774994/300_comments_mobile’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357363’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269392
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393
}
}]
}
}, */
{ // Retângulo Mobile 2
container: ‘#ad-outstream-1’,
code: ‘div-gpt-ad-1441953683365-0’,
sizes: [‘fluid’,
[250, 250],
[336, 280],
// [300, 100],
[300, 250],
// [320, 480]
],
block: ‘/1774994/300_comments_mobile’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘13357363’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}, { // Retângulo Mobile 3
container: ‘#ad-outstream-2’,
code: ‘div-gpt-ad-1533847148837-0’,
sizes: [‘fluid’,
[250, 250],
// [300, 100],
[300, 250],
[336, 280],
// [320, 480]
],
block: ‘/1774994/retangulo_3_mobile’,
prebid: {
bids: [{
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802860’ // Arroba
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802864’ // Retângulo Médio
}
}, {
bidder: ‘aol’,
params: {
network: ‘11427.1’,
placement: ‘4802862’ // Retângulo Grande
}
}, {
bidder: ‘rubicon’,
params: {
accountId: ‘18026’,
siteId: ‘187840’,
zoneId: ‘916542’
}
}, {
bidder: ‘appnexus’,
params: {
placementId: ‘16773023’
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269385 // Arroba
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269388 // Retângulo Médio
}
}, {
bidder: ‘criteo’,
params: {
zoneId: 1269393 // Retângulo Grande
}
}, {
bidder: ‘smartadserver’,
params: {
domain: ‘https://prg.smartadserver.com’,
siteId: ‘257406’,
pageId: ‘984133’,
formatId: ‘69076’
}
},
{
bidder: ‘rtbhouse’,
params: {
publisherId: ‘tIHIAJzf8B1fu4ZwqoZ7’,
region: ‘prebid-us’
}
}
]
}
}
]
}
]
} })(); (() => { ($ => {
// Testa o AdBlock usando a API fetch
fetch(‘https://ad.doubleclick.net/’, { mode: ‘no-cors’ })
.then(() => {
// AdBlock desativado
window.adBlockEnabled = false
}).catch(() => {
// AdBlock ativado
window.adBlockEnabled = true
}).finally(() => {
// Caso o AdBlock não esteja ativado, inserimos a classe sticky no header
if (!window.adBlockEnabled) {
// Adiciona classe no body 🙂
$(‘body’).addClass(‘adblock-disabled’)
// Easter Egg
console.info(‘Obrigado por não usar AdBlock! {
// Debug
console.info(`Idade do conteúdo: ${age / 1000 / 3600} horas`)
// O conteúdo tem no mínimo 24h?
if (age >= 1000 * 3600 * 24) {
// Debug
console.info(‘Ativando banner sticky…’)
// Ativa o sticky no fullbanner
$(document).ready(() => {
$(‘#fullbanner-container’).addClass(‘sticky-top’)
})
// Timeout caso o superbanner fique “preso”, 10 segundos
setTimeout(() => { $(‘#fullbanner-container’).removeClass(‘sticky-top’) }, 10 * 1000)
} else {
// Debug
console.info(‘Continuando carregamento…’)
}
}
// Trigger backup
if (window.currentContentAge) window.currentContentAgeHook(age)
// Define os slots
var adSlots = window.TecnoblogAdConfig “http://tecnoblog.net/” {}
// Inicializa o Ads
let tecnoblogAds = window.tecnoblogAds = new TecnoblogAdBidding(adSlots)
// Insere os slots mobile no corpo
$(document).ready(function () {
// Causa um resize no primeiro carregamento
$(window).trigger(‘resize’)
});
// Customização para Branded Channel (Oracle)
if (window.tecnoblogBrandedChannel) {
tecnoblogAds.onSlotSetup(function (slot) {
// Mudar targeting para Branded Channel
this.debug(‘gptSlot.setTargeting’, ‘branded_channel_1’)
slot.setTargeting(‘branded_channel_1’, ‘sim’)
// Retornar o slot para inserção no GPT
return slot
})
}
// Chamar o bidding
tecnoblogAds.bid()
} else {
// Adiciona classe no body 🙂
$(‘body’).addClass(‘adblock-enabled’)
// Pegadinha
console.info(‘Poxa, por que usar AdBlock?!’)
console.info(‘Os anúncios nesta página são o que ajudam a manter o site no ar!’)
console.info(‘Por gentileza, desative o AdBlock! :)’)
// TODO: Implementar lógica para quando detectar AdBlock, exibir mensagens, etc.
}
})
})(jQuery) })(); /* ]]> */
Tela AMOLED, bateria gigante, Snapdragon 855+ e LED colorido estão no celular premium da Asus
Além do Zenfone 6, a Asus resolveu apostar no mercado de celulares gamers no Brasil. O ROG Phone II é o modelo mais parrudo da marca, com chip Snapdragon 855 Plus, tela AMOLED de 6,59 polegadas e bateria de 6.000 mAh para rodar jogos por horas. Ele também é o smartphone mais caro da Asus até agora: a versão com 12 GB de RAM e 512 GB de armazenamento tem preço sugerido de R$ 7.299.
Os destaques ficam por conta do processador e da tela. O Snapdragon 855 Plus é uma versão turbinada do chip premium da Qualcomm: a CPU chega a 2,96 GHz (contra 2,8 GHz da versão padrão) e a GPU Adreno 640 trabalha a 672 MHz, mais que os 585 MHz de costume. Além disso, a Asus colocou uma tela AMOLED de 6,59 polegadas Full HD+ (2340×1080 pixels) com taxa de atualização de 120 Hz e alta precisão de cores.
O ROG Phone II é maior e mais pesado que a maioria dos celulares à venda: tem 9,5 mm de espessura e 240 gramas. Ele abriga uma bateria enorme de 6.000 mAh com carregamento rápido de 30 watts, além de câmeras traseiras similares às do Zenfone 6 (48 megapixels na principal e 13 megapixels na ultrawide), mais um sensor frontal de 24 megapixels (f/2,0) para selfies.
O leitor de impressões digitais fica na própria tela. Na traseira, há um LED que ilumina a marca Republic of Gamers, mas que pode ser desativado. E o Android 9.0 Pie roda uma interface diferente, a ROG UI, com ícones personalizados para o público gamer — a qualquer momento, você pode alternar para a ZenUI, que ficou visualmente mais próxima do Android puro.
Dois modelos estão disponíveis no Brasil:
- ROG Phone II com 8 GB de RAM e 128 GB de espaço: R$ 4.999 (R$ 4.499 à vista)
- ROG Phone II com 12 GB de RAM e 512 GB de espaço: R$ 7.299 (R$ 6.499 à vista)
Também há acessórios para o ROG Phone II. O mais completo é o ROG Dock Module: ele permite conectar o celular a um monitor 4K, mouse, teclado e conexão Ethernet, por R$ 2.999. Já o ROG Station Module adiciona uma segunda tela, um cooler para resfriar o aparelho e uma bateria extra de 5.000 mAh por R$ 1.999.
Asus ROG Phone II – ficha técnica
- Tela: AMOLED de 6,59 polegadas com resolução Full HD+ (2340×1080 pixels) e proteção Gorilla Glass 6;
- Processador: Qualcomm Snapdragon 855 Plus octa-core de até 2,96 GHz;
- RAM: 8 ou 12 GB;
- Armazenamento: 128 ou 512 GB (com expansão por microSD de até 2 TB);
- Câmeras traseiras:
- Principal: 48 megapixels (f/1,79);
- Ultrawide: 13 megapixels (f/2,4);
- Câmera frontal: 24 megapixels (f/2,0);
- Bateria: 6.000 mAh com carregamento rápido de 30 watts;
- Sistema operacional: Android 9.0 Pie;
- Dimensões: 171x78x9,5 mm;
- Peso: 240 gramas.
‘);
// Chama o script do Facebook
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = “http://connect.facebook.net/pt_BR/sdk.js#xfbml=1&version=v2.9&appId=170493007795”;
fjs.parentNode.insertBefore(js, fjs);
}(document, ‘script’, ‘facebook-jssdk’));
});