text:
Delta-v Capital Welcomes Six Degrees to its Portfolio
Delta-v Capital is excited to announce its recent investment in Six Degrees, a leading cloud-led managed service provider to UK enterprises. Rand Lewis, Delta-v Managing Partner, will assume a board observer role alongside Delta-v Advisor, Ken desGarennes, who serves as Chairman of the Board.
Six Degrees is a collaborative technology partner to businesses making a digital transformation. Ranging from data and application performance management to colocation and unified communication, Six Degrees' solutions are supported by its own data centers, network infrastructure, and cloud capabilities. The Company's ability to deliver a comprehensive IT solution makes Six Degrees the preferred digital transformation partner for businesses across retail, legal, manufacturing, finance, and the public sector.
In partnership with Charlesbank Capital Partners, Delta-v's financing supported Six Degrees' acquisition of the award-winning cybersecurity services and consultancy business CNS Group. CNS's portfolio of consultancy, compliance, and managed security services will enhance Six Degrees' existing cybersecurity offering and management of its clients' increasingly complex security challenges. "Existing clients want to place more of their IT estate with us, and security is a vital part of the picture," said David Howson, CEO of Six Degrees. "CNS Group's loyal client base, serviced by a strong management team and talented staff, provides the perfect fit to enable Six Degrees to offer a broader set of cyber security services."
"We are thrilled to partner with the Six Degrees management team and Charlesbank as they continue to execute on their cloud-led vision," said Rand Lewis, Managing Partner of Delta-v Capital. "The acquisition of CNS further cements Six Degrees' leadership in today's fragmented UK market and positions the group as the natural partner for enterprises undergoing a digital transformation."
Founded in 2010, Six Degrees is headquartered in Central London with circa 450 people spread over 5 UK offices.
About Delta-v Capital
Delta-v Capital is a leading provider of liquidity solutions and growth equity to private technology companies and their shareholders. Founded in 2009 with a focus on providing secondary liquidity to minority investors, the firm has since expanded its scope to include growth equity to support growth-stage technology companies. Delta-v manages over $500 million in capital commitments and targets between $3 and $30 million investments in technology sectors, including enterprise software, information services, cybersecurity, data analytics, cloud, and communications infrastructure. Delta-v has offices in Boulder, CO and Dallas, TX.
About Charlesbank Capital Partners
Based in Boston and New York, Charlesbank Capital Partners is a middle-market private equity investment firm managing more than $5 billion of capital. Charlesbank focuses on management-led buyouts and growth capital financings and also engages in opportunistic credit investments. The firm seeks to partner with strong management teams to build companies with sustainable competitive advantage and excellent prospects for growth.


text:
Véu de Verônica ou Sudário ("lenço para enxugar o suor" em latim), (diferente do Sudário de Turim) chamado geralmente apenas de "A Verônica" e conhecido na Itália como "Volto Santo" ("Santa Face"), é uma relíquia católica sendo um véu que, segundo a tradição Católica Apostólica Romana, tem gravado em si a aparência de Jesus e que não foi produzido por mãos humanas (ou seja, um dos acheiropoieton). Várias imagens ainda existentes reivindicam ser a relíquia "original" (ou serem cópias primitivas), mas algumas lendas e suposições históricas que permeiam a história faz com que haja muito menos pessoas, mesmo entre católicos tradicionais, que defendem a autenticidade da relíquia de forma séria, principalmente quando se compara com a defesa do Sudário de Turim.

A tradição ocidental conta que Santa Verônica de Jerusalém encontrou Jesus quando ele vinha carregando a cruz pela Via Dolorosa em direção ao Calvário. Quando ela parou um instante para limpar-lhe o sangue e suor do rosto (sudor em latim) com seu véu, seu semblante teria ficado impresso no tecido. O evento é comemorado na sexta estação das estações da cruz. De acordo com algumas versões, Verônica teria depois viajado à Roma para presentear o véu ao imperador romano Tibério e, ainda segundo esses relatos, o véu teria diversos poderes milagrosos, como o de aliviar a sede, curar a cegueira e até mesmo o de ressuscitar os mortos.

Contudo, esta história só adquiriu seu formato atual na Idade Média e, por isso, é muito improvável que seja verdadeira. É mais provável que sua origem esteja relacionada com a história da imagem de Jesus na Igreja Ortodoxa, a da relíquia conhecida como Mandílio ou Imagem de Edessa, somada a um desejo dos fieis de verem a face de seu salvador. No Século XIV, o véu tornou-se um ícone central na Igreja Ocidental — nas palavras do historiador da arte Neil Macgregor: "Daí (Século XIV) em diante, onde fosse a Igreja romana, a Verônica ia também".

História
Não existem referências à história de Verônica e seu véu nos evangelhos canônicos e todo o relato deriva de séculos de tradição. A referência mais próxima é o milagre de Jesus curando a mulher com sangramento, no qual ela é curada ao tocar a barra do manto de Jesus (). A mulher foi posteriormente identificada como sendo Verônica pelo apócrifo "Atos de Pilatos". Depois, a história foi novamente aumentada no  pelo relato de que Jesus teria presenteado a mulher com um retrato de si mesmo num tecido, o mesmo que depois ela utilizaria para curar Tibério. A ligação da lenda com o carregamento da cruz durante a Paixão e a história do aparecimento milagroso da imagem no tecido foi obra da "Bíblia em Francês" de Roger d'Argentuil no Século XIII e esta versão tornou-se ainda mais popular depois da publicação da obra internacionalmente popular "Meditações sobre a Vida de Cristo" por volta de 1300 por um autor Pseudo-Boaventurano. Foi a partir daí que as representações artísticas da obra mudaram para incluir também a coroa de espinhos, sangue e a expressão de um homem em intenso sofrimento. A imagem passou a ser bastante comum por toda a Europa católica, passando a integrar as Arma Christi; o encontro de Jesus e Verônica tornou-se uma das estações da cruz, presente em todas as igrejas católicas.

Na Via Dolorosa, em Jerusalém, há uma pequena capela conhecia como "Capela da Santa Face" no local onde tradicionalmente se considera que estava a casa de Santa Verônica e onde o milagre teria ocorrido.

De acordo com a Enciclopédia Católica, o nome "Verônica" é um portmanteau popular da palavra latina "vera" ("verdadeira", como em Vera Cruz), e a grega "icon" ("imagem"); por isso, o Véu de Verônica era amplamente considerado durante a Idade Média como a "verdadeira imagem" e a representação mais fiel da face de Jesus, muito antes do Sudário de Turim.

História do véu
Não há dúvida que uma imagem estava abrigada em Roma nos séculos XIII, XIV e XV conhecida e venerada como "Véu de Verônica". Porém, a história desta imagem é bastante problemática.

Geralmente se assume que a Verônica estava abrigada na antiga Basílica de São Pedro durante o papado de João VII (705-708), pois uma capela conhecida como "capela de Verônica" foi construída na época; autores posteriores também assumiam assim. Porém, não é possível ter certeza alguma disso, pois os mosaicos que decoravam a capela não fazem referência alguma à história de Verônica. Além disso, escritores contemporâneos não fazem referência à Verônica neste período. Porém, é provável que a relíquia estava ali por volta de 1011, quando um escriba foi identificado como sendo seu guardião.

Porém, registros seguros sobre a Verônica só aparecem em 1199, quando dois peregrinos chamados Gerald de Barri (Giraldus Cambrensis) e Gervásio de Tilbury escreveram, em tempos diferentes, sobre suas visitas a Roma citando diretamente a relíquia. Logo depois, em 1207, o tecido ganhou importância depois de ser paradeado ao público pelo papa Inocêncio III, que também concedeu indulgências a quem rezasse diante dela. Esta procissão, entre a Basílica de São Pedro e o Hospital do Santo Spirito, tornou-se um evento anual e, num deles, em 1300 o papa Bonifácio VIII, que a transladou para a Basílica em 1297, teve a ideia de proclamar o primeiro Jubileu no mesmo ano. Durante o jubileu, a Verônica foi apresentada para os fieis e tornou-se uma das mirabilia urbis ("maravilhas da cidade") para os peregrinos que visitavam Roma. Pelos duzentos anos seguintes, a Verônica, abrigada em São Pedro, foi considerada a mais preciosa de todas as relíquias cristãs. Foi ali que Pedro Tafur, um visitante espanhol em 1436, escreveu:

Depois do saque de Roma de 1527, alguns autores relatam que o véu teria sido destruído: Messer Unbano, escrevendo para a duquesa de Urbino, conta que a Verônica foi roubada e estava passando de mão em mão nas tavernas de Roma. Porém, outros afirmam que ela teria continuado no Vaticano e uma testemunha do saque afirma que ela não foi encontrada pelos saqueadores.

Muitos artistas da época criaram reproduções da Verônica, o que também sugere que ela teria sobrevivido ao saque. Mas, em 1616, o papa Paulo V proibiu a criação de novas cópias, exceto se fossem produzidas por clérigos da Basílica de São Pedro. Em 1629, o papa Urbano VIII não apenas proibiu as reproduções como também ordenou a destruição de todas as cópias existentes. Seu édito declarou que todos os que tinham cópias deveriam levá-las para o Vaticano sob pena de excomunhão.

Depois disso, a Verônica desapareceu completamente da vista dos fieis e sua história não foi preservada. Como não existem evidências conclusivas de que ela tenha deixado a Basílica de São Pedro, é provável que lá esteja até hoje, o que também é consistente com as poucas informações dadas pelo Vaticano nos séculos recentes.

Imagens tradicionalmente ligadas ao Véu de Verônica

Há pelo menos seis imagens que, além da semelhança que têm entre si, alegam serem ou a Verônica original ou uma cópia primária dela (e não uma "cópia da cópia") ou, em dois casos, a Imagem de Edessa. Todas estão fechadas por elaboradas molduras e cobertas por lâminas metálicas banhadas a ouro, através da qual, por uma abertura, aparece a face.

Basílica de São Pedro
Na Basílica de São Pedro certamente está uma imagem que se alega ser a mesma reverenciada durante a Idade Média. Ela está abrigada numa capela atrás da sacada do pier sudoeste da cúpula.

Há pouquíssimos relatos de inspeções em tempos modernos e não existem fotografias detalhadas. A mais rigorosa inspeção no objeto ocorreu em 1907, quando o historiador da arte jesuíta Joseph Wilpert recebeu permissão para remover duas camadas de vidro para inspecionar a imagem. Ele comentou que viu apenas "um pedaço de um material levemente colorido, um pouco desbotado por causa da idade, com duas leves manchas de marrom-ferrugem ligadas entre si".

Apesar disso, ela ainda é apresentada anualmente aos fiéis durante o quinto domingo da Quaresma, o Domingo da Paixão. A bênção  ocorre depois das vespertinas tradicionais, às 5:00 da tarde, na qual uma curta procissão pela Basílica ocorre enquanto se recita a litania romana. Um sino toca e três canônicos seguram a pesada moldura na sacada acima da estátua de Santa Verônica. Desta distância, nada se vê da imagem em si e apenas o contorno da moldura interna é visível.

Palácio Hofburg, Viena
Esta é uma importante cópia da Verônica, identificada pela assinatura de P. Strozzi no canto direito da moldura interior. Ele era o secretário do papa Paulo V e uma pessoa que o notário do Vaticano Jacopo Grimaldi relata ter feito uma série de seis cópias detalhadas do véu em 1617.

O lado de fora da moldura é relativamente moderno enquanto que o interno é pouco trabalhado, correspondendo ao formato vazado das primeiras cópias. A face em si é pouco clara, correspondendo mais a uma série de manchas na qual apenas os mais primais elementos de um nariz, olhos e uma boca podem ser identificados. Esta falta de clareza é um forte argumento pela autenticidade da obra, pois claramente não houve tentativa alguma de melhorar a imagem artisticamente. Além disso, o fato de a cópia ter sido feita a partir da Verônica no Vaticano sugere que a relíquia de fato sobreviveu ao saque de 1527.

A cópia está abrigada no Schatzkamme dos Tesoureiros Sagrados e Seculares da dinastia Habsburgo no Palácio Hofburg de Viena, na Áustria.

Mosteiro da Santa Face, Alicante, Espanha
Esta relíquia foi adquirida pelo papa Nicolau V de parentes do imperador bizantino em 1453, durante a queda de Constantinopla. Ele foi cedido por um cardeal a um sacerdote espanhol, Mosen Pedro Mena, que o levou para Alicante, no sul da Espanha, onde ela chegou em 1489 durante uma prolongada seca. Carregada em procissão em 17 de março pelo padre Villafranca, uma lágrima rolou dos olhos da face de Cristo no véu e imediatamente começou a chover. A relíquia está hoje no Mosteiro da Santa Face (Monasterio de la Santa Faz), nos arredores de Alicante, e está abrigada numa capela construída em 1611 e decorada entre 1677 e 1680 pelo escultor José Vilanova, pelo dourador Pere Joan Valero e pelo pintor Juan Conchillos. A capela está decorada com pinturas representando o milagre da seca, personalidades locais ligadas à fundação da capela e temas religiosos sobre o Juízo Final e a Salvação. O mosteiro sofreu uma grande reforma entre 2003 e 2006 juntamente com a Catedral de São Nicolau e a Basílica de Santa Maria, no centro da cidade, a os três edifícios realizaram uma grande exibição em 2006 sobre a relíquia chamada "A Face da Eternidade".

Catedral de Xaém, Espanha
A Catedral de Xaém abriga uma cópia da Verônica originária de Siena e que data provavelmente do Século XIV. Ela é mantida num santuário no altar-mor e é exibida anualmente aos fieis na Sexta-Feira Santa e na Festa da Assunção. Conhecida como "Santo Rostro", foi adquirida pelo bispo Nicolau de Biedma no Século XIV.

Imagens similares

Santa Face de Gênova
Mantida na modesta Igreja de São Bartolomeu dos Armênios, em Gênova, ela foi presenteada no Século XIV ao doge Leonardo Montaldo pelo imperador bizantino João V Paleólogo.

A imagem foi estudada em detalhes em 1969 por Colette Dufour Bozzo, que datou a moldura exterior no Século XIV; a moldura interior e a imagem em si, ela acredita que sejam anteriores. Bozzo descobriu ainda que a imagem foi impressa num tecido que havia sido colado numa prancha de madeira. A semelhança com a Verônica sugere que as duas tradições devem ter alguma ligação entre si.

Santa Face de San Silvestro
Esta imagem estava abrigada na igreja romana de San Silvestro até 1870 e está hoje na "Capela Matilda" no Vaticano. Ela está dentro de uma moldura barroca doada por uma tal irmã Dionora Chiarucci em 1623. A mais antiga evidência sobre sua existência é de 1517, quando as freiras foram proibidas de exibirem-na para evitar a competição com a Verônica. Assim como a imagem de Gênova, ela foi pintada numa prancha de madeira e, portanto, trata-se de uma cópia.

Imagem de Manoppello

Em 1999, o jesuíta alemão Heinnrich Pfeiffer, professor de História da Arte na Universidade Pontifícia Gregoriana, anunciou, numa coletiva de imprensa em Roma, ter encontrado o Véu de Verônica numa igreja de um mosteiro capuchinho na pequena vila de Manoppello, onde ele estaria desde 1660. É fato, porém que Pfeiffer já vinha defendendo a autenticidade desta imagem antes disso. De acordo com a tradição local, um peregrino anônimo chegou à cidade em 1506 com o tecido embrulhado num pacote e o deu ao doutor Giacomo Antonio Leonelli, que estava sentado num banco em frente à igreja. O doutor entrou na igreja e abriu o pacote e imediatamente saiu em busca do peregrino, mas não o encontrou. O véu esteve entre as posses da família Leonelli até 1608 quando Pacrazio Petrucci, um soldado casado com uma das filhas da família, Marzia Leonelli, roubou-o da casa de seu sogro. Alguns anos depois, Marzia vendeu-o por 400 scudi ao doutor Donato Antonio De Fabrtiis para arrecadar fundos para pagar o resgate de seu marido preso em Chieti. O véu foi então presenteado pelos De Fabritiis aos capuchinhos, seus atuais proprietários. Esta história foi documentada pelo padre Donato de Boma em sua "Relatione Historica" depois de suas pesquisas iniciadas em 1640.

Segundo constata o Pe. Pfeiffer, alemão, mesmo apesar de fontes incertas, que se encontram já no século IV, a história do Véu da Verônica está presente através dos séculos na tradição católica. Em seu filme «Jesus de Nazaré», o diretor de cinema Franco Zeffirelli a recolhe.

Por ocasião do primeiro ano santo da história, no ano 1300, o Véu da Verônica converteu-se em uma das «Mirabilia urbis» (maravilhas da cidade de Roma) para os peregrinos que puderam visitar a Basílica de São Pedro no Vaticano.

Confirma o maior poeta da história da Itália, Dante Alighieri (1265-1321), no canto XXXI do «Paraíso» (versículos 103-111) na «Divina Comédia».

As marcas do véu da Verônica se perderam nos anos sucessivos ao Ano Santo 1600, quando o véu foi encontrado em Manoppello. O Pe. Pfeiffer explica que no véu de Manoppello, na margem inferior, pode-se ver ainda um pequeno fragmento de vidro do relicário anterior, o que demonstraria sua procedência do Vaticano.

Segundo a «Relação Histórica», escrita em 1646 pelo sacerdote capuchinho Donato de Bomba, em 1608 uma senhora, Marzia Leonelli, para tirar seu marido da prisão, vendeu por 400 escudos o Véu da Verônica, que havia recebido como dote, a Donato Antonio de Fabritius. Dado que a relíquia não se encontrava em boas condições, Fabritius a entregou em 1638 aos padres capuchinhos de Manoppello.

Frei Remigio da Rapino recortou os cantos do Véu e o colocou entre duas molduras de madeira. As molduras e os vidros são o que ainda hoje conservam o véu em Manoppello.

Esta relação, da qual não há outras provas históricas, diverge da reconstrução do Pe. Pfeiffer, narrando a história popular da chegada do ícone aos Abruzos, das mãos de um peregrino, em 1506. Até 1638, o ícone teria passado por várias mãos. Com a criação desta lenda, opinam alguns dos investigadores, se poderia ter tentado ocultar o roubo do Vaticano.

O professor Donato Vittori, da Universidade de Bari, fez um exame do véu em 1997 com raios ultravioleta, descobrindo que as fibras não têm nenhum tipo de pigmentação. Ao se observar a relíquia com o microscópio, descobre-se que não está pintada e que não está tecida com fibras de cor.

Através de sofisticadas técnicas fotográficas digitais, pôde-se constatar que a imagem é idêntica em ambos os lados do véu, como se fosse um slide.

A iconógrafa Blandina Pascalis Shloemer demonstrou que a imagem do Santo Sudário de Turim se sobrepõe perfeitamente ao Santo Rosto de Manoppello (com mais de dez pontos de referência).

Representações na arte
Há duas tradições principais para a iconografia da face representada no Véu de Verônica. Uma (Tipo I), comum na arte italiana, mostra a face de Cristo barbada, sofrendo, cheia de feridas e provavelmente coroada com espinhos. Outra (Tipo II), comum na arte da Espanha e da Rússia, mostra a face de Cristo geralmente em repouso com o cabelo à altura dos ombros e uma barba bifurcada, geralmente rodeado por um halo cortado por uma cruz.

Ver também
 Acheiropoieta
 Imagem de Edessa
 Sudário de Turim
 Sudário de Oviedo

Bibliografia

 Joan Carroll Cruz, OCDS, Miraculous Images of Our Lord. ISBN 0-89555-496-8
 Ewa Kuryluk, Veronica and Her Cloth: History, Symbolism, and Structure of a True Image. ISBN 0-631-17813-9
 Ian Wilson, Holy Faces, Secret Places,Corgi, ISBN 0-552-13590-9

Ligações externas

Relíquias associadas a Jesus
Iconografia cristã
Termos cristãos

redpajama_set_name: RedPajamaWikipedia


Have you ever been struck by perfect silence? Phantom's revolutionary ADH® Intelligence achieves the impossible: zero background noise. From pure sound to absolute quiet, feel your music's every nuance. Playback at its most intense.
There's more to hear and feel. Engineered to take you deeper, Phantom's woofers power together under extreme pressure. Feel your body tremble as you travel to the edge of infrasound. Ultra-physical.


text:
'Glencairn Christmas' to deliver holiday magic virtually and in person
Bucks County Courier Times
BRYN ATHYN — Glencairn Museum will present its annual Christmas programs both virtually and in person.
"We are excited to share the joy of Christmas with our visitors as they safely immerse themselves in the beauty and majesty of Glencairn's Great and Upper Halls decorated for the holidays," says Brian Henderson, Glencairn's director.
"While many of our regular Christmas offerings will be presented digitally this Christmas, we hope that they can be enjoyed not only by those who have made Glencairn a part of their annual family holiday traditions, but by those who may live too far to be able to visit in person."
Two in-person events invite visitors to Glencairn over the holidays: a self-guided tour of the castle's first floor, decorated for Christmas much as the Pitcairn family might have in the first half of the last century; and a Bryn Athyn Historic District offering across three evenings in mid-December.
Here's a rundown of the events:
World Nativities: An Online Advent Calendar
Dec. 1 through Jan. 10. A new Nativity available at 10 a.m. daily, 12/1-12/25; view at GlencairnMuseum.org.
For this 12th year, Ed and Kirsten Gyllenhaal, Glencairn's husband-and-wife curatorial team, have put together an inspiring World Nativities online exhibition that's presented in the form of an Advent Calendar. Each day from Dec. 1 through Christmas Day, a "door" opens on Glencairn's website to reveal a new Nativity chosen from the museum's collection of 250 such depictions. These Nativities were crafted by artists from all around the globe who have used their unique cultural and spiritual viewpoints to bring the Christmas story to life.
"Discover Christmas at Glencairn" Self-Guided Tour
Nov. 27 through Jan. 10 (closed 12/24, 12/25 & 1/1); 60-minute tour slots daily at 12:30, 1:45 and 3 p.m. Registration required by 10 a.m. day of the tour; suggested donation, $5 per person.
Social distancing guidelines strictly followed; groups limited to 30; masks are required.
This is the only event in 2020 that gives visitors a live, in-person experience inside Glencairn at the holidays. The first floor is decorated much as it would have been when the Raymond and Mildred Pitcairn family celebrated in these halls with their children and grandchildren. Family heirloom pieces — some seen only rarely — have been brought from the collections and other areas of the castle.
'Christmas in the Castle' Online Holiday Tour
Begins Nov. 27; view at GlencairnMuseum.org
A new video invites viewers to journey back in time, to explore Pitcairn holiday traditions in the family's 20th-century castle. Through archival images and new photography, you'll experience the large three-part Winfred S. Hyatt Nativity scene, the decorated tree in the Great Hall that reached above the second-floor balcony, the dining table set for the Christmas feast and many examples of Nativity art and traditional décor with which the family celebrated this festive holiday.
Christmas Sing Concert
Members premiere: 7:30 p.m. Dec. 15; public can view starting at 7:30 p.m. Dec. 16. Access via social media channels & GlencairnMuseum.org.
This annual holiday concert has been turned into a special online program available to all. This unique and professionally created concert video features the "Glencairn Horns," other instruments and vocal soloists, readings of the Christmas story and musicians performing music familiar to generations of audiences.
Homeschool Days: Glencairn Christmas at Home
Available Dec. 1 – Jan. 1; access at GlencairnMuseum.org
The popular annual Christmas Homeschool Day Open House is going digital. All December, at any time, use the website's Christmas Homeschool link to "be there" in the Great and Upper halls, dive into Glencairn's multi-sensory Christmas Nativity Explorer's Notebook, make a Christmas craft, and more.
Landmarks in Lights for the Holidays
5 to 9 p.m. Dec. 17-19. Advance purchase parking pass required; $20/car or personal passenger van; $50/minibus (maximum capacity 15).
Stroll the grounds of the Bryn Athyn Historic District and see Bryn Athyn Cathedral, Glencairn Museum, and Cairnwood Estate adorned for the holidays and lit with hundreds of lights. Look for Cairnwood and Glencairn window displays and the Cathedral's stained-glass windows lit from inside. The Cathedral Cloister Garden features a new three-panel painting of the Christmas story by local artist Nancy Schnarr.
Hot drinks available for purchase at Cairnwood Estate, which is also opening its restrooms in the Garden House.

redpajama_set_name: RedPajamaCommonCrawl


Posted on November 13, 2016, in Uncategorized and tagged A+, BIOS, CompTIA, Linux, MacBook, Pearson, Review, study, Technology, Windows. Bookmark the permalink.	1 Comment.
I've just started preparing for the A+ exam last week, and was wondering, is knowing the frequency of RAM or other super specific questions necessary? Getting the big picture is not a problem for me, but as for the nitty gritty, I'm thinking if I need to understand it I'll have to make a bunch of Anki flashcards!


text:
Ancient DNA Maps Early American Migrations in New Detail
Genetic information from dozens of individuals living 700 to 10,000 years ago reveals connections between Clovis and Native Americans and South Americans.
Ashley Yeager
Ancient genomes reveal waves of migrations in the Americas.
POSTH ET AL./CELL
Early populations of humans in the Americas had the same ancestry as modern Native Americans, according to studies published today (November 8) in Cell and Science. The data dispel any ideas based on the skull shapes of a few ancient remains that early populations were not related to modern Native Americans and give more clues about the waves of people who migrated from North America to South America thousands of years ago.
The two studies combined analyzed the genomic data of more than 60 individuals who lived in the lands between Alaska and Patagonia 700 to 10,000 years ago. Because of the limited data prior to this work, "the [genetic] models that we've been using to explain the peopling of the Americas have always been oversimplified," Jennifer Raff, an anthropological geneticist at the University of Kansas in Lawrence who was not involved in the studies, tells Science. But adding genomes to the dataset allowed two teams, one led by Eske Willerslev, an evolutionary geneticist at the University of Copenhagen, and another by population geneticist David Reich of Harvard Medical School, to clarify the picture of how human populations moved about the Americas millennia ago.
Willerslev's data, reported in Science, show that "this is our homeland, these are our ancestors," Rochanne Downs, the cultural coordinator of the Fallon Paiute-Shoshone Tribe in Nevada, where the team collected some of the data, tells Science. Willerslev's team compared the genetic data of 10,700-year-old remains from the Spirit Cave, which the Fallon Paiute-Shoshone Tribe had been trying to repatriate, to that of 12,700-year-old remains from an Anzick child from Montana and found a related ancestry.
The child is considered part of what's known as Clovis culture, and the results in Science link Clovis culture to both the Spirit Cave individual—who is associated with a tradition older than Clovis culture—and to 10,000-year-old remains from Brazil. "A key discovery was that a Clovis culture-associated individual from North America dating to around 12,800 years ago shares distinctive ancestry with the oldest Chilean, Brazilian, and Belizean individuals," Cosimo Posth of the Planck Institute who coauthored the Cell study says in a media release. "This supports the hypothesis that the expansion of people who spread the Clovis culture in North America also reached Central and South America."
The result also "tells us that the peopling of Central and South America not only was fast but also it was accompanied by multiple waves, some of which disappeared and some others which left a strong genetic impact all the way until today," Posth tells Gizmodo.
ancient DNA
nutshell
Ancient Genomes Reveal Clues About Native Americans' Past
New Technique Maps RNAs in Cells Without a Microscope
Biologists Create New Maps of Caenorhabditis elegans Neurons
Ancient Microbe Migration


text:
Environmental Data to Empower Community-Driven Solutions
By Aclima on March 21 2019
Topics: Air Quality Public Health Asia Philippines
Air pollution is a global challenge, often faced most acutely in Asia. The World Health Organization has estimated that 92% of the Asia Pacific population — about 4 billion people — are exposed to levels of air pollution that pose a significant risk to health. India and China are home to some of the world's most polluted cities where the concentration of particulate matter often reaches hazardous levels; while Thailand recently became the focus of international attention as schools shut down in Bangkok due to toxic air.
This public health crisis is widespread, and Clean Air Asia, an international NGO, is on a mission to improve air quality in cities across Asia. A key step in achieving this goal is measurement to inform the public and key stakeholders on air pollution's effect on human and environmental health. Unfortunately, this is difficult when sparse, regional and local data can often have limited relevance or actionability for each of us at the personal level. Enter Aclima.
In March 2018, through our partner First Philippine Holdings, Clean Air Asia reached out to Aclima to map hyperlocal air quality in the Philippines, an effort linked to its Integrated Programme for Better Air Quality in Asia (IBAQ Programme). Together, we launched an air quality mapping campaign in Marikina City, a highly urbanized city in Metropolitan Manila, and a Clean Air Asia partner.
With Aclima's mobile mapping platform, we worked to provide a greater understanding of PM 2.5 pollution exposure for the public, especially commuters, and inform clean air action plans to ease pollution hotspots in Metro Manila. The effort was spearheaded by a consortium of non-profit, commercial, and research groups including Clean Air Asia, Marikina City Environment Management Office, Department of Environment and Natural Resources, First Philippine Holdings, Inc., Mitsubishi Motors Philippines Corporation, UP Institute of Environmental Science and Meteorology, ADMU Environmental Science Department and De La Salle University.
"We believed at first that air quality monitoring is such a simple activity, but we never knew that it can go as extensive as utilizing Aclima's mobile mapping platform. We were able to identify hotspots within the city, and that will be very crucial in the development or formulation of the Clean Air Action Plan (CAAP). Formulating a CAAP is really not that popular nowadays but it is very important — it's equally important with all other (city) plans."
- Ms. Gloria Buenaventura, Head of the Marikina City Environment Management Office
In November 2018, Marikina City and Clean Air Asia presented initial data findings from our mobile mapping campaign conducted from September to November 2018 at Clean Air Asia's 2018 Better Air Quality Conference in Kuching, Malaysia. The conference is the leading gathering of cities across Asia to share evidenced-based solutions to address air quality issues.
From left to right: Clean Air Asia Program Director Mr. Alan Silayan, MMPC Vice President for Corporate Public Relations Mr. Renato S. Lampano, Marikina City Councilor Hon. Serafin Y. Bernardino, City Environmental Officer Ms. Gloria Buenaventura, First Gen Corp VP for Business Development Mr. Aloysius Santos, DENR Central Office Engr. Jaime Jacobo and DENR Air Quality Management Engr. Jundy Del Socorro.
The presentation described the mapping campaign, where an Aclima-enabled vehicle mapped Marikina from September 24th to November 10th. Two different mapping strategies were carried out: one with a set route that included the major roads of Marikina and neighborhoods near the boundary of the city, and another mapped two Barangays (neighborhoods) in the northeast region of the city. From September 24th to October 24th, mapping occurred between 8 a.m. and 5 p.m., typical work hours, and captured pollution due to emissions from businesses and daytime traffic. From October 27th to November 10th, mapping was divided between the hours of 5 a.m. to 8 a.m. and 5 p.m. to 9 p.m. These two time windows capture morning and evening commute times as well as restaurant, home cooking, and other evening sources of pollution. During this part of the campaign, we used an electric vehicle provided by Mitsubishi.
The maps below resulting from the campaign show median PM2.5 concentrations (in 𝜇g/m3) for individual road segments 100m in length. This median value is calculated from all drives of each segment over the course of the study to arrive at a statistically representative map. The results show a wide range in values along the roads and across the city. The highest concentrations, indicated by the brightest red road segments, reflect how localized air pollution hot spots can be. Many of these hot spots occur on major roads in the city.
Aclima mapping results from air quality measuring in City of Marikina, Philippines. Color scale represents median PM2.5 concentrations (in 𝜇g/m3) for individual road segments 100m in length. Source: Aclima
Visual comparison of the two maps shows that, in general, levels measured during the daytime hours (8 a.m. to 5 p.m.) are lower than those measured during the early morning and evening time periods. The map for this time period simply looks redder overall. PM2.5 concentrations measured during daytime hours ranged from 21 to 108 𝜇g/m3, while those measured in morning and evening varied from 32 to 230 𝜇g/m3. The average concentration for the morning and evening hours was 66 𝜇g/m3, a significant difference compared to the daytime value of 44 𝜇g/m3.
The maps demonstrate the power of Aclima's platform to reveal how varied air pollution can be across a city, one block to the next, and at different times of day. It also proves to be effective at identifying pollution sources. Both of the maps show patterns in the distribution of pollutant concentrations that reflect nearby sources. The differences between the two time periods can help understand when emissions from these sources are highest, and can help distinguish between sources based on how their emissions are expected to vary with time.
With Aclima's unique block-by-block air quality mapping and visualization tools, Clean Air Asia and the local community were able to identify significant emission sources using their local knowledge of the city. These hyperlocal air quality reports have led to a better understanding of exposure to residents and commuters, and are being used to develop the city's Clean Air Action Plan to reduce air pollution hotspots, such as "no car zones" in school or recreation areas. Combining our measurements of the physical environment with contextual local knowledge gives communities a richer picture of air quality issues in their region.
We're excited to return to Marikina, and continue supporting Clean Air Asia with their work in the Philippines and throughout Asia, as our partnership expands. The flexibility of our platform and the insights it provides are essential new tools for air quality management and pollution reduction. With every new community using our platform, we make meaningful progress towards improving the health of our environment and our communities.
To find out how we can support your city or your community, get in touch at communities@aclima.io.
Sensing Wildfire Smoke at the Street Level
Exciting Announcements from Aclima at Google Cloud Next 2019


.. but I'm trying to stimulate myself into working here, so I'll post what I have.
I've been playing with SS3, translating some of my designs from SS2. This one has no appreciable differences from the SS2 version.
It might be for Navalism someday, but 1912 is a long way off. Ottoman dreadnaught using Navalism calibres but not particularly radical for Navalism. The intriguing feature is twin mount secondaries. Your thoughts?
The belt armour is rather extreme for the period. A 250mm - 300mm plate would be more likely.
Ammunition load is quite high at 160rpg. More standard would be 100rpg.
Probably want more beam if mounting the 150mm guns in twins.
Tweaked version - had to rejigger lots of stuff to keep seakeeping reasonable. Freeboard looks interesting - I love SS3's graphical display.


Amp is in excellent condition and comes with a hotcovers padded cover. I also have an AC30HW2X and tend to use that over the 15 so keeping both is overkill.
Wonderful amps these. If I didn't have one already, I'd be tempted. GLWTS.
Ah that's a shame. I'm in west London.


text:
L'USS Bowfin (SS/AGSS-287) est un sous-marin de classe Balao en service dans l'United States Navy pendant la Seconde Guerre mondiale. Depuis les années 1980, le sous-marin est un National Historic Landmark, conservé comme mémorial et navire musée dans la base de Pearl Harbor, à Hawaï.

Sa quille est posée le  au chantier naval Portsmouth Naval Shipyard de Kittery, dans le Maine. Il est lancé le , parrainé par Mme Jane Gawne (épouse du capitaine James Gawne); et mis en service le  sous le commandement du commander Joseph H. Willingham.

Historique
Le Bowfin quitta New London le  et arriva à Brisbane, en Australie, le . Entre le  et le , le submersible effectua neuf patrouilles de guerre, opérant des Indes néerlandaises à la mer du Japon et dans les eaux au sud de Hokkaido.

Lors de ses missions, il coula 15 navires marchands et une frégate pour un total de  tonnes, partageant également le naufrage d'un navire marchand de  tonnes avec l'.

Rejoignant Pearl Harbor , le Bowfin navigua vers la côte est en arrivant à Staten Island le . Il opéra avec la flotte de l'Atlantique jusqu'à son retrait du service le .

Remis en service pour soutenir les forces dirigées par l'ONU pendant la guerre de Corée, le sous-marin est de nouveau opérationnel le . Après deux ans d'entraînement et d'exercices locaux, le sous-marin rejoint les États-Unis à la fin de la guerre de Corée à l'été 1953, arrivant à San Francisco le  et de nouveau placé en réserve au chantier naval de Mare Island le .

En , il sert de sous-marin d'entraînement dans l'United States Navy Reserve, avant d'être rayé du Naval Vessel Register le . Remorqué à Hawaï le , le submersible est conservé comme mémorial et navire musée dans la base de Pearl Harbor. Il est amarré à proximité du centre d'accueil du mémorial de l'USS Arizona.

Le Bowfin est déclaré monument historique national en 1986.

Dans la culture populaire
Le Bowfin est l'un des plusieurs sous-marins (avec les , , , et ) dont les patrouilles de guerre peuvent être reconstituées dans le jeu Silent Service de MicroProse en 1985 et dans les différents ports du jeu, dont le système de divertissement Konami, sortie sous la Nintendo Entertainment System.

Notes et références

Voir aussi

Articles connexes
 Guerre du Pacifique
 Liste des sous-marins de l'United States Navy
 Liste des navires coulés par sous-marins par nombre de morts
 Registre national des lieux historiques
 Liste des bateaux-musée
 Liste des musées à Hawaï

Liens externes

 US Submarines in World War II
 USS Bowfin Submarine Museum and Park
 Kill record: USS Bowfin

Bateau lancé en 1942
Classe Balao
Navire construit à Kittery
Sous-marin de l'US Navy de la Seconde Guerre mondiale
Bateau de guerre de la Seconde Guerre mondiale
Navire musée à Hawaï
Bateau de l'US Navy de la guerre de Corée
Sous-marin classé National Historic Landmark
Registre national des lieux historiques à Honolulu
Registre national des lieux historiques en 1982
National Historic Landmark à Hawaï
National Historic Landmark en 1986
Musée militaire aux États-Unis
Musée maritime aux États-Unis
Sous-marin de l'US Navy de la guerre froide


text:
May 1, 2018 By OLIVIA DENG
JAMMED UP
Is Boston cycle infrastructure getting better faster than congestion gets worse?
Matt bikes daily.
He says that one of those days last summer, while biking past the Harvard Coop in Cambridge, he saw a car with an Uber sign parked in the bike lane.
When he began to steer around the Uber, the car almost drove into him and another cyclist.
"So I knocked on their window and yelled 'bike lane.' They were going to drive right into us. She threw a water bottle at me and then tried to drive off, but there's too much traffic. So I caught up, and now I'm next to her. Now I'm angry and I yelled, 'What the hell, you threw a water bottle at me.' I smacked her rearview mirror, which I'm not proud of. I started to ride away then she drove her car pedal to the metal as if she was going to run me over."
Crowded roads, cars obstructing bike lanes, and road rage are all challenges cyclists deal with in Greater Boston. While the city of Boston plans to increase biking as a form of daily transportation by four times by 2030, problems like road congestion, inadequate infrastructure, and negative driver-cyclist interactions can impede further adoption of biking and make biking more hazardous for current cyclists.
Are things getting better? Could they possibly get worse?
The number of people living in Boston proper alone is projected to increase from 656,000 in 2014 to 724,000 in 2030. According to transportation analytics company INRIX, Boston is the seventh most congested city in the United States. Residents already feel the strain of the population growth in housing and transportation. With a notorious lack of investment in public transportation and an increasing number of cars on the road, cyclists can run into physical as well as figurative roadblocks.
"Right now, our transit system can't handle the number of people," said Becca Wolfson, executive director of the Boston Cyclists Union. According to Wolfson, Boston's public transportation system is at capacity, forcing commuters to seek alternatives. She continued: "We need massive investment in public transit. More trains and buses with better frequency on our streets that would allow people to not rely on cars and ridesharing services that maybe are more convenient for people and the cost isn't that high, but it is actually making the congestion on our streets and travel times much worse."
According to a study by the Metropolitan Area Planning Council, more people are turning to ridesharing services to get from one place to another. Their survey found that 42 percent of passengers would have used public transportation if ridesharing services did not exist, while 12 percent would have walked or biked. Fifty-nine percent of ridesharing trips add additional cars to the roads.
"Biking is a great way to get people out of cars and provide alternatives," said Wolfson, adding that the greater road congestion due to ridesharing increases threats for bikers. "But there's a significant number of people in the population that just won't try it because they don't think they're safe."
Amanda Rychel, a cyclist who bikes daily to and from work and to pick up her son after school, said that the frustration from drivers being stuck in traffic worsens their attitude toward cyclists. "I think the thing that probably gets people most worked up, from being behind the wheel sometimes myself, is being stuck in traffic and being really frustrated by that," Rychel said. "I think people take their frustrations out on you when they're feeling like they can't get where they need to go."
Experts say that better cycling infrastructure can help alleviate problems cyclists face on congested roads. Wolfson's group specifically points to Boston thoroughfares like Mass Ave, Comm Ave, Tremont Street, Malcolm X Boulevard, and Cambridge Street as some of the most dangerous areas to bike.
"By not having safer infrastructure, we're missing out on a significant number of people who could start riding bikes and relieve congestion from cars and the T," Wolfson said.
"Comm Ave had the highest rate and number of dooring crashes, more than anywhere else in the city," Wolfson said. "That's when someone … getting out of a parked car opens the door and hits a cyclist. Those are really dangerous because you can be thrown under a vehicle immediately."
Stacey Thompson, coalition member of Vision Zero Boston, said that bike lanes benefit all commuters, not just those cycling.
"You put in a really great bike lane, it often makes it safer for people walking because people are trying to bike on sidewalks where young people and older people can be injured by someone cycling," Thompson said. "It makes it much safer for the cyclist who doesn't want to be on the street with a fast-moving motor vehicle and also helps slow down people in motor vehicles. We know that speed is a major factor in crashes that kill people. Putting in good cycling infrastructure is better for everyone on our streets."
Go Boston 2030, the city of Boston's transportation plan, includes installing safer bike lanes. Vineet Gupta, director of policy and planning at Boston Transportation Department, said that the city has substantially increased the number of bike lanes in Boston, including protected bike lanes.
"We recently completed the installation of a protected bike lane on Beacon Street [and are] maintaining efficient traffic flow along the corridor," Gupta said. "There are examples where we created protected bike lanes. A good example is in the North End. Protected bike facilities continue through Causeway Street through TD Garden. … Working with the community, we are confident we can find the right balance to make it safer for cyclists while maintaining traffic on congested roads."
Advocates want more. According to Thompson, there is an equity gap in where bike lanes are located. She pointed to the protected bike lane in the Back Bay section of Mass Ave, as compared to the infrastructure on the stretch of Mass Ave in Dorchester.
"While we would say the overall protected infrastructure is lacking in Boston, it's particularly bad in under-resourced communities [Roxbury, Mattapan, and Dorchester] where many people bike, especially when they have jobs in off hours when the T doesn't service them, or they're trying to get to areas of the city that are maybe more difficult to reach," Thompson said. "There's certainly work that's being done at the city, but we are really wanting to look at the communities with [lacking] biking infrastructure and say, 'There are lots of people in these communities who bike. They might not look like a white guy in spandex, but they deserve to get great protected infrastructure.'
"I think you're seeing an overall street safety deficit in some of these under-resourced communities and communities of color."
Wolfson said that despite certain improvements to bolster cycling safety, the pace of change is sluggish. "There are a couple signature projects that are great or will be great when they're done, but they're happening at a pace that's just glacial and isn't going to do anything to encourage enough people to start biking because you have some good projects but they are not networked to other facilities."
Wolfson is referring to bike lanes along major roads that are not connected to bike lanes on other roads.
"Mass Ave, from the Mass Ave Bridge to Symphony Hall in the South End direction, you're pretty much separated from traffic, which is great. But whatever street you turn onto, you are not separated from traffic, and that separation ends. What we say is "bike lanes to nowhere." You can't just plop down these pieces at a really slow pace that aren't connected to other things. … The city takes on these projects but doesn't work more rapidly to connect them to other things. They're not going to impact people's safety and actually build on the number of people who choose to bike to get around."
Rychel said that when she's biking, she doesn't feel like drivers see her as a person sharing the road but rather an entity to direct their anger at. Rychel said she has experienced plenty of negative interactions with aggressive drivers.
"I was about to get to my home and I actually was biking up Willow, which is a slightly more busy street but pretty low speed because it's by a school and only two lanes," Rychel said. "And I moved over to turn left. A couple cars behind me were honking and agitated that they couldn't get to that four-way stop sign two seconds faster because of me. I made my left turn, and the person made their left turn after me and aggressively passed me while honking and going very fast on this even smaller two-lane street."
On Route 28 passing by the Boston Museum of Science, Rychel said she opts to take the sidewalk because of the fast-moving cars that aggressively pass her. She also said that drivers have a perception that cyclists never obey traffic laws, which means they don't belong on the streets. Cyclists say otherwise, as does a study by the University of South Florida's Center for Urban Transportation Research that found, among other things, that cyclists obey traffic laws more than drivers.
Matt said drivers simply disregard bike lanes and frequently park in them.
"There's still a huge problem with people using the bike lane, parking in the bike lane, trucks delivering in the bike lane," he said. "There's passive-aggressive drivers from time to time who will drift into the bike lane. Giving a side-eye to a cyclist.
"I don't see enforcement. And that to me is the biggest issue. The infrastructure that is there doesn't always matter."
Despite the challenges, thousands of people bike. For efficiency, cost, convenience, community, enjoyability, and health benefits.
"I realized the amount of time I spent waiting for trains and just packed like a sardine on the Orange Line," Wolfson said. "I decided it was time to bike all the time. It really felt freeing and empowering."
Moving forward, Boston Cyclists Union is organizing for a protected bike lane on Longfellow Bridge and has successfully organized for a protected bike lane on Comm Ave, despite initial resistance from the city of Boston and Boston University.
"We've really been pushing for a shift in the pace of change," Thompson said. "The folks taking up the most space right now are people in cars. … From the cyclist's perspective, it's a really healthy and great way to move around an urban setting when we have the right cycling conditions.
"I believe the culture around cycling is shifting in Boston and will continue to shift to more positive perceptions [as] we build better and better infrastructure."
This article was produced by the Boston Institute for Nonprofit Journalism and published in DigBoston.
OLIVIA DENG
https://binjonline.com/author/olivia-deng/
CRISIS PREGNANCY CENTER CRISIS
"WE'RE HERE. WE GOT YOU."
THE NEW FACE OF DIRECT ACTION IN MASS DURING THE COVID-19 PANDEMIC
"YOUNG PEOPLE HAVE AN INCREDIBLE AMOUNT OF POWER": YOUTH MOVEMENT APPLIES PRESSURE
Filed Under: Features, Vicious Cycle Tagged With: bike infrastructure, bikes, Boston, Boston Cyclists Union, Vicious Cycle, Vision Zero


Illinois State University Professor of History Andrew Hartman is currently at work on his third book, "Karl Marx in America". According to Hartman, to read and think about Karl Marx is to grapple with the modern world that capitalism has made.
This includes modern America—especially modern America. Because the United States is the nation in world history most committed to capitalism, and because Marx is the world's most enduring theorist of capitalism, Marx is a veritable American alter ego, says Hartman.
This talk is based on Hartman's current book project, which is an investigation into the meaning of Americans reading and thinking about Marx from 1861, when Marx made waves across the Atlantic with his astute analysis of the Civil War, to the present, when Marx is on many American horizons yet again. The talk will highlight some of the specific historical case studies of Marx in America.
The event is open to all, no registration required. Light refreshments.
Andrew Hartman is the author of "Education and the Cold War: The Battle for the American School," "A War for the Soul of America: A History of the Culture Wars," and editor of "American Labyrinth: Intellectual History for Complicated Times." Hartman is the winner of two Fulbright Awards. He was the Fulbright Distinguished Chair in American Studies at the University of Southern Denmark for the 2013-14 academic year, and he is the Fulbright British Library Eccles Center Research Scholar for the 2018-19 academic year. He co-hosts a podcast: Trotsky and the Wild Orchids.
The event is supported by U.S.- Norway Fulbright Foundation for Educational Exchange.


Holidays can be a hectic time of the year - lots of shopping, cleaning, and cooking to get done before company arrives. Moms also have the responsibility of being Santa which means you need to be secretive when shopping and storing the gifts away before the big day. No matter how many times you tell yourself to "remember to grab this" at the store or that you'll need to "order that online when you get home," it's easy to forget. Moms can use this printable Shopping Guide as their checklist to help them stay organized while shopping!
Print this guide, fill out each kid's wish list, and cross off the gifts as they're purchased. Add tally marks in the table to keep track of the color and number of Toy Tamer Bags you need to order to keep your home organized on Christmas Day.
If you're traveling for the holidays, 'Santa' must travel too. It can be hard to pack all of the toys that come in such large packaging on top of all other vacation essentials. Moms can open the packaging and organize the toys in Toy Tamer Bags so there is less mess to travel with. This will also make packing to come home easier and prevent toys from being left behind!


Intelligent Worming is delighted to be working partnership with the following organisations for the benefit of our members.
If you are a member of one of the breed societies listed below click here to register for your free faecal egg count.
THE FRIESIAN HORSE ASSOCIATION OF GREAT BRITAIN AND IRELAND LTD.


text:
using absl::make_unique;
using std::max;
using std::string;
using std::unique_ptr;
using std::vector;

using EndCapStyle = S2BufferOperation::EndCapStyle;
using PolylineSide = S2BufferOperation::PolylineSide;

namespace {

// A callback that allows adding input to an S2BufferOperation.  This is
// convenient for testing the various input methods (AddPoint, AddShape, etc).
using InputCallback = std::function<void (S2BufferOperation* op)>;

// Convenience function that calls the given lambda expression to add input to
// an S2BufferOperation and returns the buffered result.
unique_ptr<S2LaxPolygonShape> DoBuffer(
    InputCallback input_callback, const S2BufferOperation::Options& options) {
  auto output = make_unique<S2LaxPolygonShape>();
  S2BufferOperation op(
      make_unique<s2builderutil::LaxPolygonLayer>(output.get()), options);
  input_callback(&op);
  S2Error error;
  EXPECT_TRUE(op.Build(&error)) << error;
  if (S2_VLOG_IS_ON(1) && output->num_vertices() < 1000) {
    std::cerr << "\nS2Polygon: " << s2textformat::ToString(*output) << "\n";
  }
  return output;
}

// Simpler version that accepts a buffer radius and error fraction.
unique_ptr<S2LaxPolygonShape> DoBuffer(
    InputCallback input_callback,
    S1Angle buffer_radius, double error_fraction) {
  S2BufferOperation::Options options;
  options.set_buffer_radius(buffer_radius);
  options.set_error_fraction(error_fraction);
  return DoBuffer(std::move(input_callback), options);
}

// Given a callback that adds empty geometry to the S2BufferOperation,
// verifies that the result is empty after buffering.
void TestBufferEmpty(InputCallback input) {
  // Test code paths that involve buffering by negative, zero, and positive
  // values, and also values where the result is usually empty or full.
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(-200), 0.1)->is_empty());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(-1), 0.1)->is_empty());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(0), 0.1)->is_empty());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(1), 0.1)->is_empty());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(200), 0.1)->is_empty());
}

TEST(S2BufferOperation, NoInput) {
  TestBufferEmpty([](S2BufferOperation* op) {});
}

TEST(S2BufferOperation, EmptyPolyline) {
  // Note that polylines with 1 vertex are defined to have no edges.
  TestBufferEmpty([](S2BufferOperation* op) {
      op->AddPolyline(vector<S2Point>{S2Point(1, 0, 0)});
    });
}

TEST(S2BufferOperation, EmptyLoop) {
  TestBufferEmpty([](S2BufferOperation* op) {
      op->AddLoop(vector<S2Point>{});
    });
}

TEST(S2BufferOperation, EmptyPointShape) {
  TestBufferEmpty([](S2BufferOperation* op) {
      op->AddShape(S2PointVectorShape{});
    });
}

TEST(S2BufferOperation, EmptyPolylineShape) {
  TestBufferEmpty([](S2BufferOperation* op) {
      op->AddShape(*s2textformat::MakeLaxPolylineOrDie(""));
    });
}

TEST(S2BufferOperation, EmptyPolygonShape) {
  TestBufferEmpty([](S2BufferOperation* op) {
      op->AddShape(*s2textformat::MakeLaxPolygonOrDie(""));
    });
}

TEST(S2BufferOperation, EmptyShapeIndex) {
  TestBufferEmpty([](S2BufferOperation* op) {
      op->AddShapeIndex(*s2textformat::MakeIndexOrDie("# #"));
    });
}

TEST(S2BufferOperation, PoorlyNormalizedPoint) {
  // Verify that debugging assertions are not triggered when an input point is
  // not unit length (but within the limits guaranteed by S2Point::Normalize).
  //
  // The purpose of this test is not to check that the result is correct
  // (which is done elsewhere), simply that no assertions occur.
  DoBuffer([](S2BufferOperation* op) {
      S2Point p(1 - 2 * DBL_EPSILON, 0, 0);  // Maximum error allowed.
      S2_CHECK(S2::IsUnitLength(p));
      op->AddPoint(p);
    }, S1Angle::Degrees(1), 0.01);
}

// Given a callback that adds the full polygon to the S2BufferOperation,
// verifies that the result is full after buffering.
void TestBufferFull(InputCallback input) {
  // Test code paths that involve buffering by negative, zero, and positive
  // values, and also values where the result is usually empty or full.
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(-200), 0.1)->is_full());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(-1), 0.1)->is_full());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(0), 0.1)->is_full());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(1), 0.1)->is_full());
  EXPECT_TRUE(DoBuffer(input, S1Angle::Degrees(200), 0.1)->is_full());
}

TEST(S2BufferOperation, FullPolygonShape) {
  TestBufferFull([](S2BufferOperation* op) {
      op->AddShape(*s2textformat::MakeLaxPolygonOrDie("full"));
    });
}

TEST(S2BufferOperation, FullShapeIndex) {
  TestBufferFull([](S2BufferOperation* op) {
      op->AddShapeIndex(*s2textformat::MakeIndexOrDie("# # full"));
    });
}

TEST(S2BufferOperation, PointsAndPolylinesAreRemoved) {
  // Test that points and polylines are removed with a negative buffer radius.
  auto output = DoBuffer([](S2BufferOperation* op) {
      op->AddShapeIndex(*s2textformat::MakeIndexOrDie("0:0 # 2:2, 2:3#"));
    }, S1Angle::Degrees(-1), 0.1);
  EXPECT_TRUE(output->is_empty());
}

TEST(S2BufferOperation, BufferedPointsAreSymmetric) {
  // Test that points are buffered into regular polygons.  (This is not
  // guaranteed by the API but makes the output nicer to look at. :)
  auto output = DoBuffer([](S2BufferOperation* op) {
      op->AddPoint(S2Point(1, 0, 0));
    }, S1Angle::Degrees(5), 0.001234567);

  // We use the length of the last edge as our reference length.
  int n = output->num_vertices();
  S1Angle edge_len(output->loop_vertex(0, 0), output->loop_vertex(0, n - 1));
  for (int i = 1; i < n; ++i) {
    EXPECT_LE(abs(edge_len - S1Angle(output->loop_vertex(0, i - 1),
                                     output->loop_vertex(0, i))),
              S1Angle::Radians(1e-14));
  }
}

TEST(S2BufferOperation, SetCircleSegments) {
  // Test that when a point is buffered with a small radius the number of
  // edges matches options.circle_segments().  (This is not true for large
  // radii because large circles on the sphere curve less than 360 degrees.)
  // Using a tiny radius helps to catch rounding problems.
  S2BufferOperation::Options options(S1Angle::Radians(1e-12));
  for (int circle_segments = 3; circle_segments <= 20; ++circle_segments) {
    options.set_circle_segments(circle_segments);
    auto output = DoBuffer([](S2BufferOperation* op) {
        op->AddPoint(S2Point(1, 0, 0));
      }, options);
    EXPECT_EQ(output->num_vertices(), circle_segments);
  }
}

TEST(S2BufferOperation, SetSnapFunction) {
  // Verify that the snap function is passed through to S2Builder.
  // We use a buffer radius of zero to make the test simpler.
  S2BufferOperation::Options options;
  options.set_snap_function(s2builderutil::IntLatLngSnapFunction(0));
  auto output = DoBuffer([](S2BufferOperation* op) {
      op->AddPoint(s2textformat::MakePointOrDie("0.1:-0.4"));
      }, options);
  EXPECT_EQ(output->num_vertices(), 1);
  EXPECT_EQ(output->loop_vertex(0, 0), s2textformat::MakePointOrDie("0:0"));
}

TEST(S2BufferOperation, NegativeBufferRadiusMultipleLayers) {
  // Verify that with a negative buffer radius, at most one polygon layer is
  // allowed.
  S2LaxPolygonShape output;
  S2BufferOperation op(
      make_unique<s2builderutil::LaxPolygonLayer>(&output),
      S2BufferOperation::Options(S1Angle::Radians(-1)));
  op.AddLoop(S2PointLoopSpan(s2textformat::ParsePointsOrDie("0:0, 0:1, 1:0")));
  op.AddShapeIndex(*s2textformat::MakeIndexOrDie("# # 2:2, 2:3, 3:2"));
  S2Error error;
  EXPECT_FALSE(op.Build(&error));
  EXPECT_EQ(error.code(), S2Error::FAILED_PRECONDITION);
}

// If buffer_radius > max_error, tests that "output" contains "input".
// If buffer_radius < -max_error tests that "input" contains "output".
// Otherwise does nothing.
void TestContainment(const MutableS2ShapeIndex& input,
                     const MutableS2ShapeIndex& output,
                     S1Angle buffer_radius, S1Angle max_error) {
  S2BooleanOperation::Options options;
  options.set_polygon_model(S2BooleanOperation::PolygonModel::CLOSED);
  options.set_polyline_model(S2BooleanOperation::PolylineModel::CLOSED);
  if (buffer_radius > max_error) {
    // For positive buffer radii, the output should contain the input.
    EXPECT_TRUE(S2BooleanOperation::Contains(output, input, options));
  } else if (buffer_radius < -max_error) {
    // For negative buffer radii, the input should contain the output.
    EXPECT_TRUE(S2BooleanOperation::Contains(input, output, options));
  }
}

// Tests that the minimum distance from the boundary of "output" to the
// boundary of "input" is at least "min_dist" using exact predicates.
void TestMinimumDistance(const MutableS2ShapeIndex& input,
                         const MutableS2ShapeIndex& output,
                         S1ChordAngle min_dist) {
  if (min_dist == S1ChordAngle::Zero()) return;

  // We do one query to find the edges of "input" that might be too close to
  // "output", then for each such edge we do another query to find the edges
  // of "output" that might be too close to it.  Then we check the distance
  // between each edge pair (A, B) using exact predicates.

  // We make the distance limit big enough to find all edges whose true
  // distance might be less than "min_dist".
  S2ClosestEdgeQuery::Options query_options;
  query_options.set_include_interiors(false);
  query_options.set_max_distance(
      min_dist.PlusError(S2::GetUpdateMinDistanceMaxError(min_dist)));

  S2ClosestEdgeQuery in_query(&input, query_options);
  S2ClosestEdgeQuery::ShapeIndexTarget out_target(&output);
  out_target.set_include_interiors(false);
  S2ClosestEdgeQuery out_query(&output, query_options);
  for (const auto& in_result : in_query.FindClosestEdges(&out_target)) {
    auto a = input.shape(in_result.shape_id())->edge(in_result.edge_id());
    S2ClosestEdgeQuery::EdgeTarget in_target(a.v0, a.v1);
    for (const auto& out_result : out_query.FindClosestEdges(&in_target)) {
      auto b = output.shape(out_result.shape_id())->edge(out_result.edge_id());
      ASSERT_GE(
          s2pred::CompareEdgePairDistance(a.v0, a.v1, b.v0, b.v1, min_dist), 0);
    }
  }
}

// Tests that the Hausdorff distance from the boundary of "output" to the
// boundary of "input" is at most (1 + error_fraction) * buffer_radius.  The
// implementation approximates this by measuring the distance at a set of
// points along the boundary of "output".
void TestHausdorffDistance(const MutableS2ShapeIndex& input,
                           const MutableS2ShapeIndex& output,
                           S1ChordAngle max_dist) {
  S2ClosestEdgeQuery::Options query_options;
  query_options.set_include_interiors(false);
  query_options.set_max_distance(
      max_dist.PlusError(S2::GetUpdateMinDistanceMaxError(max_dist)));

  S2ClosestEdgeQuery in_query(&input, query_options);
  for (const S2Shape* out_shape : output) {
    for (int i = 0; i < out_shape->num_edges(); ++i) {
      S2Shape::Edge e = out_shape->edge(i);
      // Measure the distance at 5 points along the edge.
      for (double t = 0; t <= 1.0; t += 0.25) {
        S2Point b = S2::Interpolate(e.v0, e.v1, t);
        S2ClosestEdgeQuery::PointTarget out_target(b);
        // We check the distance bound using exact predicates.
        for (const auto& in_result : in_query.FindClosestEdges(&out_target)) {
          auto a = input.shape(in_result.shape_id())->edge(in_result.edge_id());
          ASSERT_LE(s2pred::CompareEdgeDistance(b, a.v0, a.v1, max_dist), 0);
        }
      }
    }
  }
}

// Buffers the given input with the given buffer_radius and error_fraction and
// verifies that the output is correct.
void TestBuffer(const MutableS2ShapeIndex& input, S1Angle buffer_radius,
                double error_fraction) {
  // Ideally we would verify the correctness of buffering as follows.  Suppose
  // that B = Buffer(A, r) and let ~X denote the complement of region X.  Then
  // if r > 0, we would verify:
  //
  //   1a. Minimum distance between ~B and A >= r_min
  //   1b. Directed Hausdorff distance from B to A <= r_max
  //
  // Buffering A by r < 0 is equivalent to buffering ~A by |r|, so instead we
  // would verify the following (where r_min and r_max are based on |r|):
  //
  //   2a. Minimum distance between B and ~A >= r_min
  //   2b. Directed Hausdorff distance from ~B to ~A <= r_max
  //
  // Conditions 1a and 2a can be implemented as follows:
  //
  //   1a*: B.Contains(A) && minimum distance between @B and @A >= r_min
  //   2a*: A.Contains(B) && minimum distance between @B and @A >= r_min
  //
  // Note that if r_min <= 0 then there is nothing to be tested, since the
  // containment condition may not hold.  (Note that even when the specified
  // buffer radius is zero, edges can move slightly when crossing edges are
  // split during the snapping step.)  The correct approach would be to test
  // instead that the directed Hausdorff distance from A to ~B is at most
  // -r_min, but Hausdorff distance is not yet implemented.
  //
  // Similarly, conditions 1b and 2b need to be approximated because Hausdorff
  // distance is not yet implemented.  We do this by measuring the distance at
  // a set of points on the boundary of B:
  //
  //   1b*: Minimum distance from P to @A <= r_max for a set of points P on @B
  //   2b*: Minimum distance from P to @A <= r_max for a set of points P on @B
  //
  // This is not perfect (e.g., it won't detect cases where an entire boundary
  // loop of B is missing, such as returning a disc in the place of an
  // annulus) but it is sufficient to detect many types of errors.
  S2BufferOperation::Options options;
  options.set_buffer_radius(buffer_radius);
  options.set_error_fraction(error_fraction);
  MutableS2ShapeIndex output;
  output.Add(DoBuffer(
      [&input](S2BufferOperation* op) { op->AddShapeIndex(input); }, options));

  SCOPED_TRACE(absl::StrFormat(
      "\nradius = %.17g, error_fraction = %.17g\ninput = %s\noutput = %s",
      buffer_radius.radians(), error_fraction,
      s2textformat::ToString(input), s2textformat::ToString(output)));

  // Check the 1a*/1b* condition above.
  S1Angle max_error = options.max_error();
  TestContainment(input, output, buffer_radius, max_error);

  S1ChordAngle min_dist(max(S1Angle::Zero(), abs(buffer_radius) - max_error));
  TestMinimumDistance(input, output, min_dist);

  // Check the 2a*/2b* condition (i.e., directed Hausdorff distance).
  S1ChordAngle max_dist(abs(buffer_radius) + max_error);
  TestHausdorffDistance(input, output, max_dist);
}

// Convenience function that takes an S2ShapeIndex in s2textformat format.
void TestBuffer(absl::string_view index_str, S1Angle buffer_radius,
                double error_fraction) {
  TestBuffer(*s2textformat::MakeIndexOrDie(index_str), buffer_radius,
             error_fraction);
}

// Convenience function that tests buffering using +/- the given radius.
void TestSignedBuffer(absl::string_view index_str, S1Angle buffer_radius,
                      double error_fraction) {
  TestBuffer(index_str, buffer_radius, error_fraction);
  TestBuffer(index_str, -buffer_radius, error_fraction);
}

TEST(S2BufferOperation, PointShell) {
  TestSignedBuffer("# # 0:0", S1Angle::Radians(M_PI_2), 0.01);
}

TEST(S2BufferOperation, SiblingPairShell) {
  TestSignedBuffer("# # 0:0, 0:5", S1Angle::Radians(M_PI_2), 0.01);
}

TEST(S2BufferOperation, SiblingPairHole) {
  TestSignedBuffer("# # 0:0, 0:10, 7:7; 3:4, 3:6", S1Angle::Degrees(1), 0.01);
}

TEST(S2BufferOperation, Square) {
  TestSignedBuffer("# # -3:-3, -3:3, 3:3, 3:-3", S1Angle::Degrees(1), 0.01);
  TestSignedBuffer("# # -3:-3, -3:3, 3:3, 3:-3", S1Angle::Degrees(170), 1e-4);
}

TEST(S2BufferOperation, HollowSquare) {
  TestSignedBuffer("# # -3:-3, -3:3, 3:3, 3:-3; 2:2, -2:2, -2:-2, 2:-2",
                   S1Angle::Degrees(1), 0.01);
}

TEST(S2BufferOperation, ZigZagLoop) {
  TestSignedBuffer("# # 0:0, 0:7, 5:3, 5:10, 6:10, 6:1, 1:5, 1:0",
                   S1Angle::Degrees(0.2), 0.01);
}

TEST(S2BufferOperation, Fractals) {
  for (double dimension : {1.02, 1.8}) {
    S2Testing::Fractal fractal;
    fractal.SetLevelForApproxMaxEdges(3 * 64);
    fractal.set_fractal_dimension(dimension);
    auto loop = fractal.MakeLoop(S2::GetFrame(S2Point(1, 0, 0)),
                                 S1Angle::Degrees(10));
    MutableS2ShapeIndex input;
    input.Add(make_unique<S2Loop::Shape>(loop.get()));
    TestBuffer(input, S1Angle::Degrees(0.4), 0.01);
  }
}

TEST(S2BufferOperation, S2Curve) {
  // Tests buffering the S2 curve by an amount that yields the full polygon.
  constexpr int kLevel = 2;  // Number of input edges == 6 * (4 ** kLevel)
  vector<S2Point> points;
  for (S2CellId id = S2CellId::Begin(kLevel);
       id != S2CellId::End(kLevel); id = id.next()) {
    points.push_back(id.ToPoint());
  }
  // Buffering by this amount or more is guaranteed to yield the full polygon.
  // (Note that the bound is not tight for S2CellIds at low levels.)
  S1Angle full_radius = S1Angle::Radians(0.5 * S2::kMaxDiag.GetValue(kLevel));
  EXPECT_TRUE(DoBuffer([&points](S2BufferOperation* op) {
      op->AddShape(S2LaxClosedPolylineShape(points));
    }, full_radius, 0.1)->is_full());
}

// Tests buffering the given S2ShapeIndex with a variety of radii and error
// fractions.  This method is intended to be used with relatively simple
// shapes since calling it is quite expensive.
void TestRadiiAndErrorFractions(absl::string_view index_str) {
  // Try the full range of radii with a representative error fraction.
  constexpr double kFrac = 0.01;
  vector<double> kTestRadiiRadians = {
    0, 1e-300, 1e-15, 2e-15, 3e-15, 1e-5, 0.01, 0.1, 1.0,
    (1 - kFrac) * M_PI_2, M_PI_2 - 1e-15, M_PI_2, M_PI_2 + 1e-15,
    (1 - kFrac) * M_PI, M_PI - 1e-6, M_PI, 1e300
  };
  for (double radius : kTestRadiiRadians) {
    TestSignedBuffer(index_str, S1Angle::Radians(radius), kFrac);
  }

  // Now try the full range of error fractions with a few selected radii.
  vector<double> kTestErrorFractions =
      {S2BufferOperation::Options::kMinErrorFraction, 0.001, 0.01, 0.1, 1.0};
  for (double error_fraction : kTestErrorFractions) {
    TestBuffer(index_str, S1Angle::Radians(-1e-6), error_fraction);
    TestBuffer(index_str, S1Angle::Radians(1e-14), error_fraction);
    TestBuffer(index_str, S1Angle::Radians(1e-2), error_fraction);
    TestBuffer(index_str, S1Angle::Radians(M_PI - 1e-3), error_fraction);
  }
}

TEST(S2BufferOperation, RadiiAndErrorFractionCoverage) {
  // Test buffering simple shapes with a wide range of different buffer radii
  // and error fractions.

  // A single point.
  TestRadiiAndErrorFractions("1:1 # #");

  // A zig-zag polyline.
  TestRadiiAndErrorFractions("# 0:0, 0:30, 30:30, 30:60 #");

  // A triangular polygon with a triangular hole.  (The hole is clockwise.)
  TestRadiiAndErrorFractions("# # 0:0, 0:100, 70:50; 10:20, 50:50, 10:80");

  // A triangle with one very short and two very long edges.
  TestRadiiAndErrorFractions("# # 0:0, 0:179.99999999999, 1e-300:0");
}

class TestBufferPolyline {
 public:
  TestBufferPolyline(const string& input_str,
                     const S2BufferOperation::Options& options);

 private:
  const double kArcLo = 0.001;
  const double kArcHi = 0.999;
  const int kArcSamples = 7;

  S2Point GetEdgeAxis(const S2Point& a, const S2Point& b) {
    return S2::RobustCrossProd(a, b).Normalize();
  }

  bool PointBufferingUncertain(const S2Point& p, bool expect_contained) {
    // The only case where a point might be excluded from the buffered output is
    // if it is on the unbuffered side of the polyline.
    if (expect_contained && two_sided_) return false;

    int n = polyline_.size();
    for (int i = 0; i < n - 1; ++i) {
      const S2Point& a = polyline_[i];
      const S2Point& b = polyline_[i + 1];
      if (!two_sided_) {
        // Ignore points on the buffered side if expect_contained is true,
        // and on the unbuffered side if expect_contained is false.
        if ((s2pred::Sign(a, b, p) < 0) == expect_contained) continue;
      }
      // TODO(ericv): Depending on how the erasing optimization is implemented,
      // it might be possible to add "&& expect_contained" to the test below.
      if (round_) {
        if (S2::IsDistanceLess(p, a, b, max_dist_)) return true;
      } else {
        if (S2::IsInteriorDistanceLess(p, a, b, max_dist_)) return true;
        if (i > 0 && S1ChordAngle(p, a) < max_dist_) return true;
        if (i == n - 2 && S1ChordAngle(p, b) < max_dist_) return true;
      }
    }
    return false;
  }

  void TestPoint(const S2Point& p, const S2Point& dir, bool expect_contained) {
    S2Point x = S2::GetPointOnRay(
        p, dir, expect_contained ? buffer_radius_ - max_error_ : max_error_);
    if (!PointBufferingUncertain(x, expect_contained)) {
      EXPECT_EQ(MakeS2ContainsPointQuery(&output_).Contains(x),
                expect_contained);
    }
  }

  void TestVertexArc(const S2Point& p, const S2Point& start, const S2Point& end,
                     bool expect_contained) {
    for (double t = kArcLo; t < 1; t += (kArcHi - kArcLo) / kArcSamples) {
      S2Point dir = S2::Interpolate(start, end, t);
      TestPoint(p, dir, expect_contained);
    }
  }

  void TestEdgeArc(const S2Point& ba_axis, const S2Point& a, const S2Point& b,
                   bool expect_contained) {
    for (double t = kArcLo; t < 1; t += (kArcHi - kArcLo) / kArcSamples) {
      S2Point p = S2::Interpolate(a, b, t);
      TestPoint(p, ba_axis, expect_contained);
    }
  }

  void TestEdgeAndVertex(const S2Point& a, const S2Point& b, const S2Point& c,
                         bool expect_contained) {
    S2Point ba_axis = GetEdgeAxis(b, a);
    S2Point cb_axis = GetEdgeAxis(c, b);
    TestEdgeArc(ba_axis, a, b, expect_contained);
    TestVertexArc(b, ba_axis, cb_axis, expect_contained);
  }

  vector<S2Point> polyline_;
  MutableS2ShapeIndex output_;
  S1Angle buffer_radius_, max_error_;
  S1ChordAngle min_dist_, max_dist_;
  bool round_, two_sided_;
};

// Tests buffering a polyline with the given options.  This method is intended
// only for testing Options::EndCapStyle and Options::PolylineSide; if these
// options have their default values then TestBuffer() should be used
// instead.  Similarly TestBuffer should be used to test negative buffer radii
// and polylines with 0 or 1 vertices.
TestBufferPolyline::TestBufferPolyline(
    const string& input_str, const S2BufferOperation::Options& options)
    : polyline_(s2textformat::ParsePointsOrDie(input_str)),
      buffer_radius_(options.buffer_radius()),
      max_error_(options.max_error()),
      min_dist_(max(S1Angle::Zero(), buffer_radius_ - max_error_)),
      max_dist_(buffer_radius_ + max_error_),
      round_(options.end_cap_style() == EndCapStyle::ROUND),
      two_sided_(options.polyline_side() == PolylineSide::BOTH) {
  S2_DCHECK_GE(polyline_.size(), 2);
  S2_DCHECK(buffer_radius_ > S1Angle::Zero());

  MutableS2ShapeIndex input;
  input.Add(s2textformat::MakeLaxPolylineOrDie(input_str));
  output_.Add(DoBuffer(
      [&input](S2BufferOperation* op) { op->AddShapeIndex(input); }, options));

  // Even with one-sided buffering and flat end caps the Hausdorff distance
  // criterion should still be true.  (This checks that the buffered result
  // is never further than (buffer_radius + max_error) from the input.)
  TestHausdorffDistance(input, output_, max_dist_);

  // However the minimum distance criterion is different; it only applies to
  // the portions of the boundary that are buffered using the given radius.
  // We check this approximately by walking along the polyline and checking
  // that (1) on portions of the polyline that should be buffered, the output
  // contains the offset point at distance (buffer_radius - max_error) and (2)
  // on portions of the polyline that should not be buffered, the output does
  // not contain the offset point at distance max_error.  The tricky part is
  // that both of these conditions have exceptions: (1) may not hold if the
  // test point is closest to the non-buffered side of the polyline (see the
  // last caveat in the documentation for Options::polyline_side), and (2)
  // may not hold if the test point is within (buffer_radius + max_error) of
  // the buffered side of any portion of the polyline.
  if (min_dist_ == S1ChordAngle::Zero()) return;

  // Left-sided buffering is tested by reversing the polyline and then testing
  // whether it has been buffered correctly on the right.
  if (options.polyline_side() == PolylineSide::LEFT) {
    std::reverse(polyline_.begin(), polyline_.end());
  }

  int n = polyline_.size();
  S2Point start0 = polyline_[0], start1 = polyline_[1];
  S2Point start_begin = GetEdgeAxis(start0, start1);
  S2Point start_mid = start0.CrossProd(start_begin);
  TestVertexArc(start0, start_begin, start_mid, round_ && two_sided_);
  TestVertexArc(start0, start_mid, -start_begin, round_);
  for (int i = 0; i < n - 2; ++i) {
    TestEdgeAndVertex(polyline_[i], polyline_[i + 1], polyline_[i + 2], true);
  }
  S2Point end0 = polyline_[n - 1], end1 = polyline_[n - 2];
  S2Point end_begin = GetEdgeAxis(end0, end1);
  S2Point end_mid = end0.CrossProd(end_begin);
  TestEdgeArc(end_begin, end1, end0, true);
  TestVertexArc(end0, end_begin, end_mid, round_);
  TestVertexArc(end0, end_mid, -end_begin, round_ && two_sided_);
  for (int i = n - 3; i >= 0; --i) {
    TestEdgeAndVertex(polyline_[i + 2], polyline_[i + 1], polyline_[i],
                      two_sided_);
  }
  TestEdgeArc(start_begin, start1, start0, two_sided_);
}

TEST(S2BufferOperation, ZigZagPolyline) {
  S2BufferOperation::Options options(S1Angle::Degrees(1));
  for (PolylineSide polyline_side : {
      PolylineSide::LEFT, PolylineSide::RIGHT, PolylineSide::BOTH}) {
    for (EndCapStyle end_cap_style : {
        EndCapStyle::ROUND, EndCapStyle::FLAT}) {
      SCOPED_TRACE(absl::StrFormat(
          "two_sided = %d, round = %d",
          polyline_side == PolylineSide::BOTH,
          end_cap_style == EndCapStyle::ROUND));
      options.set_polyline_side(polyline_side);
      options.set_end_cap_style(end_cap_style);
      TestBufferPolyline("0:0, 0:7, 5:3, 5:10", options);  // NOLINT
      TestBufferPolyline("10:0, 0:0, 5:1", options);       // NOLINT
    }
  }
}

}  // namespace

redpajama_set_name: RedPajamaGithub


text:
Q: Upgrading from .xls to .xlsx with POI I have a web application In which i have  excel file(.xls) download option. Now I Have to provide that feature in .xlsx
I am trying to Use POI Jar. When I try to do that as a stand alone Application it works fine, but when I try to integrate that into a web application, I am getting an error as

Excel Found Unreadable Content in FILENAME.xlsx. do you want to recover the content of this workbook?
  If you trust the source of this workbook click yes!

XSSFWorkbook w = FileName.createExcelWorkbookPosition(
        request.getParameter("BSNS_DT"));
response.setContentType(
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition","attachment;filename=filename.xlsx");
w.write(response.getOutputStream());

Here's the Java code where I create the spreadsheet:
public static XSSFWorkbook createExcelWorkbookPosition(String BsnsDate)
    throws Exception
{
    FileOutputStream out = new FileOutputStream("workbook.xlsx");

    // create a new workbook
    XSSFWorkbook wb = new XSSFWorkbook();
    // create a new sheet
    XSSFSheet s = wb.createSheet();
    // declare a row object reference
    XSSFRow r = null;
    // declare a cell object reference
    XSSFCell c = null;

    // header row and columns
    r = s.createRow(0);
    c = r.createCell(0);
    c.setCellValue("Business Date");
    //c.setCellStyle(cs);
    c = r.createCell(1);
    c.setCellValue("Account No");

    try {
        wb.write(out);
        out.close();
        System.out.println("File writed");
    } catch (Exception e) {
        System.out.println("Error");
        System.out.println(e);
    }
    return wb;
}

Can anyone please help? Sorry for any bad English! Thanks.

A: I had a quite similar issue, please have a look at Forcing the browser to download a docx file in JAVA generates a corrupted document. The point was to add the Content-Length header of the response.
Try to make createExcelWorkbookPosition returning the file instead of the XSSFWorkbook:
public static File createExcelWorkbookPosition(String BsnsDate) throws Exception {
    File file = new File("workbook.xlsx");
    FileOutputStream out = new FileOutputStream(file);
    // ...
    return file;
}

Then:
File file = FileName.createExcelWorkbookPosition(request.getParameter("BSNS_DT"));
// ...
response.setContentLength((int) file.length());

InputStream in = new FileInputStream(file);
OutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}
// if using Apache IO, the above code can be simplified to IOUtils.copy(in, out);
// if using Guava, Files.copy(file, out);

// don't forget to close your streams and flush the response buffer

redpajama_set_name: RedPajamaStackExchange