;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

"Bateu desespero", diz Boulos sobre ataques da campanha de Covas

Nathan Lopes

Do UOL, em São Paulo

18/11/2020 13h28

O candidato do PSOL a prefeito de São Paulo, Guilherme Boulos, criticou os ataques contra ele feitos pela campanha de seu adversário, Bruno Covas (PSDB). "Bateu um certo desespero", disse Boulos hoje em agenda no centro de São Paulo, em um ato que, mais uma vez, gerou aglomeração em meio à pandemia.

O candidato fez menção a um comentário do ex-deputado federal Ricardo Tripoli (PSDB), integrante da campanha de Covas. Tripoli disse que Boulos "mata a mãe para ir ao baile de órfãos". A referência seria ao fato de o candidato do PSOL ter deixado sua casa para viver com membros de movimento social.

Covas pediu desculpas ao adversário por mensagem pela fala do colega de partido.

"Uma coisa que me deixou surpreso no início desse segundo turno é a raiva da campanha do Bruno Covas", disse Boulos, que voltou a citar o discurso do tucano pós-apuração em que Covas fala sobre derrotar o radicalismo, em uma referência velada ao candidato do PSOL.

"E esse caso do Tripoli não foi um caso isolado. Eu prefiro nem comentar pela baixeza, pelo desrespeito", disse.

Aglomeração na pandemia

Hoje, Boulos fez uma caminhada do Mosteiro de São Bento ao Theatro Municipal. Ele estava acompanhado de Jilmar Tatto (PT) e Orlando Silva (PCdoB), derrotados no primeiro turno e que levaram suas respetivas militâncias. A concentração de pessoas desrespeitou, mais uma vez, o distanciamento social em uma agenda de Boulos.

Questionado, Boulos disse que sua campanha está tomando os cuidados necessários. "Tem equipe orientando o distanciamento. A gente não tem feito uma convocação pelas redes sociais para as agendas. Quem tem vindo é a militância."

O candidato, porém, voltou a citar que deve fazer uma grande festa em frente à sede da prefeitura em 1º de janeiro caso seja eleito.

Apoios

Tatto e Orlando discursaram no final da caminhada. O petista, que foi o mais pressionado por alguns petistas a declarar apoio a Boulos e desistir de sua candidatura, disse que esta será a primeira vez que membros do partido não votarão 13 em uma eleição na capital paulista.

"Em defesa da democracia, este movimento não é partidário", disse Tatto. "Por isso que, agora, é Boulos."

Outros apoios devem ser anunciados. O PDT, que apoiou Márcio França (PSB), conversa com a direção do PSOL hoje à tarde.

Sobre França, Boulos disse que há espaço para ele na frente que está montando. "Tem espaço para todo mundo que quer uma cidade que seja referência democrática contra o atraso do bolsonarismo e que seja referência social contra o elitismo dos tucanos."