Zwentendorf Nuclear Power Plant: Finished in 1978 but was never used

Hacker News
www.atlasobscura.com
2024-05-17 04:16:38
Comments...
Original Article

For a brief moment in the 1970s, it looked like the future of Austria’s power production was going to be in a handful of massive nuclear plants, before the entire vision was put down by a massive public outcry. However before the people could vote down their nuclear future, one plant was completely finished, they just never turned it on.

Completed in mid-to-late 1970s, the plant in Zwentendorf cost around a billion euro to complete. The tall, monolithic building was outfitted with a modern-at-the-time boiling water reactor complete with a huge chimney tower scraping the sky next to the central building. The facility was even outfitted with the dangerous radioactive nuclear rods, all it needed was the go-ahead to turn the lights on. Then the public had their say.

The Zwentendorf facility was just the first of a number of planned nuclear plants in the country, but anti-nuclear sentiment exploded during its construction. In a referendum passed in 1978, the Austrian people voted by a margin just over 50% to ban all nuclear power plants. And with that, the new plant was dead in the water.

Since the law was passed, the Zwentendorf plant was partially dismantled and the facility was used as a sort of spare parts warehouse for other compatible plants in Germany. In addition, the space has been used for film shooting and security training. However more than anything, the massive empty complex stands as a reminder of a pivotal moment in the country’s history.

Urban Renewal Ruined Everything

Hacker News
darrellowens.substack.com
2024-05-17 03:21:57
Comments...
Original Article

“America can’t build anything,” my co-worker, a talented data scientist from China, remarked as we rode a BART train through a suburb of Oakland. She was humored by the contrast of ultra-modern subways and dense apartments in Chengdu with the 1960s stucco houses and the Apollo 11-era BART metro system of the Bay Area. The mayor of San Francisco had a similar thought on her recent trip to China, marveling at the infrastructure built within a few years. We hear it a million times in American media: our infrastructure sucks. It takes too long to build a single home in most cities and $1.7 million to build a bathroom in San Francisco. Four stations on a mere six-mile VTA-led BART extension through mostly suburban San Jose will cost as much as $12 billion, more than double the annual war budget of Iran.

The culprit is many factors, but much of them originate with urban renewal — the aggressive bulldozing and re-development programs that peaked in the 1950s and 1960s. Ramped up by the Eisenhower Administration, aggressive public policy used infrastructure like freeways and property development to bulldoze low-income areas. The impacts persist to this day: the destruction of Black middle-class urban neighborhoods, vacant lots in once-thriving districts, the erasure of historic districts, the masses of jumbled freeways, and the mass migration of people out of cities.

Most stated urban renewal goals were total failures. Intending to revitalize business in the city core, most redevelopment projects were failures at attracting and sustaining private investment in cities, with a few exceptions. Intending to remove their Black population, urban renewal depressed property values and kept these neighborhoods majority Black, though depopulated and poorer. Urban renewal did convince most Americans that the government was incapable of delivering public projects. It had successfully frightened minorities that the government would usurp their lands and target them. It had convinced the white middle class that government programs were mostly tax-wasting, destructive projects and fueled the tax revolt of the 1970s.

The backlash to how urban renewal was conducted primarily blamed its top-down approach to urban planning. Federal and state bureaucrats from neighborhoods far away from areas they lived made radical decisions about people’s neighborhoods without their input. Post-urban renewal, major planning and consulting decisions were given to private, tax-exempt companies a.k.a. not-for-profits. By the 1980s and 1990s, a cottage industry of inner-city nonprofits acting as community middlemen emerged to do that job. Private companies had already been contracted as consultants and contractors for public development during urban renewal. Now, major planning aspects of public development are directly influenced by private organizations, which aren’t inherently democratic. Rather than building up cost-effective public capacity, public funds go to private companies to manage decisions and outreach.

Accompanying this change was the ballooning of public process and veto points, often in the name of “bottom-up” planning. In my opinion, the accurate takeaway from urban renewal was not that the government lacked checks and balances in public development, as is often told. Many affluent and middle-class neighborhoods were spared from bulldozers with very little resistance. Ugly freeways sprawled throughout Oakland yet ceased at the Berkeley border because Berkeley’s local government listened to its wealthier homeowners and vetoed the city’s freeway project. Oakland City Council did not care about its mostly poorer populace and invited freeways in with comparatively less fuss.

Urban renewal wasn’t as top-down as people say. The routing of freeways and public project placements were often determined by municipalities and states, not federal officials, and they chose targets like minority neighborhoods. Rather than recognizing representation in government that gave way to the destruction of neighborhoods, a myth has emerged that there weren’t enough meetings. These urban renewal projects were deliberated on for years or enshrined in local master plans decades prior— always without the explicit participation or solicitation of poor communities.

Today, publicly funded projects have an excessive number of meetings where very little if anything is accomplished in defense of the project, yet every meeting presents an opportunity to veto the project. Nor have equitable outcomes been achieved. Though not called “urban renewal” anymore, freeway construction and widening projects continue to ravage disproportionately ethnic minority and lower-income neighborhoods in 2024.

The public outreach process tends to heavily benefit older, retired, wealthier and home-owning residents that can go to city hall regularly. Holding more meetings doesn’t increase equitable outcomes, rather it gives that constituency more chances to veto a project. Working people and parents with under-aged kids often can’t spend time at city hall, waiting for hours before commenting on projects that may benefit or harm them. Excessive hearings significantly increase the cost of all projects because salaries must be paid to officials and consultants for every minor adjustment, both in the government and private sector.

Another failed attempt at reform was environmental law. The biggest mistake that early environmental advocacy made in the 1970s was suggesting that simply being opposed to development was environmentally friendly. Today, modern climate science understands that’s incorrect, but our laws treat carbon-reduction projects as equivalent to any net-carbon increase project. Bus lanes that would take cars off the road go through extremely costly and years-long environmental review. Same for infill housing or green energy projects, which can cost hundreds of thousands in review and permitting alone.

Environmental law often also fails to distinguish between existing uses predating these laws and new uses meant to combat them. The most glaring example would be California High-Speed Rail, which would provide tremendous carbon-reduction benefits on a crowded highway and air corridor. Yet because of the California Environmental Quality Act and the federal National Environmental Policy Act, high speed rail has been delayed by decades of litigation, obstruction and study. Yet the existing West Coast crowded airline corridor, suburban sprawl, and highways built before these laws came into effect cannot have the laws used against them. Even though their emissions grew beyond their initial projections and high-speed rail would reduce them.

Our entire approach to land-use is both insanely slow and produces carbon-intensive outcomes through status quoism, all thanks to urban renewal’s trauma. In Vienna, Austria their public housing developments are influenced and customized by local community boards, but they can not prohibit housing. Unlike the U.S. where zoning dictates what you can do with your property, zoning in Japan dictates what you can’t do with property. Infrastructure can be delivered quicker there, as land use focuses on regulating against harm rather than micro-managing all possible uses. The latter leads to cities like Half Moon Bay, California, dictating and downsize housing for low income farm workers who recently suffered a mass shooting, because the concerns of neighbors supersede the welfare of the public at large.

As frustrating as it is to wait 30 years for California High-Speed rail to finish, it's the punishment we pay for never truly atoning for the harm urban renewal did, and precisely how it did it. We live in a fantasy world where all government projects and development done efficiently come at the material cost of communities, rather than the truth which is that urban renewal was meant to destroy, not improve neighborhoods. It’s hard to envision a future where we’ll have good infrastructure in the United States.

For all the gags and bewilderment of American media in the late 2000s made about “Chinese Ghost Cities”, most of those cities are now well occupied. The Chinese government correctly predicted population growth and built cities ahead of time, although not in the most efficient manner. The United States ignored our bustling population needs because we can’t plan or build cities anymore, and within 10 years we went from a housing bubble to a housing shortage where rent is the primary cause of national inflation. U.S. cities barely plan for the future anymore and don’t have any extravagant ideas about how they’ll need to grow.

Databases for Data Scientist – And why you probably don't need one

Hacker News
josiahparry.com
2024-05-17 03:19:44
Comments...
Original Article

It’s been coming up a lot recently, or, maybe, I’ve just been focused on this a lot more. Data scientists are coming to terms with the fact that they have to work with databases if they want their analytics to scale. That is pretty normal. But one of the bigger challenges is that these data scientists don’t really know how to make that leap. What do they need to know to make that transition?

For many of use in the “know”, we know that there actually isn’t all that much different between a database and a data.frame. A data frame is in memory but a database table is just over there sitting somewhere else.

If you know how to write dplyr, you already know how to work with a database.

What do you need to know?

For those of you who want to begin to use databases in your work and want to start scaling your analysis, there are a few topics that would be helpful for you to know. I’m not going to teach you them here. But list them out so you can google it. And truthfully, you already know what these are but you don’t know the terminology.

Here is my list of things to know:

  1. Learn what RDBMS means.
  • relational database management system or sometimes just DBMS
  1. Understand primary keys and foreign keys
  2. Figure out what database noramlization is and when its useful
  3. Schemas vs. tables for organizational purposes
  4. Views vs tables (this is handy for making tables to be consumed by BI / other things)
  5. Table indexes and what they are (that way you can know when you might need them)

Why you might not actually need a full RDBMS

With the ubiquity of parquet and tools like apache arrow and DuckDB, there’s a good chance that for what you want to accomplish in your analytical workflow, you don’t need a fully fledged database. Organized parquet files into a database-like structure will be sufficient. DuckDB and Arrow can allow you to work with these data in a larger than memory capacity. You don’t need to read it all into memory, actually.

Before you say you need Postgres for analytics, instead, try parquet (and with hive partitioning if your data are larger) with DuckDB and Apache Arrow. It’s likely all you need.

100 Exercises to Learn Rust

Hacker News
rust-exercises.com
2024-05-17 02:53:13
Comments...
Original Article

Welcome

Welcome to "100 Exercises To Learn Rust"!

This course will teach you Rust's core concepts, one exercise at a time.
You'll learn about Rust's syntax, its type system, its standard library, and its ecosystem.

We don't assume any prior knowledge of Rust, but we assume you know at least another programming language.
We also don't assume any prior knowledge of systems programming or memory management. Those topics will be covered in the course.

In other words, we'll be starting from scratch!
You'll build up your Rust knowledge in small, manageable steps. By the end of the course, you will have solved ~100 exercises, enough to feel comfortable working on small to medium-sized Rust projects.

Methodology

This course is based on the "learn by doing" principle.
It has been designed to be interactive and hands-on.

Mainmatter developed this course to be delivered in a classroom setting, over 4 days: each attendee advances through the lessons at their own pace, with an experienced instructor providing guidance, answering questions and diving deeper into the topics as needed.
If you're interested in attending one of our training sessions, or if you'd like to bring this course to your company, please get in touch.

You can also follow the course on your own, but we recommend you find a friend or a mentor to help you along the way should you get stuck. You can also find solutions to all exercises in the solutions branch of the GitHub repository.

Structure

On the left side of the screen, you can see that the course is divided into sections. Each section introduces a new concept or feature of the Rust language.
To verify your understanding, each section is paired with an exercise that you need to solve.

You can find the exercises in the companion GitHub repository.
Before starting the course, make sure to clone the repository to your local machine:

# If you have an SSH key set up with GitHub
git clone git@github.com:mainmatter/100-exercises-to-learn-rust.git
# Otherwise, use the HTTPS URL:
#
#   git clone https://github.com/mainmatter/100-exercises-to-learn-rust.git

We also recommend you work on a branch, so you can easily track your progress and pull in updates from the main repository, if needed:

cd 100-exercises-to-learn-rust
git checkout -b my-solutions

All exercises are located in the exercises folder. Each exercise is structured as a Rust package. The package contains the exercise itself, instructions on what to do (in src/lib.rs), and a test suite to automatically verify your solution.

wr, the workshop runner

To verify your solutions, we've provided a tool that will guide you through the course. It is the wr CLI (short for "workshop runner"). Install it with:

cargo install --locked workshop-runner

In a new terminal, navigate back to the top-level folder of the repository. Run the wr command to start the course:

wr

wr will verify the solution to the current exercise.
Don't move on to the next section until you've solved the exercise for the current one.

We recommend committing your solutions to Git as you progress through the course, so you can easily track your progress and "restart" from a known point if needed.

Enjoy the course!

References

  • The exercise for this section is located in exercises/01_intro/00_welcome

This course was written by Luca Palmieri, Principal Engineering Consultant at Mainmatter.
Luca has been working with Rust since 2018, initially at TrueLayer and then at AWS.
Luca is the author of "Zero to Production in Rust", the go-to resource for learning how to build backend applications in Rust.
He is also the author and maintainer of a variety of open-source Rust projects, including cargo-chef, Pavex and wiremock.

The Consumer Finance Protection Bureau is Constitutional, After All

Intercept
theintercept.com
2024-05-17 00:34:55
And for some reason Justice Alito can't stop talking about this witch trial judge. The post The Consumer Finance Protection Bureau is Constitutional, After All appeared first on The Intercept....
Original Article

In a blow to the conservative legal movement, the U.S. Supreme Court ruled that the Consumer Finance Protection Bureau is not, in fact, an unconstitutional abomination.

The independent agency — which oversees payday lenders, credit card companies, and student loans — has long been a partisan target. And as it turns out, its funding mechanism is perfectly constitutional, the court ruled Thursday in a 7-2 decision. 

Its conclusion was straightforward: When it created the CFPB, Congress passed a law that authorized expenditures from specific sources to fund the agency. This satisfies the Appropriations Clause, the court ruled.  

The attack on the CFPB is not the only challenge brought this term by conservative opponents of modern regulatory agencies. In as-yet-undecided cases, the Supreme Court will consider whether to curtail the powers of the Securities Exchange Commission and whether to gut a landmark standard for all regulatory oversight. Challenges to the National Labor Relations Board are working their way through lower courts. 

In all three cases before the Supreme Court this term, legions of conservative legal luminaries urged the justices to shrink the administrative state. In the CFPB challenge, however, they lost even Justice Clarence Thomas, who wrote the majority opinion, plus three others from the Court’s conservative supermajority. Only Justices Samuel Alito and Neil Gorsuch dissented.  

As The Intercept reported last year, the case was brought and bankrolled by payday lenders, who asserted the way the CFBP is funded is unconstitutional. If so, every regulation the CFPB ever issued was potentially invalid — including rules issued in 2017 for high-interest loans, which irked payday lenders. 

Congress designed the CFPB in response to the 2008 financial crisis, engineering it to be shielded from certain political winds via provisions insulating its funding and leadership in ways that differ from most federal departments. Four years ago, in a sign that the Roberts Court was eager to hear these kinds of broad challenges, the Supreme Court invalidated provisions regarding CFPB’s leadership structure but left it otherwise intact.  

The latest attempt to finish off the CFPB came with impeccable conservative provenance. In 2022, a panel of the Fifth Circuit Court of Appeals — all appointed by former President Donald Trump — ruled that CFPB’s funding mechanism was unconstitutional. 

Before the Supreme Court, former solicitor general Noel Francisco, who clerked for late Justice Antonin Scalia and notoriously refused to defend the CFPB during his tenure in the Trump administration, argued for the payday lenders. A slew of friend-of-court briefs urged the Court to sink the CFPB or at least cut off its funding, including conservative stalwarts like the U.S. Chamber of CommerceNew Civil Liberties Alliance, a coalition of Republican attorneys general, and the omnipresent John Eastman.  

In a rebuff, the Supreme Court majority rejected these arguments, concluding its funding model was indeed constitutional. 

What divided the justices — even within the majority — was one of the central disagreements ushered in by Scalia and his fellow originalist revolutionaries on the bench: When the government faces thoroughly modern issues like regulating credit card penalties and semiautomatic weapons, should ancient history matter? 

Justice Thomas, an arch-originalist, went as far back as the Middle Ages, the Magna Carta, and the Glorious Revolution. His opinion, which was signed by the full majority, dwelled on how the First Congress allocated money to agencies, and barely peeked past 1800. 

In a concurring opinion, Justice Kagan pointed out that there are a couple more centuries to consider. “The way our Government has actually worked, over our entire experience, thus provides another reason to uphold Congress’s decision about how to fund the CFPB,” Kagan wrote. Justice Sonia Sotomayor co-signed that view, along with conservative Justices Amy Coney Barrett and Brett Kavanaugh.

Justice Ketanji Brown Jackson, meanwhile, writing only for herself, suggested that sometimes ancient history has limited lessons for twenty-first century issues like financial regulation. “In response to the devastation wrought by the 2008 financial crisis, Congress passed and the President signed the Dodd-Frank Wall Street Reform and Consumer Protection Act,” she wrote, noting that the payday lenders challenging CFPB were “exactly the type of entity the Bureau’s progenitors sought to regulate and whose influence Congress may have feared.”

“An essential aspect of the Constitution’s endurance is that it empowers the political branches to address new challenges by enacting new laws and policies — without undue interference by courts,” Jackson wrote.

In dissent, Justices Alito and Gorsuch howled that the “Framers would be shocked, even horrified” by the CFPB. Alito’s dissent cited Montesquieu, the practices of “the early Stuart kings” in the 1600s, and the accounting methods of Alexander Hamilton, and threw in a gratuitous shoutout to an infamous seventeenth-century witch trial judge, Sir Matthew Hale, who birthed the legal notion that husbands cannot be prosecuted for raping their wives, which continues to haunt legal systems worldwide. 

Alito concluded: “Today’s decision is not faithful to the original understanding of the Appropriations Clause and the centuries of history that gave birth to the appropriations requirement, and I therefore respectfully dissent.” 

The Court is expected to issue its remaining decisions regarding regulatory agencies’ authority and structure by July. 

Senator Elizabeth Warren, who proposed establishing the CFPB as a law professor, praised the ruling but looked ahead to future challenges. 

“This isn’t the last attack on the CFPB we’ll see from Wall Street, the banks & their Republican allies,” Warren tweeted

The Consumer Finance Protection Bureau Is Constitutional, After All

Intercept
theintercept.com
2024-05-17 00:34:55
And for some reason Justice Samuel Alito can’t stop talking about this witch trial judge. The post The Consumer Finance Protection Bureau Is Constitutional, After All appeared first on The Intercept....
Original Article

In a blow to the conservative legal movement, the U.S. Supreme Court ruled that the Consumer Finance Protection Bureau is not, in fact, an unconstitutional abomination.

The independent agency — which oversees payday lenders, credit card companies, and student loans — has long been a partisan target. And as it turns out, its funding mechanism is perfectly constitutional, the court ruled Thursday in a 7-2 decision. 

Its conclusion was straightforward: When it created the CFPB, Congress passed a law that authorized expenditures from specific sources to fund the agency. This satisfies the Appropriations Clause of the Constitution, the court ruled.

The attack on the CFPB is not the only challenge brought this term by conservative opponents of modern regulatory agencies. In as-yet-undecided cases, the Supreme Court will consider whether to curtail the powers of the Securities Exchange Commission and whether to gut a landmark standard for all regulatory oversight. Challenges to the National Labor Relations Board are working their way through lower courts. 

In all three cases before the Supreme Court this term, legions of conservative legal luminaries urged the justices to shrink the administrative state. In the CFPB challenge, however, they lost even Justice Clarence Thomas, who wrote the majority opinion, plus three others from the Court’s conservative supermajority. Only Justices Samuel Alito and Neil Gorsuch dissented.

As The Intercept reported last year, the case was brought and bankrolled by payday lenders, who asserted the way the CFBP is funded is unconstitutional. If so, every regulation the CFPB ever issued was potentially invalid — including rules issued in 2017 for high-interest loans, which irked payday lenders. 

Congress designed the CFPB in response to the 2008 financial crisis, engineering it to be shielded from certain political winds via provisions insulating its funding and leadership in ways that differ from most federal departments. Four years ago, in a sign that the Roberts Court was eager to hear these kinds of broad challenges, the Supreme Court invalidated provisions regarding CFPB’s leadership structure but left it otherwise intact.

The latest attempt to finish off the CFPB came with impeccable conservative provenance. In 2022, a panel of the Fifth U.S. Circuit Court of Appeals — all appointed by former President Donald Trump — ruled that CFPB’s funding mechanism was unconstitutional. 

Before the Supreme Court, former solicitor general Noel Francisco, who clerked for late Justice Antonin Scalia and notoriously refused to defend the CFPB during his tenure in the Trump administration, argued for the payday lenders. A slew of friend-of-court briefs urged the court to sink the CFPB or at least cut off its funding, including conservative stalwarts like the U.S. Chamber of CommerceNew Civil Liberties Alliance, a coalition of Republican attorneys general, and the omnipresent John Eastman.

In a rebuff, the Supreme Court majority rejected these arguments, concluding its funding model was indeed constitutional. 

What divided the justices — even within the majority — was one of the central disagreements ushered in by Scalia and his fellow originalist revolutionaries on the bench: When the government faces thoroughly modern issues like regulating credit card penalties and semiautomatic weapons, should ancient history matter? 

Justice Thomas, an arch-originalist, went as far back as the Middle Ages, the Magna Carta, and the Glorious Revolution. His opinion, which was signed by the full majority, dwelled on how the First Congress allocated money to agencies, and barely peeked past 1800. 

In a concurring opinion, Justice Elena Kagan pointed out that there are a couple more centuries to consider. “The way our Government has actually worked, over our entire experience, thus provides another reason to uphold Congress’s decision about how to fund the CFPB,” Kagan wrote. Justice Sonia Sotomayor co-signed that view, along with conservative Justices Amy Coney Barrett and Brett Kavanaugh.

Justice Ketanji Brown Jackson, meanwhile, writing only for herself, suggested that sometimes ancient history has limited lessons for 21st-century issues like financial regulation. “In response to the devastation wrought by the 2008 financial crisis, Congress passed and the President signed the Dodd-Frank Wall Street Reform and Consumer Protection Act,” she wrote, noting that the payday lenders challenging CFPB were “exactly the type of entity the Bureau’s progenitors sought to regulate and whose influence Congress may have feared.”

“An essential aspect of the Constitution’s endurance is that it empowers the political branches to address new challenges by enacting new laws and policies — without undue interference by courts,” Jackson wrote.

In dissent, Justices Alito and Gorsuch howled that the “Framers would be shocked, even horrified” by the CFPB. Alito’s dissent cited Montesquieu, the practices of “the early Stuart kings” in the 1600s, and the accounting methods of Alexander Hamilton, and threw in a gratuitous shoutout to an infamous 17th-century witch trial judge, Sir Matthew Hale, who birthed the legal notion that husbands cannot be prosecuted for raping their wives, which continues to haunt legal systems worldwide. 

Alito concluded: “Today’s decision is not faithful to the original understanding of the Appropriations Clause and the centuries of history that gave birth to the appropriations requirement, and I therefore respectfully dissent.” 

The Court is expected to issue its remaining decisions regarding regulatory agencies’ authority and structure by July. 

Sen. Elizabeth Warren, D-Mass., who proposed establishing the CFPB as a law professor, praised the ruling but looked ahead to future challenges. 

“This isn’t the last attack on the CFPB we’ll see from Wall Street, the banks & their Republican allies,” Warren tweeted

In a First, Jewish Biden Administration Staffer Resigns Over War in Gaza

Portside
portside.org
2024-05-16 23:39:16
In a First, Jewish Biden Administration Staffer Resigns Over War in Gaza jay Thu, 05/16/2024 - 18:39 ...
Original Article

At first glance, the chalkboard sign looked like any of the others standing in front of Washington D.C.’s many restaurants and cafes.

But instead of advertising espresso or sandwiches, this one — across the street from a federal government building — displayed only one thing: the number of Palestinians killed in Israel’s war with Hamas, along with the words “Remember the people of Gaza.”

When it was taken down earlier this month after being vandalized, that number had passed 34,000 — a statistic quoted often in pro-Palestinian advocacy. But what made the blackboard different from the campus protests and others across the country was that the people keeping it current worked for the Biden administration, which has largely supported Israel and armed it as it has fought Hamas in Gaza.

Nearly all of the federal employees behind such efforts have kept their identities hidden — including the relatively few Jews in the movement. But a landmark moment in internal Jewish dissent came on Wednesday, when Lily Greenberg Call, special assistant to the chief of staff at the Department of Interior, announced that she was resigning in protest of President Joe Biden’s Israel policy — the first Jewish staffer among the several who have publicly resigned since Oct. 7.

“I can no longer in good conscience represent this administration amidst President Biden’s disastrous, continued support for Israel’s genocide in Gaza,” Greenberg Call, 26, wrote in her resignation letter, which she submitted to Secretary of the Interior Deb Haaland and shared on social media.

Greenberg Call, 27, attended Jewish day school and was a leader of a pro-Israel group in college, at the University of California, Berkeley, that was affiliated with AIPAC, the Washington lobby. She has previously written publicly about her move to the left on Israel, saying in a 2022 Teen Vogue essay that she had begun to question the idea of unconditional support for Israel after getting to know Arabs and Palestinians, including through her work on political campaigns. 

In her resignation letter, Greenberg Call said her family had come to the United States after escaping persecution in Europe and that she was concerned about rising antisemitism around the world now. But she said she did not believe the war aided in Jewish security.

“Israel’s ongoing offensive against Palestinians does not keep Jewish people safe — in Israel nor in the United States,” she wrote. “What I have learned from my Jewish tradition is that every life is precious. That we are obligated to stand up for those facing violence and oppression, and to question authority in the face of injustice.”

Lily Greenberg Call, as a teen leader in 2015: “Advocacy is not just a Band-Aid to cover and temporarily fix problems in society.”  (Photo courtesy of the Jewish Community Foundation of San Diego  //  Jewish Telegraphic Agency)

While Greenberg Call is the first Jewish Biden administration staffer to resign publicly over the war, others in her movement say she isn’t alone in her sentiments. In memos, in internal staff meetings, and in occasional bursts of public protest, a cadre of mid-level D.C. bureaucrats is dissenting from the Biden administration’s backing for Israel in the war. They describe crushing disappointment in an administration that they feel is committed to defending innocents from carnage elsewhere — most notably in Ukraine — but not, they say, in Gaza.

“There is nothing more American than the right to free speech and free assembly,” said a May 3 statement from Biden-Harris Administration Staffers for Ceasefire, an ad hoc group formed soon after the war broke out. 

The staffers say they have moved the needle a bit on policy — citing the increased flow of humanitarian aid to Gaza as an example — though they wish they’d had more impact. But their critics in the administration say their influence is negligible.

Those making the actual decisions say the dissent is background noise and that factors stemming from the crisis — and not the protests — are behind shifts in policy.

“These are people who are not involved in the policy discussions,” said a federal official who has a seat at the policy making table, “who are not in the room to hear senior-level policymakers make the case for both humanitarian assistance and describe what our expectations are when it comes to avoiding civilian harm and preventing violations of laws.”

The clandestine pro-Palestinian organizing began shortly after Hamas’ Oct. 7 invasion of Israel, which killed approximately 1,200 people and launched the war. As Israel began counterstrikes,  heads of various departments convened meetings to air concerns about Biden administration policy. Soon, S, a Jewish staffer who is part of the activist movement, was spearheading one of a number of letters to top Biden administration officials that called for a ceasefire. 

An Oct. 20 letter from Jewish and Muslim congressional staff calling for a ceasefire represented an early public action. A letter sent to Biden in November ultimately garnered a thousand signatures, and a White House vigil took place in December. Discussion of others has not abated.

“Word of mouth and WhatsApp are pretty active,” S said. 

Another convening point has been the Instagram account Dear White Staffers. Established in 2020 by an anonymous congressional staffer to post examples of how colleagues of color face discrimination, the account turned after Oct. 7 to decrying Biden’s war policies. The account has posted anonymous comments from administration staffers alongside news articles and calls to action such as alerts about D.C.-area pro-Palestinian protests. On Wednesday, it directed followers to Greenberg Call’s resignation letter.

P, a staffer for a congressional Democrat, joined one of the Jewish-led vigils in the Capitol that led to arrests. Contacts he forged through helping to set up the first union for congressional staffers helped lead to the letter from Hill staffers a few weeks later.

“We have continued to show up and speak at large rallies and marches,” he said.

S and P asked to be identified only by first initials in order to avoid professional repercussions. The Jewish Telegraphic Agency has verified their identities and their staff positions. Jewish groups that have organized ceasefire protests, including the anti-Zionist group Jewish Voice for Peace and IfNotNow, confirmed that they are among the groups’ active participants within the government.

IfNotNow distributed Greenberg Call’s resignation letter on Wednesday.

The Jewish activists who spoke to JTA believe they are among the few Jewish voices in the movement because of the pressures pro-Palestinian Jews feel from their communities at home. Others in the executive branch support Biden’s position. 

“I definitely feel like I’m one of the only Jewish voices in the group chats,” said S.

The dissenters point to Biden’s increased pressure on Israeli Prime Minister Benjamin Netanyahu to allow in humanitarian aid to the Gaza Strip, and measures to hold accountable alleged Israeli perpetrators of abuses, as evidence they made a difference.

But Julie Fishman Rayman, the American Jewish Committee managing director, said the dissenters have had more of an impact on the media than on actual policy in the government or in Congress. 

She noted that one of their key demands — a unilateral Israeli ceasefire — has not found support in the executive branch, or in Congress, where the majority of lawmakers calling for a ceasefire have insisted that it must be mutual and include a release of hostages.

“There are people who from the get-go were starting these calls for a one-sided ceasefire,” she said. “If they were reading the fine print here, they would see that argument has not gained any currency.”

A congressional staffer told JTA that the flood of calls from constituents opposing the war had been more influential than the internal dissenters. “They are way less impactful than a bunch of angry constituents who are calling day in and day out and are better organized,” the staffer said.

Asked for comment, a State Department official referred JTA to remarks recently by spokesman Vedant Patel, when he was asked about the resignation of Hala Rharrit, the spokeswoman for Arab media. Rharrit quit over Gaza policy, saying State Department staff were afraid to speak out in dissent. (At least one other staffer has publicly resigned from the department, while a Palestinian American staffer at the Department of Education resigned publicly in January.)

Secretary of State Antony Blinken “reads every single one of those dissent channel cables and dissenting viewpoints from across the administration,” Patel said. “We continue to welcome them and we think that it helps lead to stronger, more robust policy making.” 

Whether or not the internal protests are making a difference, pro-Palestinian activists say they are meaningful.

“Congressional and administration staffers have joined Palestinian solidarity marches, written dissent cables, signed open letters of disapproval, and in some cases publicly resigned,” Beth Miller, the political director of JVP Action, the political advocacy affiliate of Jewish Voice for Peace, told JTA. “Such public expressions of protest from people who are usually unwilling to do so should be a dire warning to the Biden administration to change course.”

Reflections on Student Activism – and the Struggle for a Better World

Portside
portside.org
2024-05-16 23:23:11
Reflections on Student Activism – and the Struggle for a Better World jay Thu, 05/16/2024 - 18:23 ...
Original Article

I’ve spent most of my life as an advocate for a more peaceful world. In recent years, I’ve been focused on promoting diplomacy over war and exposing the role of giant weapons companies like Lockheed Martin and its allies in Congress and at the Pentagon as they push for a “military-first” foreign policy. I’ve worked at an alphabet soup of think tanks: the Council on Economic Priorities (CEP), the World Policy Institute (WPI), the New America Foundation, the Center for International Policy (CIP), and my current institutional home, the Quincy Institute for Responsible Statecraft (QI).

Most of what I’ve done in my career is firmly rooted in my college experience. I got a bachelor’s degree in philosophy at Columbia University, class of 1978, and my time there prepared me for my current work — just not in the way one might expect. I took some relevant courses like Seymour Melman’s class on America’s permanent war economy and Marcia Wright’s on the history of the colonization of South Africa. But my most important training came outside the classroom, as a student activist.

Student Activism: Columbia in the 1970s

As I look at the surge of student organizing aimed at stopping the slaughter of Palestinians in Gaza, I’m reminded that participation in such movements can have a long-term impact, personally as well as politically, one that reaches far beyond the struggle of the moment. In my case, the values and skills I learned in movements like the divestment campaign against apartheid South Africa of the 1970s and 1980s formed the foundation of virtually everything I’ve done since.

I was not an obvious candidate to become a student radical. I grew up in Lake View, New York, a rock-ribbed Republican suburb of Buffalo. My dad was a Goldwater Republican, so committed that we even had that Republican senator’s “merch” prominently displayed in our house. (The funniest of those artifacts: a can of “Gold Water,” a sickly sweet variation on ginger ale.)

Although I fit in well enough for a while, by the time I was a teenager my goal had become all too straightforward: get out of my hometown as soon as possible. My escape route: Columbia University, where I expected to join a vibrant, progressive student movement.

Unfortunately, when I got there in 1973, the activist surge of the anti-Vietnam War era had almost totally subsided. By my sophomore year, though, things started to pick up. The September 1973 coup that overthrew the democratically elected socialist government of Chile’s Salvador Allende and the ongoing repression of the Black population in apartheid South Africa had sparked a new round of student activism.

My first foray into politics in college was joining the Columbia University Committee for Human Rights in Chile. It started out as a strictly student organization, but our activities took on greater meaning and our commitment intensified when we befriended a group of Chilean exiles who had moved into our neighborhood on New York’s Upper West Side.

In 1974, I also took time off to work in the New York branch of the United Farm Workers‘ boycott of non-union grapes, lettuce, and Gallo wine. I ran a picket line in front of the Daitch Shopwell supermarket at 110th and Broadway in Manhattan. One of my regulars on that picket line was an older gentleman named Jim Peck. It took a while before I learned that he had been a central figure in the Freedom Rides in the South during the late 1940s and early 1950s. He had first been arrested for civil rights organizing in 1947 in Durham, North Carolina, alongside the legendary Bayard Rustin. He and his fellow activists, black and white, went on to ride buses together across the South to press the case for the integration of interstate transportation. On a number of occasions, they would be brutally beaten by white mobs. In my own brief career as a student activist, I faced no such risks, but Jim’s history of commitment and courage inspired me.

When I got back from my stint with the United Farm Workers, the main political activity on the Columbia campus was a campaign to get the university to divest from companies involved in apartheid South Africa. We didn’t win then, but we did help put that issue on the map. Ten years later, a student divestment movement finally succeeded, and Columbia became the first major university to commit to fully divesting from South Africa. That modest victory, part of sustained anti-apartheid efforts on college campuses and beyond, would be followed nationwide by Congress’s passage of comprehensive sanctions on the apartheid regime, despite a veto attempt by then-President Ronald Reagan.
 

Buy the Book

Many of us kept working on the anti-apartheid issue after graduation. I remained a member of the New York Committee to Oppose Bank Loans to South Africa and, for a while, was also a member of the collective that put out Southern Africa Magazine in support of the anti-apartheid struggle and liberation movements in southern Africa. In New York, our mentors and inspirations in the anti-apartheid movement were people like Prexy Nesbitt, a charismatic organizer from Chicago, and Jennifer Davis, a South African exile who edited our magazine and went on to run the American Committee on Africa. For that magazine, I helped track companies breaking the arms embargo on South Africa as well as multinational corporations propping up the regime, an experience that served me well when I went on to become a researcher in the world of think tanks.

From Student Activist to Think-Tank Expert

By that time, I was fully engaged politically. As I approached the end of my four years at Columbia, however, it slowly dawned on me that I was going to have to get a real job. The good news was that, in my brief career as a student activist, I had learned some basic skills, including how to craft an article, give a speech, and run a meeting.

The bad news was that I had absolutely no idea how to find gainful employment. So, I went home to Lake View for a while and my mom, who was a member of the International Typographical Union, gave me a crash course in proofreading and how to use official proofreading symbols. On the strength of those lessons, I got a job at a New York print shop, where I spent a miserable year proofreading magazines like Psychology Today, Modern Bride, Skiing, Boating, and pretty much any other publication ending in -ing.

Then I got lucky. A friend had just turned down a job, mostly because the pay was so lousy, at the Council on Economic Priorities (CEP), a think tank founded to promote corporate social responsibility. But my expenses at the time were, to say the least, minimal, so I took the job.

The focus of my first CEP project was economic conversion, a process designed to help communities reduce their dependency on Pentagon spending. It had been launched by Gordon Adams (now Abby Ross), then finishing The Iron Triangle, his immensely useful analysis of the military-industrial complex. While at CEP, I wrote about the top 100 Pentagon contractors, the top 25 arms exporting firms, and the economic benefits of a nuclear weapons freeze. My goal: produce research that would help activists and advocates make their case.

And so it went. Other than a stint in New York State government from the mid-1980s through the early 1990s, I’ve been a think-tank analyst ever since. At the moment, most of the issues I’ve advocated for, from reducing the Pentagon budget to cutting nuclear arsenals, are heading in exactly the wrong direction. By contrast, though, the issues I worked on as a student did indeed make progress, though only after years of organizing. South Africa’s apartheid regime actually fell in 1992. In 1975, California Governor Jerry Brown pushed through a state law guaranteeing the right of farmworkers to organize. In Chile, Pinochet was ousted thanks to a 1988 national referendum and lived his last years as an international pariah, even spending 503 days under house arrest in the United Kingdom on charges of “genocide and terrorism that include murder.”

The main difference between the successful solidarity movements I participated in and the other political movements in which I’ve played some small part was that both the South Africa divestment campaign and the United Farm Workers (UFW) boycott took their leads from people and organizations on the front lines of the struggle. Solidarity movements contributed in a significant fashion to those victories, but the central players were those front-line organizations, from the African National Congress and the Black Consciousness Movement in South Africa to UFW organizers working in the fields of California.

The Student Movement for Gaza

Which brings me back to the state of current student activism. I live 10 blocks from the main gates of Columbia University, the site of one of the more active student organizations pressing for a ceasefire in Gaza and an end to government and institutional support for Israel’s brutal military campaign there, which has already killed nearly 35,000 people and left many others without medical care, adequate food, or clean water. The International Court of Justice has already suggested that a plausible case can be made for the Netanyahu government being guilty of genocide. Whether you use that term or simply call Israeli actions “war crimes,” the killing has to stop, which makes me proud of those Columbia student activists and deeply ashamed of the way the leadership of my former university has responded to them.

This April, when the president of Columbia called in the riot police to arrest students engaged in a peaceful protest, she inadvertently brought a whole new level of attention to activism about Gaza. Students at scores of campuses across the country started similar tent cities in solidarity with the Columbia students and protests that had largely been ignored in the mainstream media are now drawing TV cameras from outlets large and small.

Opponents of the student demonstrators, whose real goal is to get them to stop criticizing Israel’s mass slaughter of civilians in Gaza, have hurled claims of antisemitism at them that largely haven’t distinguished between actual acts of discrimination and cases of students feeling “uncomfortable” due to harsh — and wholly justified — criticisms of the Israeli government. As Judd Legum underscored at his substack Popular Information, there was no evidence of antisemitic acts by the students running the pro-ceasefire encampment at Columbia. Individuals and organizations outside the student movement seem to have been responsible for whatever hate rhetoric and related incidents have occurred.

Genuine antisemitism should be roundly condemned but confusing it with criticism of Israeli policies in Gaza will only make that job harder. And keep in mind that the Republican politicians hurling charges of antisemitism at students protesting repression in Gaza are, ironically enough, closely linked to actual antisemites.

To cite just one example, House Speaker Mike Johnson, who visited the Columbia campus last month in a purported effort to express his concern about antisemitism, has long promoted the racist “great replacement theory,” which holds that welcoming non-white immigrants is part of a plot to undermine the culture and power of white Americans. That theory has been cited by numerous perpetrators of racial and antisemitic violence, including the attacker who murdered 11 worshippers at the Tree of Life Synagogue in Pittsburgh in 2018.

Despite attempts to slander those student activists and divert attention from the devastation being visited on the people of Gaza, activists associated with groups like Jewish Voice for Peace and Students for Justice in Palestine continue to bravely build a vibrant movement that refuses to back down in the face of attacks by both college leaders and prominent donors. Such leaders have, in fact, interfered with student rights of assembly and free speech, suspended them for making statements critical of Israel, and used the police to break up protests. As the repression accelerates, with a surge of campus expulsions of protesters and the arrest of more than 2,500 students at more than 40 universities nationwide, the student activists continue to show courage under fire of a kind I was never called on to exhibit in my days in college. In the process, they have echoed the even larger protests of the anti-Vietnam War era.

If you were to look at a list of what the administrations at Columbia and other colleges and universities have done to student protesters in these weeks, without identifying the institutions doing it, you might reasonably assume that theirs was the work of autocratic regimes, not places purportedly dedicated to free inquiry and freedom of speech.

A number of universities — including Brown, Evergreen State, Middlebury, Rutgers, and Northwestern – have agreed to meet various student demands, from making formal statements in support of a ceasefire in Gaza to providing more transparency on university investments and agreeing to vote on divestment.  Meanwhile, President Biden has pledged to impose a partial pause on arms transfers to Israel if it launches a major attack on the residents of the vulnerable enclave of Rafah. But far more needs to be done to end the killing and begin to provide reparations for the unspeakable suffering of the Palestinians in Gaza, including a cutoff of the supply and maintenance of all the American weaponry that has been used to support the Israeli military effort.  Student organizing will continue, even in the face of ongoing efforts to smear the student rebels and divert attention from the mass killing of Palestinians. Those students remain remarkably (and bravely) determined to end this country’s shameful policy of enabling Israel’s devastating assault and they are clearly not about to give up.

Today’s Campaigns and Tomorrow’s

One thing is guaranteed: the commitment of this generation of student activists will reverberate through the progressive movement for years to come, setting high standards for steadfast activism in the face of the power of repression. Many of the activists from my own years on campus have remained in progressive politics as union organizers, immigration reform advocates, peace and racial justice activists, or even, like me, think-tank researchers. And don’t be surprised if the ceasefire movement has a similar impact on our future, possibly on an even larger scale.

Face it, we’re living through difficult times when fundamental tenets of our admittedly flawed democracy are under attack, and openly racist, misogynist, anti-gay, and anti-trans rhetoric and actions are regarded as acceptable conduct by all too many in our country. But the surge of student activism over Gaza is just one of many signs that a different, better world is still possible.

To get there, however, it’s important to understand that, even as we rally against the crises of the moment, suffering both victories and setbacks along the way, we need to prepare ourselves to stay in the struggle for the long haul. Hopefully, the current wave of student activism over the nightmare in Gaza will prove to be a catalyst in creating a larger, stronger movement that can overcome the most daunting challenges we face both as a country and a world.

[William D. Hartung, a TomDispatch regular, is a senior research fellow at the Quincy Institute for Responsible Statecraft and the author of Prophets of War: Lockheed Martin and the Making of the Military-Industrial Complex.]

Copyright 2024 William D. Hartung. Cross-posted with permission. May not be reprinted without permission from TomDispatch.

Follow TomDispatch on Twitter and join us on Facebook. Check out the newest Dispatch Books, John Feffer’s new dystopian novel, Songlands (the final one in his Splinterlands series), Beverly Gologorsky’s novel Every Body Has a Story, and Tom Engelhardt’s A Nation Unmade by War, as well as Alfred McCoy’s In the Shadows of the American Century: The Rise and Decline of U.S. Global Power, John Dower’s The Violent American Century: War and Terror Since World War II, and Ann Jones’s They Were Soldiers: How the Wounded Return from America’s Wars: The Untold Story.

Pump.fun suffers $2 million loss to former employee who claims he wanted to "kill" the project for "inadvertently hurt[ing] people"

Web3 Is Going Great
web3isgoinggreat.com
2024-05-16 22:19:23
Pump.fun is a Solana-based memecoin generator that soared to popularity recently amid a resurgence in memecoin trading. On May 16, the project suffered a $2 million exploit by an attacker who then began airdropping the money to somewhat random wallets.A former employee — whose real identity...
Original Article

Pump.fun is a Solana-based memecoin generator that soared to popularity recently amid a resurgence in memecoin trading. On May 16, the project suffered a $2 million exploit by an attacker who then began airdropping the money to somewhat random wallets.

A former employee — whose real identity is known — brazenly took credit for the theft on Twitter. They wrote: "everybody be cool, this is a r o b b e r y. ... I'm about to change the course of history. n then rot in jail. am I sane? nah. am I well? v much not. do I want for anything? my mom raised from the dead n barring that: life without parole."

In a Twitter Spaces chat, the attacker stated that he had worked for the company briefly, and that he had grievances against its management. "I just kind of wanted to kill Pump.fun because it's something to do... It's inadvertently hurt people for a long time," he said.

Pump.fun paused trading shortly after the attack, and stated that they were "cooperating with relevant parties, including law enforcement, to minimize the damage." The attacker responded to the post: "Neener neener neener".

Trump’s War on Government Will Take Public Health Back a Century

Portside
portside.org
2024-05-16 22:08:55
Trump’s War on Government Will Take Public Health Back a Century jay Thu, 05/16/2024 - 17:08 ...
Original Article

Visiting nurse entering a row home surrounded by children and adults, Visiting Nurse Society of Philladelphia, c, 1890 (Penn Nursing, University of Pennsylvania),

It’s perhaps hard to imagine today, but we have two landmark books to thank for some of the U.S. government’s most vital public health regulations. Upton Sinclair’s The Jungle, published in 1905, shined a light on the unsanitary and unsafe practices of the meatpacking industry and eventually led to the creation of the Food and Drug Administration, which regulates the safety of products for human consumption. In 1962, Rachel Carson’s Silent Spring exposed the toxicity of the pesticide DDT, which helped lay the groundwork for the creation of the Environmental Protection Agency. Today, these two agencies are part of a multitude of government regulatory bodies that ensure the health and safety of Americans.

Those bodies now find themselves under threat from right-wing politicians and legal activists alike, who together are working to gut the so-called administrative state on the grounds that it is supposedly bloated, leftist, and too powerful. But these efforts, which include two Supreme Court cases this term as well as Donald Trump’s second-term plans, would have tangible and severe consequences not just for those who keep our government functioning every day but for the hundreds of millions of Americans who rely on that government to keep them safe and healthy.

The federal government is a gargantuan institution tasked with regulating all sorts of small but consequential minutiae of American life—everything from regulations on airline safety to workplace standards for dealing with hazardous chemicals. Congress grants agencies the power to set these rules themselves—the FDA is governed by the Federal Food, Drug, and Cosmetic Act of 1938, while the EPA’s power is spread among laws like the Clean Air and Clean Water Acts—because Congress itself has neither the time nor the expertise to decide, or even simply review, the thousands of rules finalized every year.

But conservatives want to eliminate these agencies’ long-standing legal authority, and they just might succeed thanks to two consequential cases before the Supreme Court. One is a challenge to the FDA’s approval of mifepristone, the abortion medication, which the plaintiffs—a coalition of anti-abortion medical professionals—claim was insufficiently vetted. In oral arguments last month, the Supreme Court signaled it might find that the plaintiffs do not have standing, but if the justices decide otherwise and side with the plaintiffs, experts warn that the FDA’s regulatory processes would be completely undermined. People would have the ability to challenge drugs for any reason, political or otherwise.

Things are far grimmer with the second case, which calls upon the Supreme Court to overturn Chevron v. NRDC. That 1984 ruling established the so-called Chevron doctrine, effectively allowing the EPA and federal agencies to use their relevant expertise to interpret ambiguous federal statutes when they make rules; courts then defer to regulatory agencies’ expertise. To put it plainly, if congressional bills had to outline every specific instance in which an agency had to act, Congress would have to update bills constantly for regulatory agencies to function.

The EPA is not the one facing scrutiny in this case, but rather the National Marine Fisheries Service, a division of the National Oceanic and Atmospheric Administration. In arguments in January, the Supreme Court appeared willing to disregard or limit the Chevron ruling completely, which would make expert decisions made by regulatory agencies subject to far more legal scrutiny. Just like the aforementioned FDA case, a judge can override the expertise of regulatory agencies and overturn rules, however specific and niche they may be. Public health experts have warned that this would dramatically limit the ability of agencies like the FDA and Center for Medicare and Medicaid Services to operate by subjecting them to routine legal interference.

Some examples of these rules implemented in the past year include: rules reducing methane from oil and gas production, rules allowing for increased dosages of methadone and allowing take-home doses, rules allowing for the health care coverage of Deferred Action for Childhood Arrivals recipients, and much more. Every year, there are between 3,000 and 4,500 rules published in the Federal Register, according to the Congressional Research Service. Collectively, these rules help ensure that federal agencies can implement their mandate—they all touch on small but significant aspects of people’s lives. Disrupting this process may be disastrous.

Beyond legal attacks, conservative activists want to dramatically reduce the size of the federal workforce and remove civil service protections, thereby turning long-standing federal employees into essentially political appointees, serving at the pleasure of the president. Late in his presidency, Trump signed an executive order to strip away those protections for tens of thousands of government workers, but Joe Biden’s victory put an end to that—for now. Trump, if he wins, is expected to try to reenact the order, and he’s got some help from the Heritage Foundation, whose Project 2025 is working “to assemble an army of aligned, vetted, trained, and prepared conservatives to go to work on Day One to deconstruct the Administrative State.”

One can imagine the dire future if the federal government is remade in this way, especially during a pandemic. Once again, a highly contagious virus is spreading through the United States and a right-wing government is not interested in tackling the spread of the disease. When the president says the seasonal flu is worse than a pandemic and is contradicted by top disease experts at the National Institutes of Health, he fires them. When a vaccine is finally developed and approved by the FDA for emergency use, the decision is overturned by a court when a coalition of states brings about a lawsuit questioning the safety behind the vaccine. Left without proper information from the government and no access to a vaccine, thousands more die.

At the heart of the conservative push to defang federal agencies is a belief that the government should not impede the ability of companies to make a profit, and that health and safety are an individual responsibility. But public health regulations exist for a painfully obvious reason: Environmental and societal factors are necessarily beyond an individual’s control, and they can lead to bad health outcomes. You can eat well and exercise but ultimately still develop cancer from living a few miles from a plastics factory. In fact, as Jessie Singer argues in There Are No Accidents, many of the major causes of death in the U.S.—car accidents, overdoses, and other things we consider tragedies or accidents—are the result of negligent policy. Regulatory agencies like the FDA are the ones we task to fix, improve, and maintain that policy.

Things are not perfect, of course. These agencies are just as subject to corporate influence as any other arm of government. The FDA controversially approved a now abandoned Alzheimer’s drug, and the EPA recently approved a fuel made from plastic that produces carcinogenic toxic emissions. But that’s all the more reason these agencies need strengthening and that weakening them would be catastrophic.

Americans are dying at a younger age: Life expectancy has declined, people are getting cancers at a younger age, overdoses are the top killer of people age 18 to 45, and maternal mortality has skyrocketed. We should be aggressively expanding regulations that target the causes of death and disease. Instead, we are threatened by the prospect of going back in time, when there were no protections for your safety on the job, no recourse for being poisoned in your backyard.

[Abdullah Shihipar is a writer and researcher based at the Brown University School of Public Health. He directs Narrative Projects and Policy Impact Initiatives at the People, Place and Health Collective at Brown. @AShihipar]

Outside Groups Spent $285,000 Backing Jamaal Bowman. AIPAC Alone Just Dropped Nearly $2 Million to Attack Him.

Intercept
theintercept.com
2024-05-16 22:08:07
With Bowman’s challenger handpicked by AIPAC, the Israel lobby is cementing its status as the biggest player in Democratic primary politics. The post Outside Groups Spent $285,000 Backing Jamaal Bowman. AIPAC Alone Just Dropped Nearly $2 Million to Attack Him. appeared first on The Intercept....
Original Article

The American Israel Public Affairs Committee’s super PAC has launched its first ads attacking Rep. Jamaal Bowman in the Democratic primary in New York’s 16th Congressional District. The ads claim that Bowman “has his own agenda” and refuses to work with President Joe Biden. 

United Democracy Project, the AIPAC super PAC, bought its first set of ads this week for $1.9 million, disclosing that it planned to spend the money in a week, to oppose Bowman in the race against Westchester County executive George Latimer. The primary election takes place June 25.

Latimer, who was recruited to run by AIPAC and has received huge contributions directly from the group, has had nearly a million dollars of support from outside groups before AIPAC weighed in. Bowman also has outside support, but it’s a fraction of AIPAC’s spending so far for Latimer. Known as “independent expenditures,” outside groups can weigh in on elections but not in coordination with campaigns. 

With the new AIPAC money to attack Bowman, outside groups in the race are spending nearly 10 times more in Latimer’s favor — with roughly $3 million total for Latimer and against Bowman, and Bowman supporters spending only about $285,000. 

Latimer is also raking in more cash than Bowman in direct campaign contributions. His campaign itself has raised $3.6 million so far to Bowman’s $2.7 million. Latimer’s haul includes major support from Republican donors — almost a quarter of it was bundled by AIPAC. In the last quarter of 2023, almost half of Latimer’s contributions came through AIPAC. 

“Trump Republicans are funding a $1.9 million ad spend to distract us from their attempt to buy our seat.”

“NY-16 Democrats are united in rejecting MAGA’s threat to our freedoms, which is why Trump Republicans are funding a $1.9 million ad spend to distract us from their attempt to buy our seat,” Bowman campaign spokesperson Lawrence Wang said in a statement to The Intercept. “But voters know the truth: if MAGA’s top priority is unseating Jamaal Bowman, ours is to re-elect him.”

United Democracy Project did not respond to a request for comment.

Latimer has courted Republican donors and held fundraisers hosted by Republicans, including a major GOP donor to former President Donald Trump. Another AIPAC donor has been encouraging Republicans to switch parties to vote against Bowman in the primary — one Republican voter told The Intercept he recently switched parties just to vote for Latimer. Latimer’s campaign distanced itself from the GOP-hosted fundraisers and said he had no control over who hosted fundraising events.

The big outside spending push by AIPAC helps cement its status as one of if not the biggest spender in Democratic Party primaries. The pro-Israel lobby planned to spend $100 million this cycle to oust members of the Squad who have been critical of U.S. military funding for Israel and led calls for a ceasefire in Gaza.

After failing to unseat Rep. Summer Lee, D-Pa., AIPAC’s next top targets are Bowman and Rep. Cori Bush, D-Mo. AIPAC recruited Latimer to run against Bowman and has backed Bush’s challenger, Wesley Bell. Its super PAC is expected to spend up to $20 million on each race. 

Known as “independent expenditures,” outside groups like PACs can spend unlimited amounts on elections but are not supposed to coordinate with campaigns. In practical terms, however, a system of winks and nods can help campaigns point outside spenders to ideas about messaging — a tactic AIPAC has availed itself of.

AIPAC’s Primary Occupation

The race between Bowman and Latimer has been a chaotic one. Latimer’s campaign came under scrutiny when it first launched for leaving the Bronx, part of which is in the district, off of his website and only mentioning Westchester County, which is a primarily white suburb. Latimer was also criticized for comments claiming that Bowman took money from Hamas. Latimer told City & State that he wouldn’t be able to win if more Bronx voters were drawn in as part of redistricting. 

Bowman has had his own share of snafus. His decision to pull the fire alarm in Congress over the summer has plagued the campaign and become fodder in new attack ads. Critics have also raised questions about conspiratorial content he follows on YouTube, though it’s unclear whether he has watched or engaged with the videos. 

In a Twitter thread posted Thursday, Lee, the Pennsylvania representative who just won her primary, criticized AIPAC for targeting Black Democrats while using its support for members of the Congressional Black Caucus as cover. “While the biggest threat to Black America is white supremacist policymakers, they financially support the folks causing us the most harm,” Lee wrote. 

AIPAC supported several candidates of color last cycle, including Glenn Ivey, Adam Hollier, Henry Cuellar, Shontel Brown, Valerie Foushee, and Don Davis. Almost all of AIPAC’s independent expenditures against Democrats in the 2022 primaries were spent against candidates of color. The rest was spent against former Rep. Andy Levin, a Jewish member of Congress

Usamah Andrabi, a spokesperson for Justice Democrats, which spent at least $165,000 on mail and digital ads supporting Bowman and attacking Latimer’s GOP ties, said that Republicans were using United Democracy Project to target Democrats of color. The Working Families Party has spent $118,000 so far to support Bowman, with plans for additional spending. 

“This is the same tactic we’ve seen across the country, Republican billionaires using AIPAC’s super PAC to spend millions of dollars targeting Democrats of color in Democratic primaries,” Andrabi said. “Voters should know that every ad they see attacking Jamaal Bowman or defending George Latimer is being funded by the same GOP megadonors who want to ban abortion, defend insurrectionists, and elect Donald Trump.”

Moment: A Family of Open Time-Series Foundation Models

Hacker News
arxiv.org
2024-05-17 02:42:09
Comments...
Original Article

View PDF HTML (experimental)

Abstract:We introduce MOMENT, a family of open-source foundation models for general-purpose time series analysis. Pre-training large models on time series data is challenging due to (1) the absence of a large and cohesive public time series repository, and (2) diverse time series characteristics which make multi-dataset training onerous. Additionally, (3) experimental benchmarks to evaluate these models, especially in scenarios with limited resources, time, and supervision, are still in their nascent stages. To address these challenges, we compile a large and diverse collection of public time series, called the Time series Pile, and systematically tackle time series-specific challenges to unlock large-scale multi-dataset pre-training. Finally, we build on recent work to design a benchmark to evaluate time series foundation models on diverse tasks and datasets in limited supervision settings. Experiments on this benchmark demonstrate the effectiveness of our pre-trained models with minimal data and task-specific fine-tuning. Finally, we present several interesting empirical observations about large pre-trained time series models. Pre-trained models (AutonLab/MOMENT-1-large) and Time Series Pile (AutonLab/Timeseries-PILE) are available on Huggingface.

Submission history

From: Mononito Goswami Mr. [view email]
[v1] Tue, 6 Feb 2024 10:48:46 UTC (3,105 KB)
[v2] Tue, 14 May 2024 03:04:01 UTC (3,127 KB)

WD Releases New 6TB 2.5-Inch External Hard Drives – First Upgrade in Seven Years

Hacker News
www.anandtech.com
2024-05-17 02:19:37
Comments...
Original Article

The vast majority of laptops nowadays use solid-state drives, which is why the development of new, higher-capacity 2.5-inch hard drives has all but come to a halt. Or rather, it almost has. It seems that the 2.5-inch form factor has a bit more life left in it after all, as today Western Digital has released a slate of new external storage products based on a new, high-capacity 6 TB 2.5-inch hard drive.

WD's new 6 TB spinner is being used to offer upgraded versions of the company's My Passport, Black P10, and and G-DRIVE ArmorATD portable storage products. Notably, however, WD isn't selling the bare 2.5-inch drive on a standalone basis – at least not yet – so for the time being it's entirely reserved for use in external storage.

Consequently, WD isn't publishing much about the 6 TB hard drive itself. The maximum read speed for these products is listed at 130 MB/sec – the same as WD's existing externals – and write performance goes unmentioned.

Notably, all of these 6 TB devices are thicker than their existing 5 TB counterparts, which strongly suggests that WD has increased their storage capacity not by improving their areal density, but by adding another platter to their existing drive platform. This, in turn, would help to explain why these new drives are being used in external storage products, as WD's 5 TB 2.5-inch drives are already 15mm thick, which is the highest standard thickness for a 2.5-inch form-factor, and already incompatible with a decent number of portable devices. External drives, in turn, are the only place these even thicker 2.5-inch drives would fit.

WD's specifications also gloss over whether these drives are based on shingled magnetic recording (SMR) technology. The company was already using SMR for their 5 TB drives in order to hit the necessary storage density there, so it seems very likely that they're continuing to use SMR for their 6 TB drives. Which is likely why the company isn't publishing write performance specifications for the drives, as we've seen SMR drives bottom out as low as 10 MB/second in our testing when the drive needs to rewrite data.

Depending on the specific drive model, all of the external storage drives use either a USB-C connector, or the very quaint USB Micro-B 3.0 connector. Though regardless of the physical connector used, all of the drives feature a USB 3.2 Gen 1 (5Gbps) interface, which is more than ample given the drives' physically-limited transfer speeds.

Wrapping things up, according to WD the new drives are available at retail immediately. The WD My Passport Ultra and WD My Passport Ultra for Mac with USB-C both retail for $199.99; the WD My Passport and WD My Passport for Mac are $179.99; the WD My Passport Works With USB-C is $184.99; the gaming-focused WD_Black P10 Game Drive sells for $184.99, and the SanDisk Professional G-Drive ArmorATD is $229.99. All of Western Digital's external storage drives are backed with a three-year limited warranty.

Source: Western Digital

It was online for 3 seconds before getting a 404 request for /.git/config

Hacker News
honeypot.net
2024-05-17 02:16:13
Comments...
Original Article

I am not exaggerating this:

I created a new hostname in DNS, then added it to my existing webserver config.

It was online for 3 seconds – 3! – before getting a 404 request for /.git/config.

If you’re relying on obscurity to protect your services, get that right out your fool head today. You have about 3 seconds to get your act together.

In the time it took me to type this, I got another 62 requests:

     30 "/"
      3 "/.git/config"
      2 "/.vscode/sftp.json"
      2 "/v2/_catalog"
      2 "/telescope/requests"
      2 "/server-status"
      2 "/server"
      2 "/s/431323e2230323e2134323e2239313/_/;/META-INF/maven/com.atlassian.jira/jira-webapp-dist/pom.properties"
      2 "/?rest_route=/wp/v2/users/"
      2 "/login.action"
      2 "/.env"
      2 "/ecp/Current/exporttool/microsoft.exchange.ediscovery.exporttool.application"
      2 "/.DS_Store"
      2 "/debug/default/view?panel=config"
      2 "/config.json"
      2 "/_all_dbs"
      2 "/about"

A Transport Protocol's View of Starlink

Hacker News
www.potaroo.net
2024-05-17 01:17:02
Comments...
Original Article

A column on things Internet

Other Formats:

PDF

 

TXT

 


A Transport Protocol’s View of Starlink
May 2024

Digital communications systems always represent a collection of design trade-offs. Maximising one characteristic of a system may impair others, and various communications services may chose to optimise different performance parameters based on the intersection these design decisions with the physical characteristics of the communications medium. In this article I’ll look at the Starlink service [1], and how TCP, the workhorse transport protocol of the Internet, interacts with the characteristics of the Starlink service.


Figure 1 – Orbiting Bodies from Newton’s Principia Mathematica

To start, its useful to recall a small item of Newtonian physics from 1687 [2]. On the surface of the earth if you fire a projectile horizontally it will fall back to earth due to the combination of the effects of the friction from the earth’s atmosphere and the earth’s gravitational force. However, assuming that the earth has no friction-inducing atmosphere, then if you fire this projectile horizontally fast enough it will not return to the earth, but head into space. If you are high enough to clear various mountains that may be in the way, there is, however, a critical velocity where the projectile will be captured by the earth’s gravity and neither fall to ground nor head out into space (Figure 1).

This orbital velocity at the surface of the earth is some 40,320 km/sec. The orbital velocity decreases with altitude, and at an altitude of 35,786 km above the surface of the earth the orbital velocity of the projectile relative to a point on the surface of the spinning earth is 0 km/sec. This is the altitude of a geosynchronous equatorial orbit, where the orbiting object appears to sit at a fixed location in the sky.

Geosynchronous Services

Geosynchronous satellites were the favoured approach for the first wave of satellite-based communications services. Each satellite could “cover” an entire hemisphere. If the satellite was on the equatorial plane, then it was at a fixed location in the sky with respect to the earth, allowing the use of large antenna. These antennas were able to operate at a low signal to noise ratio, allowing the signal modulation to use an encoding with a high density of discrete phase amplitude points, which lifted the capacity of the service.

All this must be offset against the less favourable aspects of a geosynchronous service. Consideration of crosstalk interference between adjacent satellites in geosynchronous orbits using the same radio frequencies resulted in international agreements that require a 2° spacing for geosynchronous satellites that use the same frequency, so this orbital slot is a limited resource that is limited to just 180 spacecraft if they all use K band (18 – 27Ghz) radio systems. At any point on the earth there is an upper bound to the signal capacity that can be received (and sent) using geosynchronous services.

Depending on whether the observer is on the equator directly beneath the satellite, or further away from this point, a geosynchronous orbit satellite is between 35,760 and 42,664 km away, so a signal round trip time to the geosynchronous satellite and back will between 238ms and 284ms in terms of signal propagation time. In IP terms, that’s a round trip time of between 477 and 569ms and to this needs to be added the signal encoding and decoding times. In addition, there is a delay for the signal to be passed between the terrestrial end points and the satellite earth stations. In practice, a round trip time of around two thirds of a second (660ms) for Internet paths that include a geosynchronous satellite service is a common experience.

This extended latency means that the endpoints need to use large buffers to hold a copy of all the unacknowledged data, as is required by the TCP protocol. TCP is a feedback-governed governed protocol, using ACK pacing. The longer the round time the greater the lag in feedback, and the slower the response from end points to congestion or to available capacity. The congestion considerations lead to the common use of large buffers in the systems driving the satellite circuits which can further exacerbate congestion-induced instability. In geosynchronous service contexts, individual TCP sessions are more prone to instability and experience longer recovery times following low events as compared to their terrestrial counterparts, when such counterparts exist [3].

Low Earth Orbit Systems

A potential response to the drawbacks of geosynchronous satellites is to bring the satellite closer to earth. This approach has several benefits. The earth’s spinning iron core generates a magnetic field, which traps energetic charged solar particles and redirects them through what is called the “Van Allen Belt”, thus deflecting solar radiation. Not only does this allow the earth to retain its atmosphere, but it also protects the electronics of orbiting satellites that use an orbital altitude below 2,000 km or so from the worst effects of solar radiation (such as the recent solar storms). It’s also far cheaper to launch satellites into a low earth orbit, and these days SpaceX is able to do so using re-usable rocket boosters.

The reduced distance between the earth and the orbiting satellite reduces the latency in sending a signal to the satellite and back which can improve the efficiency of the end-to-end packet transport protocols that include such satellite circuits.

This group of orbital altitudes, from some 160km to 2,000km, are collectively termed Low Earth Orbit (or LEOs) [4]. The objective here is to keep the satellite’s orbit high enough to prevent it slowing down by grazing the upper parts of the earth’s ionosphere, but not so high that it loses the radiation protection afforded by the Inner Van Allen belt [5]. At a height of 550km, the minimum signal propagation delay to reach the satellite and back from the surface of the earth is just 3.7ms.

But all of this comes with some different issues. At a height of 550km an orbiting satellite can only be seen by a small part of the earth. If the minimum effective elevation to establish communication is 25 degrees of elevation above the horizon, then the satellite’s footprint is a circle with a radius of 940km, or a circle of area 2M km2. (Lower angles of elevation are possible but the longer the path segment through the earth’s atmosphere decreases the signal to noise ratio, compromising the available signal capacity as well as increasing the total path delay.) To provide continuous service to any point on the earth’s surface (510.1M km2) the minimum number of orbiting satellites is 500. This use of a constellation of satellites implies that a LEO satellite-based service is not a simple case of sending a signal to a fixed point in the sky and having that single satellite mirror that signal down to some other earth location. A continuous LEO satellite service needs to hop across a continual sequence of satellites as they pass overhead and switch the virtual circuit path across to successive satellites as they come into view of both the end user and the user’s designated earth station.

At the altitude of 550 km, an orbiting satellite is moving with a relative speed of 27,000 km/hour relative to a point on the earth’s surface and passes across the sky from horizon to horizon in under 5 minutes. This has some implications for the design of the radio component of the service. If the satellite constellation is large enough, then the satellites are close enough to each other that there is no need to use larger dish antennae that require some mechanised steering arrangement that tracks individual satellites in their path across the sky, but this itself it not without its downside. An individual signal carrier might be initially acquired as a weak signal (in relative terms), increases in strength as the satellite’s radio transponder and the earth antenna move into alignment, and weakens again as the satellite moves on. Starlink’s antennae use a phased array arrangement using a grid of smaller antennae on a planar surface. This allows the antenna to be electronically steered by altering the phase difference between each of the antennae in the grid. Even so, this is a relatively coarse arrangement, so the signal quality is not consistent. This implies a constantly varying Signal to Noise Ratio (SNR) as the phased array antenna tracks each satellite during its overhead path.

It appears that Starlink services use dynamic channel rate control as a response to this constantly varying SNR. The transmitter constantly adjusts the modulation and coding scheme to match the current SNR, as described in the IEEE 802.11ac standard. The modulation of this signal uses adaptive phase amplitude modulation, and as the SNR improves the modulator can use a larger number of discrete code points in this phase amplitude space, thus increasing the effective capacity of the service while using a constant frequency carrier signal. What this implies is that the satellite service is attempting to operate at peak carriage efficiency, and to achieve this the transmitter constantly adapts its signal modulation to take advantage of the instantaneous SNR from the satellite system. To the upper layer protocol drivers, the transmission service appears to have a constantly varying channel capacity and latency.

The Starlink satellite’s Ku-band downlink has a total of 8 channels using frequency division multiplexing. Each channel has an analogue bandwidth of 240Mhz. Each channel is broken into frames, which is subdivided using time division multiplexing into 302 intervals, each of 4.4µs, which together with a frame guard interval makes each frame 1,333µs, or 750 frames per second. Each frame contains a header that contains satellite, channel and modulation information [6]. The implication is that there is a contention delay of up to 1.3ms assuming that each active user is assigned at least one interval per frame.

This leaves us with four major contributory factors for variability of the capacity of the Starlink service, namely:

  • the variance in signal modulation capability, which is a direct outcome of the varying SNR of the signal,
  • the variance in the satellite path latency due to the relative motion of the satellite and the earth antennae,
  • the need to perform satellite switching on a regular basis, and
  • the variability induced by sharing the common satellite transmission medium with other users, which results in slot contention.

One way to see how these variability factors impacts on the service characteristics is to use a capacity measurement tool to measure the service capacity on a regular basis. The results of such a capacity measurement test in a Starlink service are shown in Figure 2. Here the test is a SpeedTest measurement test [7], performed on a 4-hourly basis for the period August 2023 through March 2024. The service appears to have a median value of around 120Mbps of download capacity, with individual measurements reading as high as 370Mbps and as low as 10Mbps, and 15Mbps of upload capacity, with variance of between 5Mbps to 50Mbps.


Figure 2 – Starlink Performance

In Internet terms ping [8] is a very old tool, but at the same time it’s still a very useful tool, which probably explains its longevity. Figure 3 is a plot of a continuous (flood) ping across a Starlink connection from the customer side terminal to the first IP end point behind the Starlink earth station for a 380 second interval. (A “flooding” ping sends a new ping packet each time a packet is received from the remote end).


Figure 3 – Starlink Ping Profile

The first major characteristic that is visible in this ping data is that the minimum latency changes regularly every 15 seconds. It appears that this change correlates to the Starlink user’s terminal being assigned to a different satellite. That implies that the user equipment “tracks” each satellite for a 15 second interval, which corresponds to a tracking angle of 11 degrees of arc.

The second characteristic is that loss events are seen to occur at times of switchover between satellites, as well as occurring less frequently as a result of either obstruction, signal quality or congestion.


Figure 4 – Starlink Ping Profile showing satellite handover

The third is that there is a major increase in latency at the point when the user is assigned to a different spacecraft. The worst case in this data set is a shift from 30ms to 80ms.

Finally, within each 15s satellite tracking interval the latency variation is relatively high. The average variation of jitter between successive RTT intervals is 6.7ms. The latency spikes at handover impose an additional 30ms to 50ms indicating the presence of deep buffers in the system to accommodate the transient issues associated with satellite handover. To illustrate this link behaviour the ping data set has been filterred to remove the effects of the satellite assignment at second 283 and second 298. (Figure 5).


Figure 5 – Starlink Ping Profile showing latency variance

The overall packet loss rate, when measuring using 1-second paced pings over an extended period is a little over 1% as a long-term average loss rate.

TCP Protocol Performance

TCP [9] is an instance of a sliding window positive acknowledgement protocol. The sender maintains a local copy of all data that has been passed into the local system’s IP layer and will only discard that local copy of sent data when it has received a positive acknowledgement from the receiver.

Variants to TCP are based on the variations in the sender’s control of the rate of passing data into the network and variations in the response to data loss. The classic version of TCP is one that uses a linear inflation of the sending window size while there is no loss, and halves this window in response to packet loss. This is the RENO TCP control algorithm. Its use in today’s Internet has been largely supplanted by the CUBIC TCP control algorithm [10] which uses a varying window inflation rate that attempts to stabilise the sending rate at a level just below the build-up of network queues (which ultimately leads to packet loss).

In general terms there is a small set of common assumptions about the characteristics of the network path for such TCP control algorithms:

  • There is a stable maximal capacity of the path, where the term stability describes a situation where the available path capacity is relatively constant across a number of RTT intervals.
  • The amount of jitter (variation in end-to-end delay) is low in proportion to the RTT.
  • >The average packet loss rate is low. In the case of congestion-based loss TCP control algorithms packet loss is generally interpreted by the algorithm as a sign that the network’s buffers have filled, and loss is an indication of buffer overflow.

    Obviously, as we’ve noted, the first two conditions do not necessarily hold for end-to-end paths that include a Starlink component. The loss profile is also different. There is the potential for congestion-induced packet loss, as is the case in any non-synchronous packet switched medium, but there is an additional loss component that can occur during satellite handover, and a further loss component that can be caused by other impairments imposed upon the radio signal.

    TCP typically tends to react to such environments by using conservative choices.

    The RTT estimate is a smoothed average value of RTT measurements, to which is added the mean deviation of individual measurements from this average. For Starlink, with its relatively high level of individual variance in RTT measurements this means that the TCP sender may operate with a RTT estimate that is higher than the minimum RTT, which may result in a sending rate that is lower than the available end-to-end capacity of the system.

    The occurrence of non-congestion-based packet loss can also detract from TCP performance. Conventionally, loss will cause the sender to quickly reduce its sending window, on the basis that if this loss is caused by network buffer overflow, then the sender needs to allow these buffers to drain, and then it will resume sending as a lower rate, which should restore coherency of the feedback control loop.

    How does this work in practice?

    Figure 6 shows a detailed view of a TCP cubic session over a Starlink circuit. The initial 2 seconds shows the slow start TCP sending rate inflation behaviour, where the sending window doubles in size for each RTT interval, reaching a peak of 240Mbps in 2 seconds. The sender then switches to a mode of rapid reduction of the sending window in the next second, dropping its sending rate to 50Mbps within one second. At this point the CUBIC congestion avoidance phase appears to kick in, and the sending rate increases to 70Mbps over the ensuing 5 seconds. There is a single loss event which cases the sending rate to drop in second 8 back to 40Mbps. The remainder of the trace shows this same behaviour of slow sending rate inflation and intermittent rate reductions which is typical of CUBIC.

    This CUBIC session managed an average transfer rate of some 45Mbps, which is well below the peak notional circuit capacity of some 250Mps, as indicated by SpeedTest.


    Figure 6 – TCP CUBIC over Starlink

    Starlink is a shared medium, and the performance of the system in local times of light use (off peak) is significantly different to performance in peak times. Figure 7 shows CUBIC performance profile during an off-peak time.


    Figure 7 – TCP CUBIC over Starlink – Off-Peak

    The difference between the achievable throughput between peak and off-peak is quite significant, with the off-peak performance reaching a throughput level some 3 – 4 times greater than the peak load performance. The slow-start phase increases the throughput to some 200Mbps within the first second. The flow then oscillated for a second, then started a more stable congestion avoidance behaviour by second 4. The cubic window inflation behaviour is visible up to second 12 and then the flow oscillates around some 200Mbps of throughput for the remainder of the session.

    Is the difference between these two profiles in Figures 6 and 7 a result of active flow management by Starlink equipment, or the result of the way in which CUBIC reaches a flow equilibrium with other concurrent flows?

    We can attempt to answer this question by using a different TCP control protocol which has a completely different response to contention with other concurrent flows.

    The Bottleneck Bandwidth and Round-trip propagation time (BBR) protocol [11] is a TCP congestion control algorithm developed at Google a decade or so ago. BBR attempts to position the TCP flow at the onset of network queue formation, rather than oscillating between full and empty queue states (as is the case in most loss-based TCP congestion control algorithms).

    Briefly, BBR makes an initial estimate of the delay-bandwidth product of the network path, and then drives the sender to send at this rate for 6 successive RTT intervals. It performs repair for dropped packets without adjusting its sending rate. The 7th RTT interval sees the sending rate increase by 25% and the end-to-end delay is carefully measured in this interval. The final RTT interval in the cycle sees the sending rate drop by 25% from the original rate, intended to drain any network queues that may have formed in the previous RTT interval. If the end-to-end delay increased in the sending rate inflated interval the original sending rate is maintained. If the increased sending window did not impact the end-to-end delay, then this indicates that the network path has further capacity and the delay-bandwidth estimate is increased for the next 8-RTT cycle. (There have been a couple of subsequent revisions to the BBR protocol, but in this case, I’m using the original (v1) version of BBR.)

    The results of a Starlink performance test using BBR is shown in Figure 8.


    Figure 8 – TCP BBR over Starlink

    In this case BBR has made an initial estimate of some 250Mbps for the path bandwidth. This was estimate appears to have been revised at second 14 to some 350Mbps, and then dropped to some 200Mbps some 15 seconds later for the final 10 seconds of this test. It is likely that these changes are the result of BBR responding to satellite handover in Starlink, and the variance in latency was interpreted by BBR as a sign of queue formation, or the absence of queue of queue formation, which was used to alter BBR’s bandwidth delay estimate for the link.

    The same BBR test was performed in an off-peak time, which a very similar outcome (Figure 9).


    Figure 9 – TCP BBR over Starlink – Off-Peak

    If BBR is sensitive to changes in latency, and latency is so variable in Starlink, then why does BBR perform so well as compared to CUBIC?

    I suspect that here BBR is not taking a single latency measurement, but measuring the round-trip time for all packets that are sent in this 7th RTT interval once the sender has increased its sending rate to the burst rate and uses the minimum RTT value as the ‘loaded’ RTT value to determine whether to perform a send rate adjustment. As long as the minimum RTT levels are consistent, and, as shown in Figure 3, these minimum values appear to be consistent across each 15 second scheduling interval, then BBR will assume that its sending rate is not causing network queue formation and will maintain its sending rate.

    Protocol Tuning for Starlink

    Starlink provides a somewhat unique data link service. It has a very high jitter rate, a packet drop rate of around 1%-2% that is unrelated to network congestion, and a latency profile that jumps on a regular basis every 15 seconds. From the perspective if the TCP protocol, Starlink represents an unusually hostile link environment, and older variants of TCP, such as Reno TCP, that react quickly to packet loss and recover slowly, can perform very poorly when used across Starlink connections.

    Could you tune a variant of TCP to optimise its performance over a path that includes a Starlink component?

    A promising approach would appear to start with a variant of BBR. The reason for the choice of BBR is its ability to maintain its sending rate in the face of individual packet loss events. If one were to optimise BBR for Starlink then it can be noted that Starlink performs a satellite handover at regular 15 second intervals, and if the regular sending rate inflation in BBR occurs at the same time as scheduled satellite handover, the BBR sender could defer its rate inflation, maintaining its current sending rate across the scheduled handover time.

    The issue with BBR is that, for version 1 of this protocol, it is quite aggressive in claiming network resources, which can starve other non BBR TCP concurrent sessions of capacity. One possible response is to use the same 15-second satellite handover timer with version 3 of the BBR protocol, which is intended to be less aggressive when working with concurrent data flows.

    In theory it would be possible to adjust CUBIC in a similar manner, performing a lost packet repair using Selective Acknowledgement (SACK) [11] if the packet loss occurred at the time of a scheduled satellite handover. While CUBIC is a fairer protocol with respect to sharing the path capacity with other concurrent TCP sessions, it tends to react conservatively when faced with high jitter paths (as is the case when the end-to-end path includes a Starlink component). Even with some sensitivity to scheduled satellite handovers CUBIC is still prone to reduced efficiency in the use of network resources.

    A somewhat different approach could utilise Explicit Congestion Notification (ECN) [12]. The advantage of such an approach is that it allows the TCP session to differentiate the case where a high sending rate it causes the formation of network queues (congestion), while a transient event, such as satellite handover, causes packet loss without network queue formation. ECN can permit a flow control behaviour that is very much like BBR.

    Conclusions

    While earlier TCP control protocols, such as Reno, have been observed to perform poorly on Starlink connections, more recent TCP counterparts, such as CUBIC, perform more efficiently. The major TCP feature that makes these protocols viable in Starlink contexts is the use of Selective Acknowledgement [11], that allows the TCP control algorithm to distinguish between isolated packet loss and loss-inducing levels of network congestion.

    TCP control protocols that attempt to detect the onset of network queue formation can do so using end-to-end techniques by detecting changes in end-to-end latency during intermittent periods of burst, such as BBR. These protocols need to operate with a careful implementation of their sensitivity to latency, as the highly unstable short-term latency seen on Starlink connections, coupled with the 15-second coarse level latency shifts have the potential to confuse the queue onset detection algorithm.

    It would be interesting to observe the behaviour of an ECN-aware TCP protocol behaviour if ECN were to enabled on Starlink routing devices. ECN has the potential to provide a clear signal to the endpoints about the onset of network-level queue formation, as distinct from latency variation.

    References

    [1]Starlink
    https://www.starlink.com
    [2]
     
    Isaac Newton, Philosophiæ Naturalis Principia Mathematica, July 1687.
    https://www.google.com.au/books/edition/Newton_s_Principia/KaAIAAAAIAAJ?hl=en
    [3]
     
    Allman, M., Glover, D., and L. Sanchez, "Enhancing TCP Over Satellite Channels using Standard Mechanisms", BCP 28, RFC 2488, DOI 10.17487/RFC2488, January 1999
    . https://www.rfc-editor.org/info/rfc2488
    [4]
     
    Wikipedia, Low Earth Orbit.
    https://en.wikipedia.org/wiki/Low_Earth_orbit
    [5]
     
    Wikipedia, Van Allen radiation belt.
    https://en.wikipedia.org/wiki/Van_Allen_radiation_belt
    [6]
     
    Speedtest
    https://www.speedtest.net
    [7]
     
    Ping
    https://en.wikipedia.org/wiki/Ping_(networking_utility)
    [8]
     
    Postel, J., "Transmission Control Protocol", RFC 793, DOI 10.17487/RFC0793, September 1981,
    https://www.rfc-editor.org/info/rfc793
    [9]
     
    Ha, S., Rhee, I., and Xu,L., "CUBIC: a new TCP-friendly high-speed TCP variant." ACM SIGOPS Operating Systems Review 42.5 (2008): 64-74.
    [10]
     
    Cardwell, N., Cheng, Y., Gunn, C., Yeganeh, S., and Jacobson, V., "BBR: Congestion-based Congestion Control", ACM Queue, vol. 14, no. 5, 2016.
    [11]
     
    Floyd, S., Mahdavi, J., Mathis, M., and M. Podolsky, "An Extension to the Selective Acknowledgement (SACK) Option for TCP", RFC 2883, DOI 10.17487/RFC2883, July 2000.
    https://www.rfc-editor.org/info/rfc2883
    [12]
     
    Ramakrishnan, K., Floyd, S., and D. Black, "The Addition of Explicit Congestion Notification (ECN) to IP", RFC 3168, DOI 10.17487/RFC3168, September 2001
    https://www.rfc-editor.org/info/rfc3168

    Disclaimer

    The above views do not necessarily represent the views of the Asia Pacific Network Information Centre.

      GEOFF HUSTON AM, M.Sc., is the Chief Scientist at APNIC, the Regional Internet Registry serving the Asia Pacific region.

    www.potaroo.net

  • Beyond Public Key Encryption

    Hacker News
    blog.cryptographyengineering.com
    2024-05-17 00:24:02
    Comments...
    Original Article

    One of the saddest and most fascinating things about applied cryptography is how 6689264031_4c7516b3e1_zlittle cryptography we actually use. This is not to say that cryptography isn’t widely used in industry — it is. Rather, what I mean is that cryptographic researchers have developed so many useful technologies, and yet industry on a day to day basis barely uses any of them. In fact, with a few minor exceptions, the vast majority of the cryptography we use was settled by the early-2000s.*

    Most people don’t sweat this, but as a cryptographer who works on the boundary of research and deployed cryptography it makes me unhappy. So while I can’t solve the problem entirely, what I can do is talk about some of these newer technologies. And over the course of this summer that’s what I intend to do: talk. Specifically, in the next few weeks I’m going to write a series of posts that describe some of the advanced cryptography that we don’t generally see used.

    Today I’m going to start with a very simple question: what lies beyond public key cryptography? Specifically, I’m going to talk about a handful of technologies that were developed in the past 20 years, each of which allows us to go beyond the traditional notion of public keys.

    This is a wonky post, but it won’t be mathematically-intense. For actual definitions of the schemes, I’ll provide links to the original papers, and references to cover some of the background. The point here is to explain what these new schemes do — and how they can be useful in practice.

    Identity Based Cryptography

    In the mid-1980s, a cryptographer named Adi Shamir proposed a radical new idea. The idea, put simply, was to get rid of public keys.

    To understand where Shamir was coming from, it helps to understand a bit about public key encryption. You see, prior to the invention of public key crypto, all cryptography involved secret keys. Dealing with such keys was a huge drag. Before you could communicate securely, you needed to exchange a secret with your partner. This process was fraught with difficulty and didn’t scale well.

    Public key encryption (beginning with Diffie-Hellman and Shamir’s RSA cryptosystem) hugely revolutionized cryptography by dramatically simplifying this key distribution process. Rather than sharing secret keys, users could now transmit their public key to other parties. This public key allowed the recipient to encrypt to you (or verify your signature) but it could not be used to perform the corresponding decryption (or signature generation) operations. That part would be done with a secret key you kept to yourself.

    While the use of public keys improved many aspects of using cryptography, it also gave rise to a set of new challenges. In practice, it turns out that having public keys is only half the battle — people still need to use distribute them securely.

    For example, imagine that I want to send you a PGP-encrypted email. Before I can do this, I need to obtain a copy of your public key. How do I get this? Obviously we could meet in person and exchange that key on physical media — but nobody wants to do this. It would much more desirable to obtain your public key electronically. In practice this means either (1) we have to exchange public keys by email, or (2) I have to obtain your key from a third piece of infrastructure, such as a website or key server. And now we come to the  problem: if that email or key server is untrustworthy (or simply allows anyone to upload a key in your name), I might end up downloading a malicious party’s key by accident. When I send a message to “you”, I’d actually be encrypting it to Mallory.

    f64f315ec47f0b041e3d881177039414
    Mallory.

    Solving this problem — of exchanging public keys and verifying their provenance — has motivated a huge amount of practical cryptographic engineering, including the entire web PKI. In most cases, these systems work well. But Shamir wasn’t satisfied. What if, he asked, we could do it better? More specifically, he asked: could we replace those pesky public keys with something better?

    Shamir’s idea was exciting. What he proposed was a new form of public key cryptography in which the user’s “public key” could simply be their identity. This identity could be a name (e.g., “Matt Green”) or something more precise like an email address. Actually, it didn’t realy matter. What did matter was that the public key would be some arbitrary string — and not a big meaningless jumble of characters like “7cN5K4pspQy3ExZV43F6pQ6nEKiQVg6sBkYPg1FG56Not”.

    Of course, using an arbitrary string as a public key raises a big problem. Meaningful identities sound great — but I don’t own them. If my public key is “Matt Green”, how do I get the corresponding private key? And if I can get out that private key, what stops some other Matt Green from doing the same, and thus reading my messages? And ok, now that I think about this, what stops some random person who isn’t named Matt Green from obtaining it? Yikes. We’re headed straight into Zooko’s triangle.

    Shamir’s idea thus requires a bit more finesse. Rather than expecting identities to be global, he proposed a special server called a “key generation authority” that would be responsible for generating the private keys. At setup time, this authority would generate a single master public key (MPK), which it would publish to the world. If you wanted to encrypt a message to “Matt Green” (or verify my signature), then you could do so using my identity and the single MPK of an authority we’d both agree to use. To decrypt that message (or sign one), I would have to visit the same key authority and ask for a copy of my secret key. The key authority would compute my key based on a master secret key (MSK), which it would keep very secret.

    With all algorithms and players specified, whole system looks like this:

    IBE
    Overview of an Identity-Based Encryption (IBE) system. The Setup algorithm of the Key Generation Authority generates the master public key (MPK) and master secret key (MSK). The authority can use the Extract algorithm to derive the secret key corresponding to a specific ID. The encryptor (left) encrypts using only the identity and MPK. The recipient requests the secret key for her identity, and then uses it to decrypt. (Icons by Eugen Belyakoff)

    This design has some important advantages — and more than a few obvious drawbacks. On the plus side, it removes the need for any key exchange at all with the person you’re sending the message to. Once you’ve chosen a master key authority (and downloaded its MPK), you can encrypt to anyone in the entire world. Even cooler: at the time you encrypt, your recipient doesn’t even need to have contacted the key authority yet. She can obtain her secret key after I send her a message.

    Of course, this “feature” is also a bug. Because the key authority generates all the secret keys, it has an awful lot of power. A dishonest authority could easily generate your secret key and decrypt your messages. The polite way to say this is that standard IBE systems effectively “bake in” key escrow.**

    Putting the “E” in IBE

    All of these ideas and more were laid out by Shamir in his 1984 paper. There was just one small problem: Shamir could only figure out half the problem.

    Specifically, Shamir’s proposed a scheme for identity-based signature (IBS) — a signature scheme where the public verification key is an identity, but the signing key is generated by the key authority. Try as he might, he could not find a solution to the problem of building identity-based encryption (IBE). This was left as an open problem.***

    It would take more than 16 years before someone answered Shamir’s challenge. Surprisingly, when the answer came it came not once but three times.

    The first, and probably most famous realization of IBE was developed by Dan Boneh and Matthew Franklin much later — in 2001. The timing of Boneh and Franklin’s discovery makes a great deal of sense. The Boneh-Franklin scheme relies fundamentally on elliptic curves that support an efficient “bilinear map” (or “pairing”).**** The algorithms needed to compute such pairings were not known when Shamir wrote his paper, and weren’t employed constructively — that is, as a useful thing rather than an attack — until about 2000. The same can be said about a second scheme called Sakai-Kasahara, which would be independently discovered around the same time.

    (For a brief tutorial on the Boneh-Franklin IBE scheme, see this page.)

    The third realization of IBE was not as efficient as the others, but was much more surprising. This scheme was developed by Clifford Cocks, a senior cryptologist at Britain’s GCHQ. It’s noteworthy for two reasons. First, Cocks’ IBE scheme does not require bilinear pairings at all — it is based in the much older RSA setting, which means in principle it spent all those years just waiting to be found. Second, Cocks himself had recently become known for something even more surprising: discovering the RSA cryptosystem, nearly five years before RSA did. To bookend that accomplishment with a second major advance in public key cryptography was a pretty impressive accomplishment.

    In the years since 2001, a number of additional IBE constructions have been developed, using all sorts of cryptographic settings. Nonetheless, Boneh and Franklin’s early construction remains among the simplest and most efficient.

    Even if you’re not interested in IBE for its own sake, it turns out that this primitive is really useful to cryptographers for many things beyond simple encryption. In fact, it’s more helpful to think of IBE as a way of “pluralizing” a single public/secret master keypair into billions of related keypairs. This makes it useful for applications as diverse as blocking chosen ciphertext attacks, forward-secure public key encryption, and short signature schemes.

    Attribute Based Encryption

    Of course, if you leave cryptographers alone with a tool like IBE, the first thing they’re going to do is find a way to make things more complicated improve on it.

    One of the biggest such improvements is due to Sahai and Waters. It’s called Attribute-Based Encryption, or ABE.

    The origin of this idea was not actually to encrypt with attributes. Instead Sahai and Waters were attempting to develop an Identity-Based encryption scheme that could encrypt using biometrics. To understand the problem, imagine I decide to use a biometric like your iris scan as the “identity” to encrypt you a ciphertext. Later on you’ll ask the authority for a decryption key that corresponds to your own iris scan — and if everything matches up and you’ll be able to decrypt.

    The problem is that this will almost never work.

    The issue here is that biometric readings (like iris scans or fingerprint templates) are inherently error-prone. This means every scan will typically be very close, but often there will be a few bits that disagree. With standard IBE

    iris
    Tell me this isn’t giving you nightmares.

    this is fatal: if the encryption identity differs from your key identity by even a single bit, decryption will not work. You’re out of luck.

    Sahai and Waters decided that the solution to this problem was to develop a form of IBE with a “threshold gate”. In this setting, each bit of the identity is represented as a different “attribute”. Think of each of these as components you’d encrypt under — something like “bit 5 of your iris scan is a 1” and “bit 23 of your iris scan is a 0”. The encrypting party lists all of these bits and encrypts under each one. The decryption key generated by the authority embeds a similar list of bit values. The scheme is defined so that decryption will work if and only if the number of matching attributes (between your key and the ciphertext) exceeds some pre-defined threshold: e.g., any 2024 out of 2048 bits must be identical in order to decrypt.

    The beautiful thing about this idea is not fuzzy IBE. It’s that once you have a threshold gate and a concept of “attributes”, you can more interesting things. The main observation is that a threshold gate can be used to implement the boolean AND and OR gates, like so:

    gates

    Even better, you can stack these gates on top of one another to assign a fairly complex boolean formula — which will itself determine what conditions your ciphertext can be decrypted under. For example, switching to a more realistic set of attributes, you could encrypt a medical record so that either a pediatrician in a hospital could read it, or an insurance adjuster could. All you’d need is to make sure people received keys that correctly described their attributes (which are just arbitrary strings, like identities).

    ABEFormula
    A simple “ciphertext policy”, in which the ciphertext can be decrypted if and only if a key matches an appropriate set of attributes. In this case, the key satisfies the formula and thus the ciphertext decrypts. The remaining key attributes are ignored.

    The other direction can be implemented as well. It’s possible to encrypt a ciphertext under a long list of attributes, such as creation time, file name, and even GPS coordinates indicating where the file was created. You can then have the authority hand out keys that correspond to a very precise slice of your dataset — for example, “this key decrypts any radiology file encrypted in Chicago between November 3rd and December 12th that is tagged with ‘pediatrics’ or ‘oncology'”.

    Functional Encryption

    Once you have a related of primitives like IBE and ABE, the researchers’ instinct is to both extend and generalize. Why stop at simple boolean formulae? Can we make keys (or ciphertexts) that embed arbitrary computer programs? The answer, it turns out, is yes — though not terribly efficiently. A set of recent works show that it is possible to build ABE that works over arbitrary polynomial-size circuits, using various lattice-based assumptions. So there is certainly a lot of potential here.

    This potential has inspired researchers to generalize all of the above ideas into a single class of encryption called “functional encryption“. Functional encryption is more conceptual than concrete — it’s just a way to look at all of these systems as instances of a specific class. The basic idea is to represent the decryption procedure as an algorithm that computes an arbitary function F over (1) the plaintext inside of a ciphertext, and (2) the data embedded in the key. This function has the following profile:

    output = F(key data, plaintext data)

    In this model IBE can be expressed by having the encryption algorithm encrypt (identity, plaintext) and defining the function F such that, if “key input == identity”, it outputs the plaintext, and outputs an empty string otherwise. Similarly, ABE can be expressed by a slightly more complex function. Following this paradigm, once can envision all sorts of interesting functions that might be computed by different functions and realized by future schemes.

    But those will have to wait for another time. We’ve gone far enough for today.

    So what’s the point of all this?

    For me, the point is just to show that cryptography can do some pretty amazing things. We rarely see this on a day-to-day basis when it comes to industry and “applied” cryptography, but it’s all there waiting to be used.

    Perhaps the perfect application is out there. Maybe you’ll find it.

    Notes:

    * An earlier version of this post said “mid-1990s”. In comments below, Tom Ristenpart takes issue with that and makes the excellent point that many important developments post-date that. So I’ve moved the date forward about five years, and I’m thinking about how to say this in a nicer way.

    ** There is also an intermediate form of encryption known as “certificateless encryption“. Proposed by Al-Riyami and Paterson, this idea uses a combination of standard public key encryption and IBE. The basic idea is to encrypt each message using both a traditional public key (generated by the recipient) and an IBE identity. The recipient must then obtain a copy of the secret key from the IBE authority to decrypt. The advantages here are twofold: (1) the IBE key authority can’t decrypt the message by itself, since it does not have the corresponding secret key, which solves the “escrow” problem. And (2) the sender does not need to verify that the public key really belongs to the sender (e.g., by checking a certificate), since the IBE portion prevents imposters from decrypting the resulting message. Unfortunately this system is more like traditional public key cryptography than IBE, and does not have the neat usability features of IBE.

    *** A part of the challenge of developing IBE is the need to make a system that is secure against “collusion” between different key holders. For example, imagine a very simple system that has only 2-bit identities. This gives four possible identities: “00”, “01”, “10”, “11”. If I give you a key for the identity “01” and I give Bob a key for “10”, we need to ensure that you two cannot collude to produce a key for identities “00” and “11”. Many earlier proposed solutions have tried to solve this problem by gluing together standard public encryption keys in various ways (e.g., by having a separate public key for each bit of the identity and giving out the secret keys as a single “key”). However these systems tend to fail catastrophically when just a few users collude (or their keys are stolen). Solving the collusion problem is fundamentally what separates real IBE from its faux cousins.

    **** A full description of Boneh and Franklin’s scheme can be found here, or in the original paper. Some code is here and here and here. I won’t spend more time on it, except to note that the scheme is very efficient. It was patented and implemented by Voltage Security, now part of HPE.

    Interactive Visualizations of Rate-Limiting Algorithms

    Hacker News
    smudge.ai
    2024-05-17 00:07:20
    Comments...
    Original Article

    Visualizing algorithms for rate limiting

    Why rate limit?

    Imagine a Twitch chat with many active participants and just one spammer. Without rate limiting, the sole spammer can easily dominate the entire conversation. With rate limiting, each user has a fair chance to participate.

    A rate limiter lets you control the rate of traffic that your service processes by blocking requests that exceed a set limit during a period of time. This is useful beyond just throttling spam in a chat. For instance, rate limiting a login form can deter brute force attacks while still allowing a small burst of incorrect guesses.

    API endpoints are also frequently rate-limited to prevent any single user from monopolizing resources. Imagine that you want users to only be able to hit an expensive endpoint 100 times per minute. You could track hits with a counter that resets every minute. Any request after the 100th within that minute gets blocked. This is one of the simplest rate-limiting algorithms, called a fixed window limiter, and is a common way to control traffic to a service.

    But it’s not always that simple.

    When does each one-minute window begin and end? If I begin a burst of requests near the end of a window, can I exceed the limit? Is a window’s capacity restored one request at a time, or all at once?

    In this post, we’ll explore the three most common algorithms to answer each of these questions.

    1. Fixed windows
    2. Sliding windows
    3. Token buckets

    Fixed windows

    A set number of requests can be made within a predefined time window. Requests increment a counter that’s reset to zero at the start of each window.

    Allow 6 requests per day (24-hour windows)

    Each green dot  represents an allowed request while  is a request blocked by the rate limiter. You can add more requests with the Hit button, which pauses the automatic stream.
    • Pros
      • Simple to implement and understand
      • Predictable for users
    • Cons
      • Allows bursts up to 2x the limit when requests begin near the end of a window
    • Real-world example
      • GitHub’s API uses a fixed window rate limiter with limit = 5000, windowDuration = 1h, and windowStart set to the start of each wall clock hour, allowing users 5,000 requests per hour.
    A brief tangent on 24-hour fixed windows

    There is a subtle issue with the 24-hour limiter above. Its windows reset every day at midnight—but midnight according to what time zone? A standard fixed window might reset its counter according to your server’s midnight or a standard timezone offset such as UTC. A user in a different timezone who just ran out of requests might retry just after midnight and be surprised if the limit hasn’t been lifted—since to them, it is a new calendar day.

    For these applications, you need to offset your window starts according to the user’s time zone, which has some potential for abuse as users can manually adjust their timezone once they’ve run out of requests to gain up to 1 full window of additional requests. Worse yet, users traveling West to East might incorrectly have more requests limited while those traveling East to West might incorrectly have more requests allowed as they effectively extend their day. If a rate limit resets based on local midnight and a user moves to an earlier time zone, they encounter earlier local midnights. This can effectively allow them to reset their request count sooner by being in a new “day” earlier than expected, thus potentially increasing their total allowable requests within a 24-hour period as measured by real time. Yikes. And we still haven’t dealt with DST.

    This use case is already a bit of a tangent, so for now I’ll leave it at this: handling time zones correctly, accounting for users relocating as well as daylight savings, is difficult to get right—so if you’re considering going down that painful path, I’ll just point you to these resources instead. If you can sidestep this problem by using any other approach at all, you should!

    Fixed window with user-defined start

    Instead of fixing the start times to a set interval, each window can be created at the time of the user’s first request within that window.

    With this approach, it’s especially important to show users the time remaining until the next window once they’re limited since there’s no set time that aligns each window.

    Sliding windows

    Instead of refreshing the capacity all at once, sliding windows refill one request at a time.

    • Pros
      • Smooths the distribution of request traffic
      • Well-suited for high loads
    • Cons
      • Less predictable for users than fixed windows
      • Storing timestamps for each request is resource-intensive

    Because sliding windows tend to be most useful in high-traffic scenarios, the fact that the naive algorithm is resource-intensive is counterproductive. Shouldn’t a high-traffic rate limiter use an efficient algorithm? For this reason, most real-world sliding window rate limiters, such as those provided by Upstash or Cloudflare, use an approximation, often called a floating window. Using this approximation, we have all the same pros but can remove the “resource-intensive” point from the cons. Here’s how it works:

    1. Count the number of allowed requests in the previous fixed window.
    2. Count the number of allowed requests in the current fixed window.
    3. Weight the previous window’s allowed requests proportional to that window’s overlap with a floating window ending at the current time.
    4. Add the weighted requests from (3) to the unweighted requests from (2).

    In other words, this is the computation:

    approximation = (prevWindowCount * prevWindowWeight) + currentWindowCount


    In practice, this approximation limits requests at roughly the same proportion but is far more efficient than tracking all the requests’ timestamps. See for yourself how it compares:

    Token buckets

    Instead of thinking in terms of windows with durations, picture a bucket that fills up with “tokens” at a constant rate. Each request withdraws one token from this bucket, and when the bucket is empty the next request will be blocked. This token bucket approach has some useful properties.

    1. The capacity of the bucket is the maximum number of requests that a burst can support (not counting tokens that are replenished mid-burst).
    2. The refill interval represents the long-term average allowed request interval.

    Having distinct burst and average capacities without the need for multiple rate limiters is one of the main benefits to this algorithm.

    • Pros

      • Allows bursts of high traffic, but enforces a long-term average rate of requests
      • More flexible for users, allowing for traffic spikes within an acceptable range
    • Cons

      • More difficult to convey limits and refill times to users than with fixed windows
    • Real-world examples

      • Stripe uses a token bucket in which each user gets a bucket with limit = 500, refillInterval = 0.01s, allowing for sustained activity of 100 requests per second, but bursts of up to 500 requests. (Implementation details.)
      • OpenAI’s free tier for GPT-3.5 is limited to 200 requests per day using a token bucket with limit = 200 and refillInterval = 86400s / 200, replenishing the bucket such that at the end of a day (86,400 seconds) an empty bucket will be 100% filled. They refill the bucket one token at a time.

      The Twitch chat demo above is rate-limited using a token bucket with a bucket size of 3, allowing bursts of up to 3 requests, and a refill interval of 4 seconds, which creates a long-term average allowed rate of 1 message every 4 seconds.

      Thanks to their flexibility, token buckets can also mimic the properties of some of the other algorithms. For example, set the refillRate equal to the limit and you have an equivalent to a fixed window rate limiter with a user-defined start.

    Other considerations

    If you decide to add rate limiting to your application or endpoint, in addition to selecting an appropriate algorithm there are a few other things you should keep in mind.

    • Create a persisted store for the rate limiter. If you ever intend to horizontally scale your server (or even just restart it) your rate limiter data store can’t be in-memory. A popular option is to save rate limiting data to a key-value store like Redis, which has built-in functions for expiring keys, on a separate machine from your application. You can, however, use an ephemeral in-memory cache to block requests without hitting Redis while the limiter is hot.
    • Fail open. If your server’s connection to the persisted store fails, make sure to allow all requests rather than blocking access to your service altogether.
    • Optionally throttle bursts. Throttling can be used in combination with rate limiting to reduce the impact of burst traffic.
    • Choose sensible keys. In general, rate limiting is done on a per-user level. For most apps, this means keying on the user ID. For APIs, key on an API key. To rate limit unauthenticated users, the options aren’t great, but popular methods include using the request’s IP address, a device fingerprint, a unique installation ID, or just a shared limiter.
    • Surface useful rate limiting errors. Let users know how long they have to wait for their next request. For APIs, use the 429 HTTP status code when a request is blocked and include the relevant x-ratelimit-* response headers. GitHub has good examples of the headers for their fixed-window limiter and OpenAI has some for their token-bucket limiter.

    Wrapping up

    • If you need a simple rate limiter or predictable window start times, use a fixed window.
    • If you need traffic smoothing for a high volume of requests, consider using an approximated sliding window.
    • If you need to support bursts of traffic while enforcing a lower average long-term rate for requests, use a token bucket.

    Playground


    This post was inspired by the amazing load balancing visualizations at samwho.dev. Also, a huge thank you to @onsclom for pairing with me on the canvas visualizations. Lastly, shoutout to Upstash for their docs and implementation scripts, which served as an excellent reference for each algorithm.

    Feel free to send corrections, ideas, and feedback my way at feedback@smudge.ai!


    This post is the second in a series where I document some of the things I’ve learned while building smudge.ai. If you’re new here, smudge.ai is a Chrome extension that lets you save custom ChatGPT commands into your right-click menu. It’s a (mostly) solo project and an extension I rely on almost every day. If you think it could be a useful tool for you, too, then you can always try smudge.ai for free with no account using the rate-limited free tier, which happens to have been implemented as a fixed window with a user-defined start. Cheers!

    LearnLM models tuned for human learning

    Hacker News
    blog.google
    2024-05-16 23:44:58
    Comments...
    Original Article

    May 14, 2024

    [[read-time]] min read

    LearnLM is our new family of models fine-tuned for learning, and grounded in educational research to make teaching and learning experiences more active, personal and engaging.

    Text saying “LearnLM” surrounded by a diverse set of images, including a honey bee, the Colosseum and plants in sunlight

    Generative AI is fundamentally changing how we’re approaching learning and education, enabling powerful new ways to support educators and learners. It’s taking curiosity and understanding to the next level — and we’re just at the beginning of how it can help us reimagine learning.

    Building a new family of models for learning

    Today we’re introducing LearnLM: our new family of models fine-tuned for learning, based on Gemini.

    Grounded in educational research and tailored to how people learn, LearnLM represents an effort across Google DeepMind, Google Research and our product teams to help make learning experiences more engaging, personal and useful. Our technical report presents our approach to improving generative AI for education and highlights how we’re working together with the AI and EdTech communities to responsibly maximize its positive impact and potential.

    Working alongside educators and other learning experts, we’re infusing learning science principles, like the following, into our models and the products they power:

    • Inspire active learning: Allow for practice and healthy struggle with timely feedback
    • Manage cognitive load: Present relevant, well-structured information in multiple modalities
    • Adapt to the learner: Dynamically adjust to goals and needs, grounding in relevant materials
    • Stimulate curiosity: Inspire engagement to provide motivation through the learning journey
    • Deepen metacognition: Plan, monitor and help the learner reflect on progress

    Bringing LearnLM to products you already love

    With LearnLM we’re enhancing learning experiences in products you already use today — like Search, YouTube and when chatting with Gemini — so they can help you deepen understanding, rather than just giving an answer. Here are a few examples:

    • In Google Search, soon you’ll be able to make sense of complex topics by tapping a button to adjust your AI Overview into the format that’s most useful for you — whether you want to simplify the language, or break it down.
    • On Android, Circle to Search can help people get unstuck on math and physics word problems directly from their phones and tablets. Later this year, you’ll be able to solve even more complex problems involving symbolic formulas, diagrams, graphs and more.
    • When chatting with Gemini, soon you’ll be able to use Gems, custom versions of Gemini that can act as personal experts on any topic. Learning coach, one of the pre-made Gems, can support you in building knowledge by providing step-by-step study guidance, along with helpful practice activities like quizzes and games. Learning coach in Gemini will launch in the coming months, and with Gemini Advanced, you’ll be able to further customize this Gem to suit your unique learning preferences.
    • On YouTube, a conversational AI tool makes it possible to figuratively “raise your hand” while watching academic videos to ask clarifying questions, get helpful explanations or take a quiz on what you’ve been learning. This even works with longer educational videos like lectures or seminars thanks to the Gemini model’s long-context capabilities. These features are already rolling out to select Android users in the U.S.
    • A search query for "explain the connection between lightning and thunder" with the option to use AI Overview to make it simpler

    • A demo of the Circle to Search feature on a mobile device. Circle appears around a math question

    • A demo of the user experience of Learning coach on a mobile device. In response to two queries, Learning coach first explains the photosynthesis equation, then shares a mnemonic device to help the user remember it.

    • A demo of the user experience of asking a question while watching a YouTube video

    Applying LearnLM to build generative AI experiences for schools

    We’ll also apply LearnLM to inform and enable the generative AI experiences that we build for schools. Through a new pilot program in Google Classroom, we’re working directly with educators to see how we can help simplify and improve the process of lesson planning — a critical, but time-consuming component of teaching. These features will help teachers discover new ideas and unique activities, find engaging materials, and differentiate their lessons and content to meet each of their students where they are. No technology can ever replace the magic of a teacher, but when applied in deliberate and thoughtful ways, AI can help to augment their capacity — giving them time back to invest in themselves and their students.

    Introducing two new experimental tools to advance learning

    Beyond LearnLM and our existing products, we’re also building entirely new tools and experiences that expand learning:

    • Illuminate is a new experiment that breaks down research papers into short audio conversations. In minutes, it can generate audio with two AI-generated voices in conversation, providing an overview of key insights from these complex papers. And soon, you’ll be able to ask follow-up questions. Visit Labs.google to check out a library of available audio conversations and join the waitlist to generate your own.
    • Learn About is a new Labs experience that explores how information can turn into understanding by bringing together high-quality content, learning science and chat experiences. Ask a question and it helps guide you through any topic at your own pace — through pictures, videos, webpages and activities — and you can upload files or notes and ask clarifying questions along the way. Sign up to be an early tester.

    With any emerging technology, there are still risks and new questions that will arise as AI advances and its uses evolve. To us, building AI responsibly means both addressing the risks and maximizing the benefits for people and society. Reimagining learning and education with AI will require collective effort. We’ve collaborated with MIT RAISE to develop an online course to help educators better understand and use generative AI in the classroom. And as we work to extend LearnLM beyond our own products, we will partner with experts at institutions like Columbia Teachers College, Arizona State University, NYU Tisch and Khan Academy to test and improve this technology. We want to build for you and with you, so please let us know if you’re interested in working together to help define educational benchmarks, improve academic capabilities and ultimately explore the possibilities when it comes to applying advances in generative AI to teaching and learning. These possibilities — much like our curiosity — are endless.

    A grid with curved lines and rectangles filled with a gradient of rainbow colors.

    I/O 2024

    Here’s a look at everything we announced at Google I/O 2024.

    You are already subscribed to our newsletter.

    The Forged Apple Employee Badge

    Hacker News
    cabel.com
    2024-05-16 23:19:06
    Comments...
    Original Article

    Here’s a quick and cautionary tale.

    This eBay auction, spotted by Eric Vitiello, immediately caught my eye:

    Wow. Someone was selling Apple Employee #10’s employee badge?! What an incredible piece of Apple history! Sure, it’s not Steve Jobs’ badge (despite the auction title), but there are only so many of these in the world — especially from one of the first ten employees.

    I persistently pored through the provided pictures.

    At first, it looked good. The plastic was scuffed with age, the tape on the map was yellowed, the logo was correct, Sherry Livingston really was Employee #10.

    But, that map — it felt a little off. (“Tennis courts?”) And I couldn’t stop looking at the “typewritten” part…

    This badge would’ve been (obviously!) made before desktop publishing. A badge template would’ve been printed by a local printing company, then fed into a typewriter to type the individual employee details. And that typed text is way, way cleaner than any typewriter I’ve seen.

    And just as I was beginning to 🧐, along came Chris:

    “That’s… fake. Both of them.”

    Oh snap. It’s really fake?

    What does this Chris guy know, anyway? Well, he’s Chris Espinosa. Who just so happens to be Apple Employee #8.

    (Trivia: he joined the company when he was 14… and still works there!)

    And we know exactly what Chris’ badge looked like:

    I asked Chris (who I truly admire!) for more thoughts:

    So, yeah. One of the most qualified people on planet earth to say this is a fake, is saying this is a fake.

    I had no choice at this point. I simply had to meddle.

    From… the German Red Cross?! How specific!

    It seems like the German Red Cross runs a kind of second hand/charity shop, so ok, sure. But why would the German Red Cross have the employee badge for Apple Employee #10?

    I couldn’t wait. The seller sent the Red “Croos” proof just a few hours later. (Enough time to… create it?)

    At first blush, again, this provenance looks pretty good, right? A German purchase receipt, dated 2001, for the item pictured. The right logo. A nice emboss. Seems plausible.

    But, again again, I had a weird feeling — this series of photos was trying too hard. That binder labelled “BILLS 200[0]—2010”, conveniently flipped upside down for casual authenticity? Why would you put that in these photos unless you were trying a bit too hard to make your case? It felt like a set dresser trying to stage a movie scene.

    The seller added:

    As you can see, the invoice is expressed in the old German currency, the German mark, before the entry of the EURO in the years following.

    No way. A regular human wouldn’t point this out. Someone proud of a detail they thought of in their forgery would point this out. This little detail would’ve been far more effective for me to discover on my own.

    It was time to totally close the case. It was time to engage the internet.

    The Mastodon response from Germans was swift and brutal.

    There was no doubt. This “proof” was yet another forgery.

    I told the seller this. And then, weirdly, for the amount of effort put into this, they made a very dumb error:

    Wait… what?!?

    I never received a reply.

    Case closed!?

    There’s just one small, sad problem…

    …yes, the item sold before I could finish this post. So, my sincere apologies to whoever out there just spent $946.00 on a total (but interesting!) work of fiction.

    Here are the key takeaways from our meeting today:

    • Beware of fraudulent pieces of Apple history
    • Don’t buy anything from this particular seller
    • When in doubt, Engage The Internet®

    Best,
    Cabel

    PS: I hope you’re having a nice week

    Slack AI Training with Customer Data

    Hacker News
    slack.com
    2024-05-16 23:16:01
    Comments...
    Original Article

    Our mission is to build a product that makes work life simpler, more pleasant and more productive. Our guiding principle as we build this product is that the privacy and security of Customer Data is sacrosanct, as detailed in our Privacy Policy, Security Documentation and SPARC and the Slack Terms.

    Machine Learning (ML) and Artificial Intelligence (AI) are useful tools that we use in limited ways to enhance our product mission. To develop AI/ML models, our systems analyze Customer Data (e.g. messages, content, and files) submitted to Slack as well as Other Information (including usage information) as defined in our Privacy Policy and in your customer agreement. To ensure the privacy and security of Customer Data in this particular context, we have a few guiding principles:

    • Data will not leak across workspaces. For any model that will be used broadly across all of our customers, we do not build or train these models in such a way that they could learn, memorize, or be able to reproduce some part of Customer Data.
    • We have technical controls in place to prevent access. When developing AI/ML models or otherwise analyzing Customer Data, Slack can’t access the underlying content. We have various technical measures preventing this from occurring. Please read our Security White Paper for more info on these controls that protect the confidentiality and security of Customer Data.
    • We offer Customers a choice around these practices. If you want to exclude your Customer Data from helping train Slack global models, you can opt out. If you opt out, Customer Data on your workspace will only be used to improve the experience on your own workspace and you will still enjoy all of the benefits of our globally trained AI/ML models without contributing to the underlying models.

    Contact us to opt out. If you want to exclude your Customer Data from Slack global models, you can opt out. To opt out, please have your Org or Workspace Owners or Primary Owner contact our Customer Experience team at feedback@slack.com with your Workspace/Org URL and the subject line “Slack Global model opt-out request.” We will process your request and respond once the opt out has been completed.

    Customer Data and Other Information

    How Slack may use Customer Data (e.g. messages, content, files) and Other Information to update our services

    Working from the above principles, here are a few examples of improvements and privacy protective techniques that our product and analytics teams may use to develop, update and improve Slack:

    • Channel Recommendations: We may use insights to recommend that a user joins a new public channel in their company. We make these suggestions based on channel membership, activity, and topic overlaps. Our model learns from previous suggestions and whether or not a user joins the channel we recommend. We protect privacy while doing so by separating our model from Customer Data. We use external models (not trained on Slack messages) to evaluate topic similarity, outputting numerical scores. Our global model only makes recommendations based on these numerical scores and non-Customer Data. For more technical details, please visit our Engineering Blog to learn more.
    • Search Results: Our search machine learning models help users find what they're seeking by identifying the right results for a particular query. We do this based on historical search results and previous engagements without learning from the underlying text of the search query, result, or proxy. Simply put, our model can't reconstruct the search query or result. Instead, it learns from team-specific, contextual information like the number of times a message has been clicked in a search or an overlap in the number of words in the query and recommended message.
    • Autocomplete: Slack might make suggestions to complete search queries or other text– for example autocompleting the phrase "Customer Support" after a user types the first several letters of this phrase. These suggestions are local and sourced from common public message phrases in the user’s workspace. Our algorithm that picks from potential suggestions is trained globally on previously suggested and accepted completions. We protect data privacy by using rules to score the similarity between the typed text and suggestion in various ways, including only using the numerical scores and counts of past interactions in the algorithm.
    • Emoji Suggestion: Slack might suggest emoji reactions to messages using the content and sentiment of the message, the historic usage of the emoji, and the frequency of use of the emoji on the team in various contexts. For instance, if 🎉 is a common reaction to celebratory messages in a particular channel, we will suggest users react to new, similarly positive messages with 🎉. To do this while protecting Customer Data, we might use an etrnal model (not trained on Slack messages) to classify the sentiment of the message. Our model would then suggest an emoji only considering the frequency with which a particular emoji has been associated with messages of that sentiment in that workspace.

    These types of thoughtful personalizations and improvements are only possible if we study and understand how our users interact with Slack.

    Slack takes privacy seriously and our confidentiality obligations described in our customer agreements and Privacy Policy apply in each of these scenarios. Customers own their own Customer Data. Slack aggregates and disassociates Customer Data such that Slack’s use of Customer Data to update the Services will never identify any of our customers or individuals as the source of any of these improvements to any third party, other than to Slack’s affiliates or sub-processors.

    Improvements to Data Analysis in ChatGPT

    Hacker News
    openai.com
    2024-05-16 23:06:28
    Comments...

    Army soldiers not impressed with Strykers outfitted with 50-kilowatt lasers

    Hacker News
    breakingdefense.com
    2024-05-16 22:57:22
    Comments...
    Original Article

    DE MSHORAD

    Shown here is a Directed Energy Maneuver-Short Range Air Defense (DE M-SHORAD) prototype. (US Army/ Jim Kendall)

    WASHINGTON — Earlier this year the US Army sent four Stryker-mounted 50-kilowatt laser prototypes to the Middle East for soldiers to test out against aerial threats. Initial feedback is rolling in and it’s not overwhelmingly positive, according to Army acquisition head Doug Bush.

    What we’re finding is where the challenges are with directed energy at different power levels,” Bush told members of the Senate Appropriations airland subcommittee on Wednesday. “That [50-kilowatt] power level is proving challenging to incorporate into a vehicle that has to move around constantly — the heat dissipation, the amount of electronics, kind of the wear and tear of a vehicle in a tactical environment versus a fixed site.”

    Dubbed the Directed Energy Maneuver Short-Range Air Defense (DE M-SHORAD), the service tasked Kord Technologies with integrating a 50-kilowatt class RTX laser onto a Stryker to down class one to three aerial drones and incoming rockets, artillery and mortars. In total, four prototypes were produced, and Breaking Defense first reported that all four were sent to the US Central Command (CENTCOM) region in February. 

    Army Vice Chief of Staff Gen. James Mingus said at the time that the goal was to experiment in a live environment complete with weather challenges and dust storms that can alter light particles and degrade beam quality.

    “You may have a 50-kilowatt laser, [but] at 10 kilometers can you put at least four kilowatts in a centimeter square because … that’s what you need to burn through a quarter inch steel plate?” the three-star general asked. “But that’s really hard to get … from a big beam to get the small portion of it on the exact spot to be able to burn at that high intensity and any kind of dust particle or that starts to disrupt that.”

    Fast forward to today and soldiers are delivering some of that feedback, and Bush said results from the lab environment and test ranges is very different from the tactical environment.

    [Soldiers] will tell you everything and they’re not worried about your feelings,” Bush told senators.

    While their initial input is not stellar for those Stryker-based prototypes, other high-energy lasers are proving to be more useful. In late-April, Military.com first reported that the service had also sent a 20-kilowatt Palletized High Energy Laser (P-HEL), overseas.

    Bush did not name the P-HEL by name or disclose where it had been deployed, but told lawmakers that those 20-kilowatt class systems “are proving successful” for “some” fixed-site setups. The service has also inked a contract with Lockheed Martin for300-kilowatt high energy laser weapon, dubbed the Indirect Fire Protection Capability-High Energy Laser (IFPC-HEL), but that has not yet been delivered to soldiers and tested out, he added.

    By The Numbers

    The Pentagon has been developing such directed energy weapons for years but is now looking for ways to test them out and get them into the field. That pressure is only growing as the cost of shooting down low-priced drones grows.

    At the same time, the Army is grappling with a flat budget next year and opted to make cuts to an array of development coffers, including directed energy one’s.

    Even before the DE-MSHORAD soldier feedback came in, Army leaders were planning cuts to that 50-kilowatt laser effort. In its fiscal 2024 budget request, for example, the Army included $110 million for DE M-SHORAD development and laid out a plan to spend nearly $126 million the following year. When the service delivered its FY25 budget request to lawmakers in March, though, it asked for $38 million less than anticipated, or $88 million. And it’s not just a one year cut. Army leaders now plan to spend $445 million between FY26 and FY28 for program development, or about $186 million less than it projected spending last year over the same three-year stint.

    Next year’s budget request also takes a swipe at Lockheed Martin’s IFPC-HEL development with the service asking for just under $32 million, a sharp decrease from the $86 million it requested for FY24 and the $209 million it received in FY23. However, it noted that this cut is a natural “progression” as prototypes are delivered and the effort transitions to a program of record.

    IFPC High Power Microwave (HPM) research and development also takes a hit. The Army’s FY25 request asks for just over $4 million for next year, $11 million less than requested in FY24 and $41 million fewer dollars than received for FY23. While that development pot is reduced, the service had previously predicted that spending trajectory would decline. (That is, in part, due to this week’s announcement that Epirus has delivered all four IFPC-HPM prototypes to the service.)

    As is the case with IFPC-HPM prototype deliveries marking a development milestone, service leaders propose coffer reductions for a variety of reasons, including budget constraints, testing schedules and program transitions out of development and into production. But reductions to the Army’s directed energy portfolios have raised the eyebrows of at least one lawmaker, Sen. Angus King, an Independent from Maine.

    During a Senate Armed Services Committee hearing in April, those cuts prompted King to say to Army Secretary Christine Wormuth and Chief of Staff Gen. Randy George, “What in the hell are you people thinking?”

    “I’d like to start with three data points: $10,000, $4.3 million and $12,” he said during a Senate Armed Services Committee hearing. “$10,000 is the high-end estimate of cost of the drones that Iran and the Houthis are using, $4.3 million is the cost of one SM-6 missile, $4 million for the Patriot, [and] $12 [is] the cost of the directed energy shot that can take down one of these drones.”

    Hertz sold a bunch of Teslas and it turns out they're all kinds of trouble

    Hacker News
    qz.com
    2024-05-16 22:33:26
    Comments...
    Original Article

    Hertz gambled and lost when it placed its big EV bet on Tesla a few years ago. It was a chance for the rental car company to shake up the industry, instead the company bought 30,000 Teslas, got scared away by depreciation and expensive repairs and now wants to get rid of them. While all those used Teslas looked to be great used car deals, it turns out high mileage EVs that were formerly rentals are horrible to own as New York Magazine reported.

    Nvidia stock has all-time closing high in its crosshairs

    • Off
    • English

    Hertz had ambitions to make 20 percent of its rental fleet EVs, and it was going to start with a massive Tesla deal that saw the company purchase over 30,000. Expensive maintenance that the company didn’t account for spooked the company enough to start to sell off it’s fleet. This made for incredible used EV buys, especially when you factor in the used EV tax credit of $4,000. People scrambled to Hertz dealers buying them up. One salesman at a Hertz dealer in Smithtown, New York told New York Magazine that they were selling as many as 30 Teslas a week at one point. A slowdown came when buyers finally started to realize just what they got themselves into.

    Take Bijay Pandey of Irving, Texas. He went and purchased a 2022 Model 3 Long Range for just $25,000 for his wife earlier this year. Problems with it started not long after he purchased it.

    After getting a temporary title, he found the car wasn’t reading voltage correctly. Soon, a body shop found a quarter-size hole in the undercarriage he hadn’t seen before, which led to revelations of deeper issues inside. “The high-voltage battery pack is damaged and could cause extreme safety concerns,” a Tesla technician texted him.

    The hole in the battery pack turned out to be damage that was classified as “exterior damage,” resulting in a repair bill of over $13,000. Of course, that amount wasn’t covered by warranty. Surprisingly, Hertz told Pandey they would let him swap the car for another. Unfortunately that meant two months of waiting while Pandey still made his $500 car payment. Pandey says this is when it dawned on him why Hertz was trying to offload these EVs. “I realized why they were trying to get rid of those Teslas. If anything happens to a Tesla, then the bill is too high.”

    Pandey isn’t alone in this realization. Places like Reddit and Tesla forums are full of people asking whether or not it’s a good idea to buy a used Tesla from Hertz. And a good number of people are telling them to steer clear. Many seem to forget that these were rentals, and rentals often have hard lives. Some suggested that it would make more sense to buy a used Model 3 from Tesla than Hertz.

    The battery abuse these have received makes a purchase from Hertz a dealbreaker. My prior experience with purchase of a used rental does factor. Most rental cars don’t see much abuse, however many of these were Uber rentals, lots of fast charging, using all the range there is, the abuse is such it falls on the poor slob that buys one. I would buy a used Tesla from Tesla, that’s about it.

    We reached out to Hertz for comment, but Hertz isn’t saying much about the used Teslas. It seems the company just wants to get rid of them and be done with it. In a statement to New York, a spokeswoman said the company expects to be done selling the remaining 20,000 Teslas by the end of the year. If you’re in the market for one of these things and are tempted by the low prices, all I can say is good luck.

    A version of this article originally appeared on Jalopnik.

    Deutsche Bahn Introduces "MetaWindow"

    Hacker News
    www.railtarget.eu
    2024-05-16 22:14:47
    Comments...
    Original Article

    Deutsche Bahn Introduces &quote;MetaWindow&quote;: A Game-Changer in Noise Reduction for Railways

    photo: Dominic Dupont / DB AG / Public domain/Berthold Huber

    Deutsche Bahn has unveiled a pioneering advancement in noise control technology with the introduction of the MetaWindow, a transparent noise barrier boasting unparalleled sound-absorbing capabilities.

    Read more

    Derailing Stability: The Escalation of Russian Railway Sabotage in Europe Amidst War

    Developed in collaboration with Italian start-up Phononic Vibes, the MetaWindow was recently showcased at the Greentech Festival in Berlin. This new system integrates meta technology, which utilizes a unique geometric design to enhance acoustic efficiency far beyond traditional noise barriers. The first real-world application of this innovative technology is set to commence on the S4 railway construction in Hamburg later this year.

    Source: DB AG / Public domain

    Berthold Huber, a DB Board Member for Infrastructure, emphasized the dual benefits of the MetaWindow. "To achieve our climate protection targets, we need to get more traffic on the rails and expand and extend the network," emphasized Huber. "But we can only gain the necessary acceptance from residents if rail transport becomes quieter. This is precisely where the innovative MetaWindow comes in. With the transparent noise barrier, local authorities no longer have to choose between appearance and functionality."

    Read more

    Budimex Launches New Tram Line in Warsaw

    The barrier achieves noise insulation levels ranging from 34 to 37 decibels while maintaining up to 72 percent transparency, a stark improvement over existing solutions that often sacrifice effectiveness for visual openness. The MetaWindow is specifically designed for sensitive areas where strict noise reduction regulations apply, such as urban settings, tourist spots, residential zones, and protected landscapes. Its design minimizes visual disruptions, aligning better with the environment and reducing public grievances often associated with the construction of conventional noise barriers.

    Source: DB AG / Public domain

    Although the MetaWindow comes at a higher material cost, the overall financial implications are mitigated by the potential for faster planning approvals and reduced objection rates from communities, ultimately speeding up project completions.

    Read more

    “High-Speed Lines Are Not Just Transit Lines to the Main Airport, but Will Connect the…

    Tags

    Skio (YC S20) – Subscriptions for Shopify, ReCharge Migrations Is Hiring

    Hacker News
    skio.com
    2024-05-16 22:01:29
    Comments...
    Original Article

    careers

    What we do

    We help brands on Shopify sell subscriptions (+more in the future).

    Company health (as of February 2024)

    • Founded: 2021
    • Funding: $8.4M
    • Revenue: $8M ARR (97% margins)
    • Team size: 43

    Ways we stand out

    • Post-PMF/actual revenue. $8M ARR (97% margin) as of February 2024 on $8.4M raised.
    • Transaction fee business model (1% + 20c on every order).
    • D2C/Shopify app ecosystem is low tech. Lots of low hanging fruit.
    • Minimal meeting culture. Make reversible decisions quickly. Make irreversible decisions less quickly. 15m meetings instead of 30m meetings. Good read on this here.
    • Backed by Y Combinator (if investors matter to you).

    Values

    • Integrity. Always act like someone's watching.
    • Agency. We look for drivers over passengers (Frank Slootman). You run through walls to get things done & question how things can be better instead of going with the flow (too many people who go with the flow and we're going to be in a bad spot in 10 years).
    • Grind. We work long hours to be the best at what we do.
    • Hats. Wear many hats. No job is not your job.
    • Intent. Assume good intent (esp. w/ written communication). We're sensitive without walking on eggshells.

    Great traits

    • Really good at something with high skill ceiling. Poker, piano, gaming, sports, past startup/project, anything.
    • High delta in circumstances & outcome. It's a pretty strong signal when you're able to do much better than most people in your shoes would do.
    • Adventure-driven. We're here to build a legendary company & make some fun memories (+hopefully lots of money).
    • EV-based decision-making. You look at how much X will help Y, the number of Y, and estimate how long X will take when deciding what to work on.
    • Autonomous. Can take vague requests and get them done without needing too much help.
    • Apolitical. Culmination of many points above. If you've experienced a political company culture and it killed you inside, then that's great (will do our best to make sure this never happens here).

    Deck

    Deck

    What they're saying

    Dr. Parik Patel tweet

    Engineering

    Product

    Sales

    Customer Experience

    Growth

    Everything else

    What we do

    We help brands on Shopify sell subscriptions (+more in the future).

    Company health (as of February 2024)

    • Founded: 2021
    • Funding: $8.4M
    • Revenue: $8M ARR (97% margins)
    • Team size: 43

    Ways we stand out

    • Post-PMF/actual revenue. $8M ARR (97% margin) as of February 2024 on $8.4M raised.
    • Transaction fee business model (1% + 20c on every order).
    • D2C/Shopify app ecosystem is low tech. Lots of low hanging fruit.
    • Minimal meeting culture. Make reversible decisions quickly. Make irreversible decisions less quickly. 15m meetings instead of 30m meetings. Good read on this here.
    • Backed by Y Combinator (if investors matter to you).

    Values

    • Integrity. Always act like someone's watching.
    • Agency. We look for drivers over passengers (Frank Slootman). You run through walls to get things done & question how things can be better instead of going with the flow (too many people who go with the flow and we're going to be in a bad spot in 10 years).
    • Grind. We work long hours to be the best at what we do.
    • Hats. Wear many hats. No job is not your job.
    • Intent. Assume good intent (esp. w/ written communication). We're sensitive without walking on eggshells.

    Great traits

    • Really good at something with high skill ceiling. Poker, piano, gaming, sports, past startup/project, anything.
    • High delta in circumstances & outcome. It's a pretty strong signal when you're able to do much better than most people in your shoes would do.
    • Adventure-driven. We're here to build a legendary company & make some fun memories (+hopefully lots of money).
    • EV-based decision-making. You look at how much X will help Y, the number of Y, and estimate how long X will take when deciding what to work on.
    • Autonomous. Can take vague requests and get them done without needing too much help.
    • Apolitical. Culmination of many points above. If you've experienced a political company culture and it killed you inside, then that's great (will do our best to make sure this never happens here).

    Deck

    Deck

    What they're saying

    Dr. Parik Patel tweet

    Engineering

    Product

    Sales

    Customer Experience

    Growth

    Everything else

    Winamp has announced that it is "opening up" its source code

    Hacker News
    about.winamp.com
    2024-05-16 21:56:17
    Comments...
    Original Article

    Winamp

    Dec 16, 1

    Press Release

    Winamp has announced that it is opening up its source code to enable collaborative development of its legendary player for Windows.

    Winamp has announced that on 24 September 2024, the application's source code will be open to developers worldwide.

    Winamp will open up its code for the player used on Windows, enabling the entire community to participate in its development. This is an invitation to global collaboration, where developers worldwide can contribute their expertise, ideas, and passion to help this iconic software evolve.

    Winamp has become much more than just a music player. It embodies a unique digital culture, aesthetic, and user experience. With this initiative to open the source code, Winamp is taking the next step in its history, allowing its users to contribute directly to improving the product.

     "This is a decision that will delight millions of users around the world. Our focus will be on new mobile players and other platforms. We will be releasing a new mobile player at the beginning of July. Still, we don't want to forget the tens of millions of users who use the software on Windows and will benefit from thousands of developers' experience and creativity. Winamp will remain the owner of the software and will decide on the innovations made in the official version," explains Alexandre Saboundjian, CEO of Winamp.

    Interested developers can now make themselves known at the following address: about.winamp.com/free-llama

    Subscribe to our newsletter

    Get the best content for creators delivered to your inbox every week.

    Winamp

    Dec 16, 1

    Press Release

    Winamp has announced that it is opening up its source code to enable collaborative development of its legendary player for Windows.

    Winamp has announced that on 24 September 2024, the application's source code will be open to developers worldwide.

    Winamp will open up its code for the player used on Windows, enabling the entire community to participate in its development. This is an invitation to global collaboration, where developers worldwide can contribute their expertise, ideas, and passion to help this iconic software evolve.

    Winamp has become much more than just a music player. It embodies a unique digital culture, aesthetic, and user experience. With this initiative to open the source code, Winamp is taking the next step in its history, allowing its users to contribute directly to improving the product.

     "This is a decision that will delight millions of users around the world. Our focus will be on new mobile players and other platforms. We will be releasing a new mobile player at the beginning of July. Still, we don't want to forget the tens of millions of users who use the software on Windows and will benefit from thousands of developers' experience and creativity. Winamp will remain the owner of the software and will decide on the innovations made in the official version," explains Alexandre Saboundjian, CEO of Winamp.

    Interested developers can now make themselves known at the following address: about.winamp.com/free-llama

    Subscribe to our newsletter

    Get the best content for creators delivered to your inbox every week.

    Winamp

    Dec 16, 1

    Press Release

    Winamp has announced that it is opening up its source code to enable collaborative development of its legendary player for Windows.

    Winamp has announced that on 24 September 2024, the application's source code will be open to developers worldwide.

    Winamp will open up its code for the player used on Windows, enabling the entire community to participate in its development. This is an invitation to global collaboration, where developers worldwide can contribute their expertise, ideas, and passion to help this iconic software evolve.

    Winamp has become much more than just a music player. It embodies a unique digital culture, aesthetic, and user experience. With this initiative to open the source code, Winamp is taking the next step in its history, allowing its users to contribute directly to improving the product.

     "This is a decision that will delight millions of users around the world. Our focus will be on new mobile players and other platforms. We will be releasing a new mobile player at the beginning of July. Still, we don't want to forget the tens of millions of users who use the software on Windows and will benefit from thousands of developers' experience and creativity. Winamp will remain the owner of the software and will decide on the innovations made in the official version," explains Alexandre Saboundjian, CEO of Winamp.

    Interested developers can now make themselves known at the following address: about.winamp.com/free-llama

    Subscribe to our newsletter

    Get the best content for creators delivered to your inbox every week.

    Winamp

    Dec 16, 1

    Press Release

    Winamp has announced that it is opening up its source code to enable collaborative development of its legendary player for Windows.

    Winamp has announced that on 24 September 2024, the application's source code will be open to developers worldwide.

    Winamp will open up its code for the player used on Windows, enabling the entire community to participate in its development. This is an invitation to global collaboration, where developers worldwide can contribute their expertise, ideas, and passion to help this iconic software evolve.

    Winamp has become much more than just a music player. It embodies a unique digital culture, aesthetic, and user experience. With this initiative to open the source code, Winamp is taking the next step in its history, allowing its users to contribute directly to improving the product.

     "This is a decision that will delight millions of users around the world. Our focus will be on new mobile players and other platforms. We will be releasing a new mobile player at the beginning of July. Still, we don't want to forget the tens of millions of users who use the software on Windows and will benefit from thousands of developers' experience and creativity. Winamp will remain the owner of the software and will decide on the innovations made in the official version," explains Alexandre Saboundjian, CEO of Winamp.

    Interested developers can now make themselves known at the following address: about.winamp.com/free-llama

    Subscribe to our newsletter

    Get the best content for creators delivered to your inbox every week.

    Genocide Trial in Guatemala Brings Memories of Israel’s Role in the Killings

    Portside
    portside.org
    2024-05-16 21:52:03
    Genocide Trial in Guatemala Brings Memories of Israel’s Role in the Killings jay Thu, 05/16/2024 - 16:52 ...
    Original Article

    As the genocide trial of retired Guatemalan General Benedicto Lucas Garcia unfolds in a courtroom in Guatemala City, Indigenous Maya witnesses—some in strained voices or reduced to tears—describe the killing methods used by soldiers. A woman in a woven huipil blouse grabs her chest and inclines forward to show how her mother was shot point blank. A man who was fourteen when troops came upon his family cleaning their cornfield points to his forehead and a spot above his right ear where a soldier shot his father “in front of me.” Another woman closes her fingers like the head of an ax and brings it down on the crown of her head to show how a neighbor was killed.

    As testimonies unroll, it is germane to point out that Benedicto Lucas Garcia did not commit mass murder by himself, but rather with help from the United States and Israel.

    Lucas, now ninety-one, Armed Forces Chief of Staff for his brother, President General Fernando Romeo Lucas Garcia, was the architect of the counterinsurgency in a war from 1960 to 1996 in which 200,000 died or disappeared, 93 percent of them at the hands of the state according to a United Nations-sponsored Truth Commission report. Genocide trials are rare, partly because of the difficulty of proving that the accused intended to destroy a particular group as such. Lucas is charged with deliberately seeking to eliminate Indigenous Maya in the Ixil Triangle, located in the remote mountainous region of Quiche, among the hardest hit during the war.

    Retired General Benedicto Lucas Garcia, accused of genocide, signifies his presence during roll call by the president of the tribunal at the beginning of a trial session at the Tribunals Tower in Guatemala City, 2024. Lucas attends virtually from a nearby military medical center due to health issues, with one of his three attorneys at his side, while his image is projected on the wall behind the judges.  (Photo: Mary Jo McConahay / The Progressive Magazine)

    From the time of the 1954 CIA-orchestrated coup against the progressive, democratically elected president, Jacobo Árbenz, Guatemala was led by military autocrats supported by the United States, or civilians answerable to the military. (Only in January, 2024 did another progressive, independent thinking president, Bernardo Arévalo, take office, although he continues to fight the old military guard and rightists in the business and legal sectors.) After the CIA coup, young officers rebelled in 1960 when the Guatemalan president at the time, a general, allowed Washington to train fighters for the Bay of Pigs invasion on a local plantation. Fidel Castro was a hero to many Latin Americans for throwing off the U.S. yoke; permitting the U.S. military to instruct the Cuban invaders inside Guatemala was an affront to national sovereignty.  

    Unsuccessful, the insurgents fled to the eastern Zacapa region and began a guerrilla movement aiming to overthrow the government. Washington sent in Green Berets to advise, and by some reports to fight alongside Guatemalan troops. They pursued the rebels mercilessly, used napalm, and slaughtered civilians suspected of being guerrilla supporters. In 1972 a handful of surviving insurgents regrouped as the Guerrilla Army of the Poor (EGP) and entered the Quiche region by way of Mexico. The EGP gathered thousands of supporters, including in the Ixil Triangle. Meanwhile in Guatemala City, U.S. advisors, many fresh from Vietnam, reshaped Guatemalan police and intelligence procedures. Death squads killed opposition student, church, and union leaders. In 1977 the human rights situation in Guatemala was so bleak that U.S. President Jimmy Carter stopped military aid. 


    But there was another source of weapons and advisors: Israel, “the only country that gave us support in our battle against the guerrillas,” Benedicto Lucas said, as foreign correspondent Yoav Karni reported in 1986 in the Israeli newspaper Ha’aretz

    Two members of the prosecution team listen to a witness during the genocide trial of former Guatemalan General Benedicto Lucas Garcia, architect of the counterinsurgency program in which witnesses say their entire villages were burned to the ground after families were killed. The trial took place at the Tribunals Tower in Guatemala City, 2024.  (Photo: Mary Jo McConahay / The Progressive Magazine)

    Yet Israel should not be considered a mere proxy for the United States during Lucas’s genocidal sweeps through the Ixil. Israel was a war machine on its own, searching for arms markets and anxious for allies. Tel Aviv supported the brutal Guatemalan army in Lucas’s day and beyond. 

    Israel began selling weapons to Guatemala in 1974: armored personnel carriers, military communications equipment, light cannons, machine guns, Uzis, and thousands of Galil assault rifles, which became the Guatemalan troops’ standard weapon. In the 1980s Israel built a factory inside Guatemala to produce the Galils and bullets to go with them. Tel Aviv made deliveries of its signature short take-off and landing aircraft, the Arava, several of which were later equipped with gun pods.

    “The planes came over us,” testified Caterina Rodriguez, now seventy-one, recounting the year she spent sheltering in the mountains with her husband and a brother, watching others die of starvation, eating grass after Guatemalan soldiers wiped out residents of their village and burned its houses to cinders. “The planes dropped bombs . . . we were like animals looking for places to hide,” she said in the courtroom.


    Various news media reported that Lucas said Israeli advisors were teaching locals how to use the Israeli equipment the army had purchased. But they did much more. By 1983, when the regime of Lucas’s brother had given way to another autocrat, General Efraín Ríos Montt, the EGP said there were 300 Israeli advisors in the country, “in the security structures and in the army.” 

    “Israeli advisers—some official, others private—helped Guatemalan internal security agents hunt underground rebel groups,” reported correspondent Ed Cody for The Washington Post that year. 

    An Israeli company, then called Tadiran, designed and financed the Guatemalan army’s school of transmission and electronics. At the school’s opening celebration, Lucas thanked the Israeli ambassador for “the advice and transfer of electronic technology” which brought the country up to date, and the ambassador called Guatemala “one of our best friends.” A computer supplied by Israel and housed in a former military academy became “the nerve center of the armed forces, which deals with the movements of units in the field and so on,” Lucas said. Once the army’s presence was secure in an area, Maya were concentrated into controlled settlements. Israelis advised on those as well.

    Dr. Milton Jamail, a scholar who has examined the Israel-Guatemala connection and traveled in the country during the war, wrote in the 1986 book It’s No SecretIsrael’s Military involvement in Central America that the Guatemalan government, “in facing a broad based popular movement, has come to resemble the Israelis on the West Bank and Gaza: They are an occupying army.” To stop dissent, “they must use force, but also need to plan for the more long-range effort of social control. Thus the Israeli plans at home provide a prototype for solving Guatemalan problems.”
     

    Psychologists from the Public Ministry accompany Maya massacre survivors during the trial of retired General Benedicto Lucas Garcia at the Tribunals Tower in Guatemala City, 2024.  (Photo: Mary Jo McConahay / The Progressive Magazine)

    At the end of their testimonies, witnesses in the genocide trial are asked what they want from the tribunal by lawyers of the Public Ministry, which is prosecuting the criminal case for the government, or by lawyers from the plaintiffs, the Human Rights Office of the Archdiocese of Guatemala and the Association for Justice and Reconciliation, a victims’ group.

    The witnesses usually answer with some version of the words of Juana Avilés, who was fifteen when she ran at the appearance of soldiers and later returned to find her parents dead and her house destroyed. “What obligates me is the pain I carry,” Avilés said. “I do not want my children to suffer like this.”

    [Mary Jo McConahay's latest book is "Playing God: American Catholic Bishops and the Far Right" (Melville House).]

    Show HN: I've built a macOS app for developers to clean their dev machines

    Hacker News
    apps.apple.com
    2024-05-16 21:48:58
    Comments...
    Original Article

    Screenshots

    Optimize your Mac with Cleano! Quickly clear Xcode clutter, free up disk space, and enhance system performance. Keep your development environment efficient.

    With Cleano, you can easily maintain a lean development environment, allowing for faster builds and more efficient use of your Mac’s resources. Keep your system running smoothly with just a few clicks. Embrace the simplicity of NSCleaner and make it a core part of your development routine.

    Here's how Cleano enhances your Mac's performance:

    Xcode Derived Data Cleanup:
    Detect and remove outdated or redundant derived data from Xcode, ensuring that only the most relevant build files and indexes are retained. This not only frees up significant disk space but also improves Xcode's performance.

    Package Managers Cache Management:
    Clean caches from popular package managers such as Swift Package Manager (SPM) and Carthage. By purging unused packages and temporary files, NSCleaner helps in recovering disk space and reducing build times.

    Xcode Simulator Management with simctl:
    Utilizes the simctl utility to manage installed Xcode simulators. This feature allows you to streamline your development environment by removing unused simulators and reclaiming valuable system resources.

    Subscription Information:
    - Cleano requires a subscription to access all modules except the Derived Data module. A subscription grants full access to Cleano's functionality.
    - Upon launch, you will have free access to the Derived Data module. To unlock other modules, you will need to subscribe.
    - Once you start your subscription, you will be billed automatically either monthly or annually, depending on your selection. You can cancel your subscription at any time. If you do, Cleano will disable paid features at the end of the subscription period, and only the Derived Data module will remain available.

    See our Privacy Policy and Terms here:
    https://github.com/deszip/Cleaner-Tracker/blob/main/PrivacyPolicy.md
    https://github.com/deszip/Cleaner-Tracker/blob/main/eula.md

    Feel free to report issues here:
    https://github.com/deszip/Cleaner-Tracker

    App Privacy

    The developer, Igor Igor, indicated that the app’s privacy practices may include handling of data as described below. For more information, see the developer’s privacy policy.

    Data Not Linked to You

    The following data may be collected but it is not linked to your identity:

    • Usage Data

    Privacy practices may vary based on, for example, the features you use or your age. Learn More

    Information

    Provider
    Igor Igor

    Size
    18.8 MB

    Category
    Developer Tools

    Compatibility
    Mac
    Requires macOS 12.0 or later.

    Age Rating
    4+

    Copyright
    © The Missing Bits

    Price
    Free

    In-App Purchases

    1. Monthly subscription 2,99 USD
    2. Annual subscription 34,99 USD

    Supports

    • Family Sharing

      Some in‑app purchases, including subscriptions, may be shareable with your family group when Family Sharing is enabled.

    More By This Developer

    OpenAI and Reddit Partnership

    Hacker News
    openai.com
    2024-05-16 21:34:00
    Comments...

    Germany's Sovereign Tech Fund Now Supporting FFmpeg

    Hacker News
    www.phoronix.com
    2024-05-16 21:09:19
    Comments...
    Original Article

    MULTIMEDIA

    Following Germany's Sovereign Tech Fund providing significant funding for GNOME, Rust Coreutils, PHP, a systemd bug bounty, and numerous other free software projects, the FFmpeg multimedia library is the latest beneficiary to this funding from the Germany government.

    The Sovereign Tech Fund notes that the FFmpeg project is receiving €157,580.00 for 2024 and 2025.

    FFmpeg logo

    An announcement on the FFmpeg.org project site notes:

    "The FFmpeg community is excited to announce that Germany's Sovereign Tech Fund has become its first governmental sponsor. Their support will help sustain the [maintenance] of the FFmpeg project, a critical open-source software multimedia component essential to bringing audio and video to billions around the world everyday."

    Exciting news and great continuing to see the significant investments across many open-source projects being made by the Sovereign Tech Fund.

    A long list of (advanced) JavaScript questions, and their explanations

    Hacker News
    github.com
    2024-05-16 21:07:37
    Comments...
    Original Article

    JavaScript Questions

    Note

    This repo was created in 2019 and the questions provided here are therefore based on the JavaScript syntax and behavior at that time. Since JavaScript is a constantly evolving language, there are newer language features that are not covered by the questions here.


    From basic to advanced: test how well you know JavaScript, refresh your knowledge a bit or prepare for your coding interview! 💪 🚀 I update this repo regularly with new questions. I added the answers in the **collapsed sections** below the questions, simply click on them to expand it. It's just for fun, good luck! ❤️

    Feel free to reach out to me! 😊

    Instagram || Twitter || LinkedIn || Blog

    Feel free to use them in a project! 😃 I would really appreciate a reference to this repo, I create the questions and explanations (yes I'm sad lol) and the community helps me so much to maintain and improve it! 💪🏼 Thank you and have fun!
    See 20 Available Translations 🇸🇦🇪🇬🇧🇦🇩🇪🇪🇸🇫🇷🇮🇩🇯🇵🇰🇷🇳🇱🇧🇷🇷🇺🇹🇭🇹🇷🇺🇦🇻🇳🇨🇳🇹🇼🇽🇰

    1. What's the output?

    function sayHi() {
      console.log(name);
      console.log(age);
      var name = 'Lydia';
      let age = 21;
    }
    
    sayHi();
    • A: Lydia and undefined
    • B: Lydia and ReferenceError
    • C: ReferenceError and 21
    • D: undefined and ReferenceError
    Answer

    Answer: D

    Within the function, we first declare the name variable with the var keyword. This means that the variable gets hoisted (memory space is set up during the creation phase) with the default value of undefined, until we actually get to the line where we define the variable. We haven't defined the variable yet on the line where we try to log the name variable, so it still holds the value of undefined.

    Variables with the let keyword (and const) are hoisted, but unlike var, don't get initialized. They are not accessible before the line we declare (initialize) them. This is called the "temporal dead zone". When we try to access the variables before they are declared, JavaScript throws a ReferenceError.


    2. What's the output?

    for (var i = 0; i < 3; i++) {
      setTimeout(() => console.log(i), 1);
    }
    
    for (let i = 0; i < 3; i++) {
      setTimeout(() => console.log(i), 1);
    }
    • A: 0 1 2 and 0 1 2
    • B: 0 1 2 and 3 3 3
    • C: 3 3 3 and 0 1 2
    Answer

    Answer: C

    Because of the event queue in JavaScript, the setTimeout callback function is called after the loop has been executed. Since the variable i in the first loop was declared using the var keyword, this value was global. During the loop, we incremented the value of i by 1 each time, using the unary operator ++. By the time the setTimeout callback function was invoked, i was equal to 3 in the first example.

    In the second loop, the variable i was declared using the let keyword: variables declared with the let (and const) keyword are block-scoped (a block is anything between { }). During each iteration, i will have a new value, and each value is scoped inside the loop.


    3. What's the output?

    const shape = {
      radius: 10,
      diameter() {
        return this.radius * 2;
      },
      perimeter: () => 2 * Math.PI * this.radius,
    };
    
    console.log(shape.diameter());
    console.log(shape.perimeter());
    • A: 20 and 62.83185307179586
    • B: 20 and NaN
    • C: 20 and 63
    • D: NaN and 63
    Answer

    Answer: B

    Note that the value of diameter is a regular function, whereas the value of perimeter is an arrow function.

    With arrow functions, the this keyword refers to its current surrounding scope, unlike regular functions! This means that when we call perimeter, it doesn't refer to the shape object, but to its surrounding scope (window for example).

    Since there is no value radius in the scope of the arrow function, this.radius returns undefined which, when multiplied by 2 * Math.PI, results in NaN.


    4. What's the output?

    • A: 1 and false
    • B: false and NaN
    • C: false and false
    Answer

    Answer: A

    The unary plus tries to convert an operand to a number. true is 1, and false is 0.

    The string 'Lydia' is a truthy value. What we're actually asking, is "Is this truthy value falsy?". This returns false.


    5. Which one is true?

    const bird = {
      size: 'small',
    };
    
    const mouse = {
      name: 'Mickey',
      small: true,
    };
    • A: mouse.bird.size is not valid
    • B: mouse[bird.size] is not valid
    • C: mouse[bird["size"]] is not valid
    • D: All of them are valid
    Answer

    Answer: A

    In JavaScript, all object keys are strings (unless it's a Symbol). Even though we might not type them as strings, they are always converted into strings under the hood.

    JavaScript interprets (or unboxes) statements. When we use bracket notation, it sees the first opening bracket [ and keeps going until it finds the closing bracket ]. Only then, it will evaluate the statement.

    mouse[bird.size]: First it evaluates bird.size, which is "small". mouse["small"] returns true

    However, with dot notation, this doesn't happen. mouse does not have a key called bird, which means that mouse.bird is undefined. Then, we ask for the size using dot notation: mouse.bird.size. Since mouse.bird is undefined, we're actually asking undefined.size. This isn't valid, and will throw an error similar to Cannot read property "size" of undefined.


    6. What's the output?

    let c = { greeting: 'Hey!' };
    let d;
    
    d = c;
    c.greeting = 'Hello';
    console.log(d.greeting);
    • A: Hello
    • B: Hey!
    • C: undefined
    • D: ReferenceError
    • E: TypeError
    Answer

    Answer: A

    In JavaScript, all objects interact by reference when setting them equal to each other.

    First, variable c holds a value to an object. Later, we assign d with the same reference that c has to the object.

    When you change one object, you change all of them.


    7. What's the output?

    let a = 3;
    let b = new Number(3);
    let c = 3;
    
    console.log(a == b);
    console.log(a === b);
    console.log(b === c);
    • A: true false true
    • B: false false true
    • C: true false false
    • D: false true true
    Answer

    Answer: C

    new Number() is a built-in function constructor. Although it looks like a number, it's not really a number: it has a bunch of extra features and is an object.

    When we use the == operator (Equality operator), it only checks whether it has the same value. They both have the value of 3, so it returns true.

    However, when we use the === operator (Strict equality operator), both value and type should be the same. It's not: new Number() is not a number, it's an object. Both return false.


    8. What's the output?

    class Chameleon {
      static colorChange(newColor) {
        this.newColor = newColor;
        return this.newColor;
      }
    
      constructor({ newColor = 'green' } = {}) {
        this.newColor = newColor;
      }
    }
    
    const freddie = new Chameleon({ newColor: 'purple' });
    console.log(freddie.colorChange('orange'));
    • A: orange
    • B: purple
    • C: green
    • D: TypeError
    Answer

    Answer: D

    The colorChange function is static. Static methods are designed to live only on the constructor in which they are created, and cannot be passed down to any children or called upon class instances. Since freddie is an instance of class Chameleon, the function cannot be called upon it. A TypeError is thrown.


    9. What's the output?

    let greeting;
    greetign = {}; // Typo!
    console.log(greetign);
    • A: {}
    • B: ReferenceError: greetign is not defined
    • C: undefined
    Answer

    Answer: A

    It logs the object, because we just created an empty object on the global object! When we mistyped greeting as greetign, the JS interpreter actually saw this as:

    1. global.greetign = {} in Node.js
    2. window.greetign = {}, frames.greetign = {} and self.greetign in browsers.
    3. self.greetign in web workers.
    4. globalThis.greetign in all environments.

    In order to avoid this, we can use "use strict". This makes sure that you have declared a variable before setting it equal to anything.


    10. What happens when we do this?

    function bark() {
      console.log('Woof!');
    }
    
    bark.animal = 'dog';
    • A: Nothing, this is totally fine!
    • B: SyntaxError. You cannot add properties to a function this way.
    • C: "Woof" gets logged.
    • D: ReferenceError
    Answer

    Answer: A

    This is possible in JavaScript, because functions are objects! (Everything besides primitive types are objects)

    A function is a special type of object. The code you write yourself isn't the actual function. The function is an object with properties. This property is invocable.


    11. What's the output?

    function Person(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }
    
    const member = new Person('Lydia', 'Hallie');
    Person.getFullName = function() {
      return `${this.firstName} ${this.lastName}`;
    };
    
    console.log(member.getFullName());
    • A: TypeError
    • B: SyntaxError
    • C: Lydia Hallie
    • D: undefined undefined
    Answer

    Answer: A

    In JavaScript, functions are objects, and therefore, the method getFullName gets added to the constructor function object itself. For that reason, we can call Person.getFullName(), but member.getFullName throws a TypeError.

    If you want a method to be available to all object instances, you have to add it to the prototype property:

    Person.prototype.getFullName = function() {
      return `${this.firstName} ${this.lastName}`;
    };

    12. What's the output?

    function Person(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }
    
    const lydia = new Person('Lydia', 'Hallie');
    const sarah = Person('Sarah', 'Smith');
    
    console.log(lydia);
    console.log(sarah);
    • A: Person {firstName: "Lydia", lastName: "Hallie"} and undefined
    • B: Person {firstName: "Lydia", lastName: "Hallie"} and Person {firstName: "Sarah", lastName: "Smith"}
    • C: Person {firstName: "Lydia", lastName: "Hallie"} and {}
    • D: Person {firstName: "Lydia", lastName: "Hallie"} and ReferenceError
    Answer

    Answer: A

    For sarah, we didn't use the new keyword. When using new, this refers to the new empty object we create. However, if you don't add new, this refers to the global object!

    We said that this.firstName equals "Sarah" and this.lastName equals "Smith". What we actually did, is defining global.firstName = 'Sarah' and global.lastName = 'Smith'. sarah itself is left undefined, since we don't return a value from the Person function.


    13. What are the three phases of event propagation?

    • A: Target > Capturing > Bubbling
    • B: Bubbling > Target > Capturing
    • C: Target > Bubbling > Capturing
    • D: Capturing > Target > Bubbling
    Answer

    Answer: D

    During the capturing phase, the event goes through the ancestor elements down to the target element. It then reaches the target element, and bubbling begins.


    14. All object have prototypes.

    • A: true
    • B: false
    Answer

    Answer: B

    All objects have prototypes, except for the base object. The base object is the object created by the user, or an object that is created using the new keyword. The base object has access to some methods and properties, such as .toString. This is the reason why you can use built-in JavaScript methods! All of such methods are available on the prototype. Although JavaScript can't find it directly on your object, it goes down the prototype chain and finds it there, which makes it accessible for you.


    15. What's the output?

    function sum(a, b) {
      return a + b;
    }
    
    sum(1, '2');
    • A: NaN
    • B: TypeError
    • C: "12"
    • D: 3
    Answer

    Answer: C

    JavaScript is a dynamically typed language: we don't specify what types certain variables are. Values can automatically be converted into another type without you knowing, which is called implicit type coercion. Coercion is converting from one type into another.

    In this example, JavaScript converts the number 1 into a string, in order for the function to make sense and return a value. During the addition of a numeric type (1) and a string type ('2'), the number is treated as a string. We can concatenate strings like "Hello" + "World", so what's happening here is "1" + "2" which returns "12".


    16. What's the output?

    let number = 0;
    console.log(number++);
    console.log(++number);
    console.log(number);
    • A: 1 1 2
    • B: 1 2 2
    • C: 0 2 2
    • D: 0 1 2
    Answer

    Answer: C

    The postfix unary operator ++:

    1. Returns the value (this returns 0)
    2. Increments the value (number is now 1)

    The prefix unary operator ++:

    1. Increments the value (number is now 2)
    2. Returns the value (this returns 2)

    This returns 0 2 2.


    17. What's the output?

    function getPersonInfo(one, two, three) {
      console.log(one);
      console.log(two);
      console.log(three);
    }
    
    const person = 'Lydia';
    const age = 21;
    
    getPersonInfo`${person} is ${age} years old`;
    • A: "Lydia" 21 ["", " is ", " years old"]
    • B: ["", " is ", " years old"] "Lydia" 21
    • C: "Lydia" ["", " is ", " years old"] 21
    Answer

    Answer: B

    If you use tagged template literals, the value of the first argument is always an array of the string values. The remaining arguments get the values of the passed expressions!


    18. What's the output?

    function checkAge(data) {
      if (data === { age: 18 }) {
        console.log('You are an adult!');
      } else if (data == { age: 18 }) {
        console.log('You are still an adult.');
      } else {
        console.log(`Hmm.. You don't have an age I guess`);
      }
    }
    
    checkAge({ age: 18 });
    • A: You are an adult!
    • B: You are still an adult.
    • C: Hmm.. You don't have an age I guess
    Answer

    Answer: C

    When testing equality, primitives are compared by their value, while objects are compared by their reference. JavaScript checks if the objects have a reference to the same location in memory.

    The two objects that we are comparing don't have that: the object we passed as a parameter refers to a different location in memory than the object we used in order to check equality.

    This is why both { age: 18 } === { age: 18 } and { age: 18 } == { age: 18 } return false.


    19. What's the output?

    function getAge(...args) {
      console.log(typeof args);
    }
    
    getAge(21);
    • A: "number"
    • B: "array"
    • C: "object"
    • D: "NaN"
    Answer

    Answer: C

    The rest parameter (...args) lets us "collect" all remaining arguments into an array. An array is an object, so typeof args returns "object"


    20. What's the output?

    function getAge() {
      'use strict';
      age = 21;
      console.log(age);
    }
    
    getAge();
    • A: 21
    • B: undefined
    • C: ReferenceError
    • D: TypeError
    Answer

    Answer: C

    With "use strict", you can make sure that you don't accidentally declare global variables. We never declared the variable age, and since we use "use strict", it will throw a reference error. If we didn't use "use strict", it would have worked, since the property age would have gotten added to the global object.


    21. What's the value of sum?

    const sum = eval('10*10+5');
    • A: 105
    • B: "105"
    • C: TypeError
    • D: "10*10+5"
    Answer

    Answer: A

    eval evaluates code that's passed as a string. If it's an expression, like in this case, it evaluates the expression. The expression is 10 * 10 + 5. This returns the number 105.


    22. How long is cool_secret accessible?

    sessionStorage.setItem('cool_secret', 123);
    • A: Forever, the data doesn't get lost.
    • B: When the user closes the tab.
    • C: When the user closes the entire browser, not only the tab.
    • D: When the user shuts off their computer.
    Answer

    Answer: B

    The data stored in sessionStorage is removed after closing the tab.

    If you used localStorage, the data would've been there forever, unless for example localStorage.clear() is invoked.


    23. What's the output?

    var num = 8;
    var num = 10;
    
    console.log(num);
    • A: 8
    • B: 10
    • C: SyntaxError
    • D: ReferenceError
    Answer

    Answer: B

    With the var keyword, you can declare multiple variables with the same name. The variable will then hold the latest value.

    You cannot do this with let or const since they're block-scoped and therefore can't be redeclared.


    24. What's the output?

    const obj = { 1: 'a', 2: 'b', 3: 'c' };
    const set = new Set([1, 2, 3, 4, 5]);
    
    obj.hasOwnProperty('1');
    obj.hasOwnProperty(1);
    set.has('1');
    set.has(1);
    • A: false true false true
    • B: false true true true
    • C: true true false true
    • D: true true true true
    Answer

    Answer: C

    All object keys (excluding Symbols) are strings under the hood, even if you don't type it yourself as a string. This is why obj.hasOwnProperty('1') also returns true.

    It doesn't work that way for a set. There is no '1' in our set: set.has('1') returns false. It has the numeric type 1, set.has(1) returns true.


    25. What's the output?

    const obj = { a: 'one', b: 'two', a: 'three' };
    console.log(obj);
    • A: { a: "one", b: "two" }
    • B: { b: "two", a: "three" }
    • C: { a: "three", b: "two" }
    • D: SyntaxError
    Answer

    Answer: C

    If you have two keys with the same name, the key will be replaced. It will still be in its first position, but with the last specified value.


    26. The JavaScript global execution context creates two things for you: the global object, and the "this" keyword.

    • A: true
    • B: false
    • C: it depends
    Answer

    Answer: A

    The base execution context is the global execution context: it's what's accessible everywhere in your code.


    27. What's the output?

    for (let i = 1; i < 5; i++) {
      if (i === 3) continue;
      console.log(i);
    }
    • A: 1 2
    • B: 1 2 3
    • C: 1 2 4
    • D: 1 3 4
    Answer

    Answer: C

    The continue statement skips an iteration if a certain condition returns true.


    28. What's the output?

    String.prototype.giveLydiaPizza = () => {
      return 'Just give Lydia pizza already!';
    };
    
    const name = 'Lydia';
    
    console.log(name.giveLydiaPizza())
    • A: "Just give Lydia pizza already!"
    • B: TypeError: not a function
    • C: SyntaxError
    • D: undefined
    Answer

    Answer: A

    String is a built-in constructor, that we can add properties to. I just added a method to its prototype. Primitive strings are automatically converted into a string object, generated by the string prototype function. So, all strings (string objects) have access to that method!


    29. What's the output?

    const a = {};
    const b = { key: 'b' };
    const c = { key: 'c' };
    
    a[b] = 123;
    a[c] = 456;
    
    console.log(a[b]);
    • A: 123
    • B: 456
    • C: undefined
    • D: ReferenceError
    Answer

    Answer: B

    Object keys are automatically converted into strings. We are trying to set an object as a key to object a, with the value of 123.

    However, when we stringify an object, it becomes "[object Object]". So what we are saying here, is that a["[object Object]"] = 123. Then, we can try to do the same again. c is another object that we are implicitly stringifying. So then, a["[object Object]"] = 456.

    Then, we log a[b], which is actually a["[object Object]"]. We just set that to 456, so it returns 456.


    30. What's the output?

    const foo = () => console.log('First');
    const bar = () => setTimeout(() => console.log('Second'));
    const baz = () => console.log('Third');
    
    bar();
    foo();
    baz();
    • A: First Second Third
    • B: First Third Second
    • C: Second First Third
    • D: Second Third First
    Answer

    Answer: B

    We have a setTimeout function and invoked it first. Yet, it was logged last.

    This is because in browsers, we don't just have the runtime engine, we also have something called a WebAPI. The WebAPI gives us the setTimeout function to start with, and for example the DOM.

    After the callback is pushed to the WebAPI, the setTimeout function itself (but not the callback!) is popped off the stack.

    Now, foo gets invoked, and "First" is being logged.

    foo is popped off the stack, and baz gets invoked. "Third" gets logged.

    The WebAPI can't just add stuff to the stack whenever it's ready. Instead, it pushes the callback function to something called the queue.

    This is where an event loop starts to work. An event loop looks at the stack and task queue. If the stack is empty, it takes the first thing on the queue and pushes it onto the stack.

    bar gets invoked, "Second" gets logged, and it's popped off the stack.


    31. What is the event.target when clicking the button?

    <div onclick="console.log('first div')">
      <div onclick="console.log('second div')">
        <button onclick="console.log('button')">
          Click!
        </button>
      </div>
    </div>
    • A: Outer div
    • B: Inner div
    • C: button
    • D: An array of all nested elements.
    Answer

    Answer: C

    The deepest nested element that caused the event is the target of the event. You can stop bubbling by event.stopPropagation


    32. When you click the paragraph, what's the logged output?

    <div onclick="console.log('div')">
      <p onclick="console.log('p')">
        Click here!
      </p>
    </div>
    • A: p div
    • B: div p
    • C: p
    • D: div
    Answer

    Answer: A

    If we click p, we see two logs: p and div. During event propagation, there are 3 phases: capturing, targeting, and bubbling. By default, event handlers are executed in the bubbling phase (unless you set useCapture to true). It goes from the deepest nested element outwards.


    33. What's the output?

    const person = { name: 'Lydia' };
    
    function sayHi(age) {
      return `${this.name} is ${age}`;
    }
    
    console.log(sayHi.call(person, 21));
    console.log(sayHi.bind(person, 21));
    • A: undefined is 21 Lydia is 21
    • B: function function
    • C: Lydia is 21 Lydia is 21
    • D: Lydia is 21 function
    Answer

    Answer: D

    With both, we can pass the object to which we want the this keyword to refer to. However, .call is also executed immediately!

    .bind. returns a copy of the function, but with a bound context! It is not executed immediately.


    34. What's the output?

    function sayHi() {
      return (() => 0)();
    }
    
    console.log(typeof sayHi());
    • A: "object"
    • B: "number"
    • C: "function"
    • D: "undefined"
    Answer

    Answer: B

    The sayHi function returns the returned value of the immediately invoked function expression (IIFE). This function returned 0, which is type "number".

    FYI: typeof can return the following list of values: undefined, boolean, number, bigint, string, symbol, function and object. Note that typeof null returns "object".


    35. Which of these values are falsy?

    0;
    new Number(0);
    ('');
    (' ');
    new Boolean(false);
    undefined;
    • A: 0, '', undefined
    • B: 0, new Number(0), '', new Boolean(false), undefined
    • C: 0, '', new Boolean(false), undefined
    • D: All of them are falsy
    Answer

    Answer: A

    There are 8 falsy values:

    • undefined
    • null
    • NaN
    • false
    • '' (empty string)
    • 0
    • -0
    • 0n (BigInt(0))

    Function constructors, like new Number and new Boolean are truthy.


    36. What's the output?

    console.log(typeof typeof 1);
    • A: "number"
    • B: "string"
    • C: "object"
    • D: "undefined"
    Answer

    Answer: B

    typeof 1 returns "number". typeof "number" returns "string"


    37. What's the output?

    const numbers = [1, 2, 3];
    numbers[10] = 11;
    console.log(numbers);
    • A: [1, 2, 3, null x 7, 11]
    • B: [1, 2, 3, 11]
    • C: [1, 2, 3, empty x 7, 11]
    • D: SyntaxError
    Answer

    Answer: C

    When you set a value to an element in an array that exceeds the length of the array, JavaScript creates something called "empty slots". These actually have the value of undefined, but you will see something like:

    [1, 2, 3, empty x 7, 11]

    depending on where you run it (it's different for every browser, node, etc.)


    38. What's the output?

    (() => {
      let x, y;
      try {
        throw new Error();
      } catch (x) {
        (x = 1), (y = 2);
        console.log(x);
      }
      console.log(x);
      console.log(y);
    })();
    • A: 1 undefined 2
    • B: undefined undefined undefined
    • C: 1 1 2
    • D: 1 undefined undefined
    Answer

    Answer: A

    The catch block receives the argument x. This is not the same x as the variable when we pass arguments. This variable x is block-scoped.

    Later, we set this block-scoped variable equal to 1, and set the value of the variable y. Now, we log the block-scoped variable x, which is equal to 1.

    Outside of the catch block, x is still undefined, and y is 2. When we want to console.log(x) outside of the catch block, it returns undefined, and y returns 2.


    39. Everything in JavaScript is either a...

    • A: primitive or object
    • B: function or object
    • C: trick question! only objects
    • D: number or object
    Answer

    Answer: A

    JavaScript only has primitive types and objects.

    Primitive types are boolean, null, undefined, bigint, number, string, and symbol.

    What differentiates a primitive from an object is that primitives do not have any properties or methods; however, you'll note that 'foo'.toUpperCase() evaluates to 'FOO' and does not result in a TypeError. This is because when you try to access a property or method on a primitive like a string, JavaScript will implicitly wrap the primitive type using one of the wrapper classes, i.e. String, and then immediately discard the wrapper after the expression evaluates. All primitives except for null and undefined exhibit this behavior.


    40. What's the output?

    [[0, 1], [2, 3]].reduce(
      (acc, cur) => {
        return acc.concat(cur);
      },
      [1, 2],
    );
    • A: [0, 1, 2, 3, 1, 2]
    • B: [6, 1, 2]
    • C: [1, 2, 0, 1, 2, 3]
    • D: [1, 2, 6]
    Answer

    Answer: C

    [1, 2] is our initial value. This is the value we start with, and the value of the very first acc. During the first round, acc is [1,2], and cur is [0, 1]. We concatenate them, which results in [1, 2, 0, 1].

    Then, [1, 2, 0, 1] is acc and [2, 3] is cur. We concatenate them, and get [1, 2, 0, 1, 2, 3]


    41. What's the output?

    • A: false true false
    • B: false false true
    • C: false true true
    • D: true true false
    Answer

    Answer: B

    null is falsy. !null returns true. !true returns false.

    "" is falsy. !"" returns true. !true returns false.

    1 is truthy. !1 returns false. !false returns true.


    42. What does the setInterval method return in the browser?

    setInterval(() => console.log('Hi'), 1000);
    • A: a unique id
    • B: the amount of milliseconds specified
    • C: the passed function
    • D: undefined
    Answer

    Answer: A

    It returns a unique id. This id can be used to clear that interval with the clearInterval() function.


    43. What does this return?

    • A: ["L", "y", "d", "i", "a"]
    • B: ["Lydia"]
    • C: [[], "Lydia"]
    • D: [["L", "y", "d", "i", "a"]]
    Answer

    Answer: A

    A string is an iterable. The spread operator maps every character of an iterable to one element.


    44. What's the output?

    function* generator(i) {
      yield i;
      yield i * 2;
    }
    
    const gen = generator(10);
    
    console.log(gen.next().value);
    console.log(gen.next().value);
    • A: [0, 10], [10, 20]
    • B: 20, 20
    • C: 10, 20
    • D: 0, 10 and 10, 20
    Answer

    Answer: C

    Regular functions cannot be stopped mid-way after invocation. However, a generator function can be "stopped" midway, and later continue from where it stopped. Every time a generator function encounters a yield keyword, the function yields the value specified after it. Note that the generator function in that case doesn’t return the value, it yields the value.

    First, we initialize the generator function with i equal to 10. We invoke the generator function using the next() method. The first time we invoke the generator function, i is equal to 10. It encounters the first yield keyword: it yields the value of i. The generator is now "paused", and 10 gets logged.

    Then, we invoke the function again with the next() method. It starts to continue where it stopped previously, still with i equal to 10. Now, it encounters the next yield keyword, and yields i * 2. i is equal to 10, so it returns 10 * 2, which is 20. This results in 10, 20.


    45. What does this return?

    const firstPromise = new Promise((res, rej) => {
      setTimeout(res, 500, 'one');
    });
    
    const secondPromise = new Promise((res, rej) => {
      setTimeout(res, 100, 'two');
    });
    
    Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
    • A: "one"
    • B: "two"
    • C: "two" "one"
    • D: "one" "two"
    Answer

    Answer: B

    When we pass multiple promises to the Promise.race method, it resolves/rejects the first promise that resolves/rejects. To the setTimeout method, we pass a timer: 500ms for the first promise (firstPromise), and 100ms for the second promise (secondPromise). This means that the secondPromise resolves first with the value of 'two'. res now holds the value of 'two', which gets logged.


    46. What's the output?

    let person = { name: 'Lydia' };
    const members = [person];
    person = null;
    
    console.log(members);
    • A: null
    • B: [null]
    • C: [{}]
    • D: [{ name: "Lydia" }]
    Answer

    Answer: D

    First, we declare a variable person with the value of an object that has a name property.

    Then, we declare a variable called members. We set the first element of that array equal to the value of the person variable. Objects interact by reference when setting them equal to each other. When you assign a reference from one variable to another, you make a copy of that reference. (note that they don't have the same reference!)

    Then, we set the variable person equal to null.

    We are only modifying the value of the person variable, and not the first element in the array, since that element has a different (copied) reference to the object. The first element in members still holds its reference to the original object. When we log the members array, the first element still holds the value of the object, which gets logged.


    47. What's the output?

    const person = {
      name: 'Lydia',
      age: 21,
    };
    
    for (const item in person) {
      console.log(item);
    }
    • A: { name: "Lydia" }, { age: 21 }
    • B: "name", "age"
    • C: "Lydia", 21
    • D: ["name", "Lydia"], ["age", 21]
    Answer

    Answer: B

    With a for-in loop, we can iterate through object keys, in this case name and age. Under the hood, object keys are strings (if they're not a Symbol). On every loop, we set the value of item equal to the current key it’s iterating over. First, item is equal to name, and gets logged. Then, item is equal to age, which gets logged.


    48. What's the output?

    console.log(3 + 4 + '5');
    • A: "345"
    • B: "75"
    • C: 12
    • D: "12"
    Answer

    Answer: B

    Operator associativity is the order in which the compiler evaluates the expressions, either left-to-right or right-to-left. This only happens if all operators have the same precedence. We only have one type of operator: +. For addition, the associativity is left-to-right.

    3 + 4 gets evaluated first. This results in the number 7.

    7 + '5' results in "75" because of coercion. JavaScript converts the number 7 into a string, see question 15. We can concatenate two strings using the +operator. "7" + "5" results in "75".


    49. What's the value of num?

    const num = parseInt('7*6', 10);
    • A: 42
    • B: "42"
    • C: 7
    • D: NaN
    Answer

    Answer: C

    Only the first number in the string is returned. Based on the radix (the second argument in order to specify what type of number we want to parse it to: base 10, hexadecimal, octal, binary, etc.), the parseInt checks whether the characters in the string are valid. Once it encounters a character that isn't a valid number in the radix, it stops parsing and ignores the following characters.

    * is not a valid number. It only parses "7" into the decimal 7. num now holds the value of 7.


    50. What's the output?

    [1, 2, 3].map(num => {
      if (typeof num === 'number') return;
      return num * 2;
    });
    • A: []
    • B: [null, null, null]
    • C: [undefined, undefined, undefined]
    • D: [ 3 x empty ]
    Answer

    Answer: C

    When mapping over the array, the value of num is equal to the element it’s currently looping over. In this case, the elements are numbers, so the condition of the if statement typeof num === "number" returns true. The map function creates a new array and inserts the values returned from the function.

    However, we don’t return a value. When we don’t return a value from the function, the function returns undefined. For every element in the array, the function block gets called, so for each element we return undefined.


    51. What's the output?

    function getInfo(member, year) {
      member.name = 'Lydia';
      year = '1998';
    }
    
    const person = { name: 'Sarah' };
    const birthYear = '1997';
    
    getInfo(person, birthYear);
    
    console.log(person, birthYear);
    • A: { name: "Lydia" }, "1997"
    • B: { name: "Sarah" }, "1998"
    • C: { name: "Lydia" }, "1998"
    • D: { name: "Sarah" }, "1997"
    Answer

    Answer: A

    Arguments are passed by value, unless their value is an object, then they're passed by reference. birthYear is passed by value, since it's a string, not an object. When we pass arguments by value, a copy of that value is created (see question 46).

    The variable birthYear has a reference to the value "1997". The argument year also has a reference to the value "1997", but it's not the same value as birthYear has a reference to. When we update the value of year by setting year equal to "1998", we are only updating the value of year. birthYear is still equal to "1997".

    The value of person is an object. The argument member has a (copied) reference to the same object. When we modify a property of the object member has a reference to, the value of person will also be modified, since they both have a reference to the same object. person's name property is now equal to the value "Lydia"


    52. What's the output?

    function greeting() {
      throw 'Hello world!';
    }
    
    function sayHi() {
      try {
        const data = greeting();
        console.log('It worked!', data);
      } catch (e) {
        console.log('Oh no an error:', e);
      }
    }
    
    sayHi();
    • A: It worked! Hello world!
    • B: Oh no an error: undefined
    • C: SyntaxError: can only throw Error objects
    • D: Oh no an error: Hello world!
    Answer

    Answer: D

    With the throw statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be a string, a number, a boolean or an object. In this case, our exception is the string 'Hello world!'.

    With the catch statement, we can specify what to do if an exception is thrown in the try block. An exception is thrown: the string 'Hello world!'. e is now equal to that string, which we log. This results in 'Oh an error: Hello world!'.


    53. What's the output?

    function Car() {
      this.make = 'Lamborghini';
      return { make: 'Maserati' };
    }
    
    const myCar = new Car();
    console.log(myCar.make);
    • A: "Lamborghini"
    • B: "Maserati"
    • C: ReferenceError
    • D: TypeError
    Answer

    Answer: B

    When a constructor function is called with the new keyword, it creates an object and sets the this keyword to refer to that object. By default, if the constructor function doesn't explicitly return anything, it will return the newly created object.

    In this case, the constructor function Car explicitly returns a new object with make set to "Maserati", which overrides the default behavior. Therefore, when new Car() is called, the returned object is assigned to myCar, resulting in the output being "Maserati" when myCar.make is accessed.


    54. What's the output?

    (() => {
      let x = (y = 10);
    })();
    
    console.log(typeof x);
    console.log(typeof y);
    • A: "undefined", "number"
    • B: "number", "number"
    • C: "object", "number"
    • D: "number", "undefined"
    Answer

    Answer: A

    let x = (y = 10); is actually shorthand for:

    When we set y equal to 10, we actually add a property y to the global object (window in the browser, global in Node). In a browser, window.y is now equal to 10.

    Then, we declare a variable x with the value of y, which is 10. Variables declared with the let keyword are block scoped, they are only defined within the block they're declared in; the immediately invoked function expression (IIFE) in this case. When we use the typeof operator, the operand x is not defined: we are trying to access x outside of the block it's declared in. This means that x is not defined. Values who haven't been assigned a value or declared are of type "undefined". console.log(typeof x) returns "undefined".

    However, we created a global variable y when setting y equal to 10. This value is accessible anywhere in our code. y is defined, and holds a value of type "number". console.log(typeof y) returns "number".


    55. What's the output?

    class Dog {
      constructor(name) {
        this.name = name;
      }
    }
    
    Dog.prototype.bark = function() {
      console.log(`Woof I am ${this.name}`);
    };
    
    const pet = new Dog('Mara');
    
    pet.bark();
    
    delete Dog.prototype.bark;
    
    pet.bark();
    • A: "Woof I am Mara", TypeError
    • B: "Woof I am Mara", "Woof I am Mara"
    • C: "Woof I am Mara", undefined
    • D: TypeError, TypeError
    Answer

    Answer: A

    We can delete properties from objects using the delete keyword, also on the prototype. By deleting a property on the prototype, it is not available anymore in the prototype chain. In this case, the bark function is not available anymore on the prototype after delete Dog.prototype.bark, yet we still try to access it.

    When we try to invoke something that is not a function, a TypeError is thrown. In this case TypeError: pet.bark is not a function, since pet.bark is undefined.


    56. What's the output?

    const set = new Set([1, 1, 2, 3, 4]);
    
    console.log(set);
    • A: [1, 1, 2, 3, 4]
    • B: [1, 2, 3, 4]
    • C: {1, 1, 2, 3, 4}
    • D: {1, 2, 3, 4}
    Answer

    Answer: D

    The Set object is a collection of unique values: a value can only occur once in a set.

    We passed the iterable [1, 1, 2, 3, 4] with a duplicate value 1. Since we cannot have two of the same values in a set, one of them is removed. This results in {1, 2, 3, 4}.


    57. What's the output?

    // counter.js
    let counter = 10;
    export default counter;
    // index.js
    import myCounter from './counter';
    
    myCounter += 1;
    
    console.log(myCounter);
    • A: 10
    • B: 11
    • C: Error
    • D: NaN
    Answer

    Answer: C

    An imported module is read-only: you cannot modify the imported module. Only the module that exports them can change its value.

    When we try to increment the value of myCounter, it throws an error: myCounter is read-only and cannot be modified.


    58. What's the output?

    const name = 'Lydia';
    age = 21;
    
    console.log(delete name);
    console.log(delete age);
    • A: false, true
    • B: "Lydia", 21
    • C: true, true
    • D: undefined, undefined
    Answer

    Answer: A

    The delete operator returns a boolean value: true on a successful deletion, else it'll return false. However, variables declared with the var, const, or let keywords cannot be deleted using the delete operator.

    The name variable was declared with a const keyword, so its deletion is not successful: false is returned. When we set age equal to 21, we actually added a property called age to the global object. You can successfully delete properties from objects this way, also the global object, so delete age returns true.


    59. What's the output?

    const numbers = [1, 2, 3, 4, 5];
    const [y] = numbers;
    
    console.log(y);
    • A: [[1, 2, 3, 4, 5]]
    • B: [1, 2, 3, 4, 5]
    • C: 1
    • D: [1]
    Answer

    Answer: C

    We can unpack values from arrays or properties from objects through destructuring. For example:

    The value of a is now 1, and the value of b is now 2. What we actually did in the question, is:

    This means that the value of y is equal to the first value in the array, which is the number 1. When we log y, 1 is returned.


    60. What's the output?

    const user = { name: 'Lydia', age: 21 };
    const admin = { admin: true, ...user };
    
    console.log(admin);
    • A: { admin: true, user: { name: "Lydia", age: 21 } }
    • B: { admin: true, name: "Lydia", age: 21 }
    • C: { admin: true, user: ["Lydia", 21] }
    • D: { admin: true }
    Answer

    Answer: B

    It's possible to combine objects using the spread operator .... It lets you create copies of the key/value pairs of one object, and add them to another object. In this case, we create copies of the user object, and add them to the admin object. The admin object now contains the copied key/value pairs, which results in { admin: true, name: "Lydia", age: 21 }.


    61. What's the output?

    const person = { name: 'Lydia' };
    
    Object.defineProperty(person, 'age', { value: 21 });
    
    console.log(person);
    console.log(Object.keys(person));
    • A: { name: "Lydia", age: 21 }, ["name", "age"]
    • B: { name: "Lydia", age: 21 }, ["name"]
    • C: { name: "Lydia"}, ["name", "age"]
    • D: { name: "Lydia"}, ["age"]
    Answer

    Answer: B

    With the defineProperty method, we can add new properties to an object, or modify existing ones. When we add a property to an object using the defineProperty method, they are by default not enumerable. The Object.keys method returns all enumerable property names from an object, in this case only "name".

    Properties added using the defineProperty method are immutable by default. You can override this behavior using the writable, configurable and enumerable properties. This way, the defineProperty method gives you a lot more control over the properties you're adding to an object.


    62. What's the output?

    const settings = {
      username: 'lydiahallie',
      level: 19,
      health: 90,
    };
    
    const data = JSON.stringify(settings, ['level', 'health']);
    console.log(data);
    • A: "{"level":19, "health":90}"
    • B: "{"username": "lydiahallie"}"
    • C: "["level", "health"]"
    • D: "{"username": "lydiahallie", "level":19, "health":90}"
    Answer

    Answer: A

    The second argument of JSON.stringify is the replacer. The replacer can either be a function or an array, and lets you control what and how the values should be stringified.

    If the replacer is an array, only the property names included in the array will be added to the JSON string. In this case, only the properties with the names "level" and "health" are included, "username" is excluded. data is now equal to "{"level":19, "health":90}".

    If the replacer is a function, this function gets called on every property in the object you're stringifying. The value returned from this function will be the value of the property when it's added to the JSON string. If the value is undefined, this property is excluded from the JSON string.


    63. What's the output?

    let num = 10;
    
    const increaseNumber = () => num++;
    const increasePassedNumber = number => number++;
    
    const num1 = increaseNumber();
    const num2 = increasePassedNumber(num1);
    
    console.log(num1);
    console.log(num2);
    • A: 10, 10
    • B: 10, 11
    • C: 11, 11
    • D: 11, 12
    Answer

    Answer: A

    The unary operator ++ first returns the value of the operand, then increments the value of the operand. The value of num1 is 10, since the increaseNumber function first returns the value of num, which is 10, and only increments the value of num afterward.

    num2 is 10, since we passed num1 to the increasePassedNumber. number is equal to 10(the value of num1). Again, the unary operator ++ first returns the value of the operand, then increments the value of the operand. The value of number is 10, so num2 is equal to 10.


    64. What's the output?

    const value = { number: 10 };
    
    const multiply = (x = { ...value }) => {
      console.log((x.number *= 2));
    };
    
    multiply();
    multiply();
    multiply(value);
    multiply(value);
    • A: 20, 40, 80, 160
    • B: 20, 40, 20, 40
    • C: 20, 20, 20, 40
    • D: NaN, NaN, 20, 40
    Answer

    Answer: C

    In ES6, we can initialize parameters with a default value. The value of the parameter will be the default value, if no other value has been passed to the function, or if the value of the parameter is "undefined". In this case, we spread the properties of the value object into a new object, so x has the default value of { number: 10 }.

    The default argument is evaluated at call time! Every time we call the function, a new object is created. We invoke the multiply function the first two times without passing a value: x has the default value of { number: 10 }. We then log the multiplied value of that number, which is 20.

    The third time we invoke multiply, we do pass an argument: the object called value. The *= operator is actually shorthand for x.number = x.number * 2: we modify the value of x.number, and log the multiplied value 20.

    The fourth time, we pass the value object again. x.number was previously modified to 20, so x.number *= 2 logs 40.


    65. What's the output?

    [1, 2, 3, 4].reduce((x, y) => console.log(x, y));
    • A: 1 2 and 3 3 and 6 4
    • B: 1 2 and 2 3 and 3 4
    • C: 1 undefined and 2 undefined and 3 undefined and 4 undefined
    • D: 1 2 and undefined 3 and undefined 4
    Answer

    Answer: D

    The first argument that the reduce method receives is the accumulator, x in this case. The second argument is the current value, y. With the reduce method, we execute a callback function on every element in the array, which could ultimately result in one single value.

    In this example, we are not returning any values, we are simply logging the values of the accumulator and the current value.

    The value of the accumulator is equal to the previously returned value of the callback function. If you don't pass the optional initialValue argument to the reduce method, the accumulator is equal to the first element on the first call.

    On the first call, the accumulator (x) is 1, and the current value (y) is 2. We don't return from the callback function, we log the accumulator, and the current values: 1 and 2 get logged.

    If you don't return a value from a function, it returns undefined. On the next call, the accumulator is undefined, and the current value is 3. undefined and 3 get logged.

    On the fourth call, we again don't return from the callback function. The accumulator is again undefined, and the current value is 4. undefined and 4 get logged.


    66. With which constructor can we successfully extend the Dog class?

    class Dog {
      constructor(name) {
        this.name = name;
      }
    };
    
    class Labrador extends Dog {
      // 1
      constructor(name, size) {
        this.size = size;
      }
      // 2
      constructor(name, size) {
        super(name);
        this.size = size;
      }
      // 3
      constructor(size) {
        super(name);
        this.size = size;
      }
      // 4
      constructor(name, size) {
        this.name = name;
        this.size = size;
      }
    
    };
    • A: 1
    • B: 2
    • C: 3
    • D: 4
    Answer

    Answer: B

    In a derived class, you cannot access the this keyword before calling super. If you try to do that, it will throw a ReferenceError: 1 and 4 would throw a reference error.

    With the super keyword, we call that parent class's constructor with the given arguments. The parent's constructor receives the name argument, so we need to pass name to super.

    The Labrador class receives two arguments, name since it extends Dog, and size as an extra property on the Labrador class. They both need to be passed to the constructor function on Labrador, which is done correctly using constructor 2.


    67. What's the output?

    // index.js
    console.log('running index.js');
    import { sum } from './sum.js';
    console.log(sum(1, 2));
    
    // sum.js
    console.log('running sum.js');
    export const sum = (a, b) => a + b;
    • A: running index.js, running sum.js, 3
    • B: running sum.js, running index.js, 3
    • C: running sum.js, 3, running index.js
    • D: running index.js, undefined, running sum.js
    Answer

    Answer: B

    With the import keyword, all imported modules are pre-parsed. This means that the imported modules get run first, and the code in the file that imports the module gets executed after.

    This is a difference between require() in CommonJS and import! With require(), you can load dependencies on demand while the code is being run. If we had used require instead of import, running index.js, running sum.js, 3 would have been logged to the console.


    68. What's the output?

    console.log(Number(2) === Number(2));
    console.log(Boolean(false) === Boolean(false));
    console.log(Symbol('foo') === Symbol('foo'));
    • A: true, true, false
    • B: false, true, false
    • C: true, false, true
    • D: true, true, true
    Answer

    Answer: A

    Every Symbol is entirely unique. The purpose of the argument passed to the Symbol is to give the Symbol a description. The value of the Symbol is not dependent on the passed argument. As we test equality, we are creating two entirely new symbols: the first Symbol('foo'), and the second Symbol('foo'). These two values are unique and not equal to each other, Symbol('foo') === Symbol('foo') returns false.


    69. What's the output?

    const name = 'Lydia Hallie';
    console.log(name.padStart(13));
    console.log(name.padStart(2));
    • A: "Lydia Hallie", "Lydia Hallie"
    • B: " Lydia Hallie", " Lydia Hallie" ("[13x whitespace]Lydia Hallie", "[2x whitespace]Lydia Hallie")
    • C: " Lydia Hallie", "Lydia Hallie" ("[1x whitespace]Lydia Hallie", "Lydia Hallie")
    • D: "Lydia Hallie", "Lyd",
    Answer

    Answer: C

    With the padStart method, we can add padding to the beginning of a string. The value passed to this method is the total length of the string together with the padding. The string "Lydia Hallie" has a length of 12. name.padStart(13) inserts 1 space at the start of the string, because 12 + 1 is 13.

    If the argument passed to the padStart method is smaller than the length of the array, no padding will be added.


    70. What's the output?

    console.log('🥑' + '💻');
    • A: "🥑💻"
    • B: 257548
    • C: A string containing their code points
    • D: Error
    Answer

    Answer: A

    With the + operator, you can concatenate strings. In this case, we are concatenating the string "🥑" with the string "💻", resulting in "🥑💻".


    71. How can we log the values that are commented out after the console.log statement?

    function* startGame() {
      const answer = yield 'Do you love JavaScript?';
      if (answer !== 'Yes') {
        return "Oh wow... Guess we're done here";
      }
      return 'JavaScript loves you back ❤️';
    }
    
    const game = startGame();
    console.log(/* 1 */); // Do you love JavaScript?
    console.log(/* 2 */); // JavaScript loves you back ❤️
    • A: game.next("Yes").value and game.next().value
    • B: game.next.value("Yes") and game.next.value()
    • C: game.next().value and game.next("Yes").value
    • D: game.next.value() and game.next.value("Yes")
    Answer

    Answer: C

    A generator function "pauses" its execution when it sees the yield keyword. First, we have to let the function yield the string "Do you love JavaScript?", which can be done by calling game.next().value.

    Every line is executed, until it finds the first yield keyword. There is a yield keyword on the first line within the function: the execution stops with the first yield! This means that the variable answer is not defined yet!

    When we call game.next("Yes").value, the previous yield is replaced with the value of the parameters passed to the next() function, "Yes" in this case. The value of the variable answer is now equal to "Yes". The condition of the if-statement returns false, and JavaScript loves you back ❤️ gets logged.


    72. What's the output?

    console.log(String.raw`Hello\nworld`);
    • A: Hello world!
    • B: Hello
           world
    • C: Hello\nworld
    • D: Hello\n
           world
    Answer

    Answer: C

    String.raw returns a string where the escapes (\n, \v, \t etc.) are ignored! Backslashes can be an issue since you could end up with something like:

    const path = `C:\Documents\Projects\table.html`

    Which would result in:

    "C:DocumentsProjects able.html"

    With String.raw, it would simply ignore the escape and print:

    C:\Documents\Projects\table.html

    In this case, the string is Hello\nworld, which gets logged.


    73. What's the output?

    async function getData() {
      return await Promise.resolve('I made it!');
    }
    
    const data = getData();
    console.log(data);
    • A: "I made it!"
    • B: Promise {<resolved>: "I made it!"}
    • C: Promise {<pending>}
    • D: undefined
    Answer

    Answer: C

    An async function always returns a promise. The await still has to wait for the promise to resolve: a pending promise gets returned when we call getData() in order to set data equal to it.

    If we wanted to get access to the resolved value "I made it", we could have used the .then() method on data:

    data.then(res => console.log(res))

    This would've logged "I made it!"


    74. What's the output?

    function addToList(item, list) {
      return list.push(item);
    }
    
    const result = addToList('apple', ['banana']);
    console.log(result);
    • A: ['apple', 'banana']
    • B: 2
    • C: true
    • D: undefined
    Answer

    Answer: B

    The .push() method returns the length of the new array! Previously, the array contained one element (the string "banana") and had a length of 1. After adding the string "apple" to the array, the array contains two elements, and has a length of 2. This gets returned from the addToList function.

    The push method modifies the original array. If you wanted to return the array from the function rather than the length of the array, you should have returned list after pushing item to it.


    75. What's the output?

    const box = { x: 10, y: 20 };
    
    Object.freeze(box);
    
    const shape = box;
    shape.x = 100;
    
    console.log(shape);
    • A: { x: 100, y: 20 }
    • B: { x: 10, y: 20 }
    • C: { x: 100 }
    • D: ReferenceError
    Answer

    Answer: B

    Object.freeze makes it impossible to add, remove, or modify properties of an object (unless the property's value is another object).

    When we create the variable shape and set it equal to the frozen object box, shape also refers to a frozen object. You can check whether an object is frozen by using Object.isFrozen. In this case, Object.isFrozen(shape) would return true, since the variable shape has a reference to a frozen object.

    Since shape is frozen, and since the value of x is not an object, we cannot modify the property x. x is still equal to 10, and { x: 10, y: 20 } gets logged.


    76. What's the output?

    const { firstName: myName } = { firstName: 'Lydia' };
    
    console.log(firstName);
    • A: "Lydia"
    • B: "myName"
    • C: undefined
    • D: ReferenceError
    Answer

    Answer: D

    By using destructuring assignment syntax we can unpack values from arrays, or properties from objects, into distinct variables:

    const { firstName } = { firstName: 'Lydia' };
    // ES5 version:
    // var firstName = { firstName: 'Lydia' }.firstName;
    
    console.log(firstName); // "Lydia"

    Also, a property can be unpacked from an object and assigned to a variable with a different name than the object property:

    const { firstName: myName } = { firstName: 'Lydia' };
    // ES5 version:
    // var myName = { firstName: 'Lydia' }.firstName;
    
    console.log(myName); // "Lydia"
    console.log(firstName); // Uncaught ReferenceError: firstName is not defined

    Therefore, firstName does not exist as a variable, thus attempting to access its value will raise a ReferenceError.

    Note: Be aware of the global scope properties:

    const { name: myName } = { name: 'Lydia' };
    
    console.log(myName); // "lydia"
    console.log(name); // "" ----- Browser e.g. Chrome
    console.log(name); // ReferenceError: name is not defined  ----- NodeJS

    Whenever Javascript is unable to find a variable within the current scope, it climbs up the Scope chain and searches for it and if it reaches the top-level scope, aka Global scope, and still doesn't find it, it will throw a ReferenceError.

    • In Browsers such as Chrome, name is a deprecated global scope property. In this example, the code is running inside global scope and there is no user-defined local variable for name, therefore it searches the predefined variables/properties in the global scope which is in the case of browsers, it searches through window object and it will extract the window.name value which is equal to an empty string.

    • In NodeJS, there is no such property on the global object, thus attempting to access a non-existent variable will raise a ReferenceError.


    77. Is this a pure function?

    function sum(a, b) {
      return a + b;
    }
    • A: Yes
    • B: No
    Answer

    Answer: A

    A pure function is a function that always returns the same result, if the same arguments are passed.

    The sum function always returns the same result. If we pass 1 and 2, it will always return 3 without side effects. If we pass 5 and 10, it will always return 15, and so on. This is the definition of a pure function.


    78. What is the output?

    const add = () => {
      const cache = {};
      return num => {
        if (num in cache) {
          return `From cache! ${cache[num]}`;
        } else {
          const result = num + 10;
          cache[num] = result;
          return `Calculated! ${result}`;
        }
      };
    };
    
    const addFunction = add();
    console.log(addFunction(10));
    console.log(addFunction(10));
    console.log(addFunction(5 * 2));
    • A: Calculated! 20 Calculated! 20 Calculated! 20
    • B: Calculated! 20 From cache! 20 Calculated! 20
    • C: Calculated! 20 From cache! 20 From cache! 20
    • D: Calculated! 20 From cache! 20 Error
    Answer

    Answer: C

    The add function is a memoized function. With memoization, we can cache the results of a function in order to speed up its execution. In this case, we create a cache object that stores the previously returned values.

    If we call the addFunction function again with the same argument, it first checks whether it has already gotten that value in its cache. If that's the case, the cache value will be returned, which saves execution time. Otherwise, if it's not cached, it will calculate the value and store it afterward.

    We call the addFunction function three times with the same value: on the first invocation, the value of the function when num is equal to 10 isn't cached yet. The condition of the if-statement num in cache returns false, and the else block gets executed: Calculated! 20 gets logged, and the value of the result gets added to the cache object. cache now looks like { 10: 20 }.

    The second time, the cache object contains the value that gets returned for 10. The condition of the if-statement num in cache returns true, and 'From cache! 20' gets logged.

    The third time, we pass 5 * 2 to the function which gets evaluated to 10. The cache object contains the value that gets returned for 10. The condition of the if-statement num in cache returns true, and 'From cache! 20' gets logged.


    79. What is the output?

    const myLifeSummedUp = ['☕', '💻', '🍷', '🍫'];
    
    for (let item in myLifeSummedUp) {
      console.log(item);
    }
    
    for (let item of myLifeSummedUp) {
      console.log(item);
    }
    • A: 0 1 2 3 and "☕" "💻" "🍷" "🍫"
    • B: "☕" "💻" "🍷" "🍫" and "☕" "💻" "🍷" "🍫"
    • C: "☕" "💻" "🍷" "🍫" and 0 1 2 3
    • D: 0 1 2 3 and {0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}
    Answer

    Answer: A

    With a for-in loop, we can iterate over enumerable properties. In an array, the enumerable properties are the "keys" of array elements, which are actually their indexes. You could see an array as:

    {0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}

    Where the keys are the enumerable properties. 0 1 2 3 get logged.

    With a for-of loop, we can iterate over iterables. An array is an iterable. When we iterate over the array, the variable "item" is equal to the element it's currently iterating over, "☕" "💻" "🍷" "🍫" get logged.


    80. What is the output?

    const list = [1 + 2, 1 * 2, 1 / 2];
    console.log(list);
    • A: ["1 + 2", "1 * 2", "1 / 2"]
    • B: ["12", 2, 0.5]
    • C: [3, 2, 0.5]
    • D: [1, 1, 1]
    Answer

    Answer: C

    Array elements can hold any value. Numbers, strings, objects, other arrays, null, boolean values, undefined, and other expressions such as dates, functions, and calculations.

    The element will be equal to the returned value. 1 + 2 returns 3, 1 * 2 returns 2, and 1 / 2 returns 0.5.


    81. What is the output?

    function sayHi(name) {
      return `Hi there, ${name}`;
    }
    
    console.log(sayHi());
    • A: Hi there,
    • B: Hi there, undefined
    • C: Hi there, null
    • D: ReferenceError
    Answer

    Answer: B

    By default, arguments have the value of undefined, unless a value has been passed to the function. In this case, we didn't pass a value for the name argument. name is equal to undefined which gets logged.

    In ES6, we can overwrite this default undefined value with default parameters. For example:

    function sayHi(name = "Lydia") { ... }

    In this case, if we didn't pass a value or if we passed undefined, name would always be equal to the string Lydia


    82. What is the output?

    var status = '😎';
    
    setTimeout(() => {
      const status = '😍';
    
      const data = {
        status: '🥑',
        getStatus() {
          return this.status;
        },
      };
    
      console.log(data.getStatus());
      console.log(data.getStatus.call(this));
    }, 0);
    • A: "🥑" and "😍"
    • B: "🥑" and "😎"
    • C: "😍" and "😎"
    • D: "😎" and "😎"
    Answer

    Answer: B

    The value of the this keyword is dependent on where you use it. In a method, like the getStatus method, the this keyword refers to the object that the method belongs to. The method belongs to the data object, so this refers to the data object. When we log this.status, the status property on the data object gets logged, which is "🥑".

    With the call method, we can change the object to which the this keyword refers. In functions, the this keyword refers to the the object that the function belongs to. We declared the setTimeout function on the global object, so within the setTimeout function, the this keyword refers to the global object. On the global object, there is a variable called status with the value of "😎". When logging this.status, "😎" gets logged.


    83. What is the output?

    const person = {
      name: 'Lydia',
      age: 21,
    };
    
    let city = person.city;
    city = 'Amsterdam';
    
    console.log(person);
    • A: { name: "Lydia", age: 21 }
    • B: { name: "Lydia", age: 21, city: "Amsterdam" }
    • C: { name: "Lydia", age: 21, city: undefined }
    • D: "Amsterdam"
    Answer

    Answer: A

    We set the variable city equal to the value of the property called city on the person object. There is no property on this object called city, so the variable city has the value of undefined.

    Note that we are not referencing the person object itself! We simply set the variable city equal to the current value of the city property on the person object.

    Then, we set city equal to the string "Amsterdam". This doesn't change the person object: there is no reference to that object.

    When logging the person object, the unmodified object gets returned.


    84. What is the output?

    function checkAge(age) {
      if (age < 18) {
        const message = "Sorry, you're too young.";
      } else {
        const message = "Yay! You're old enough!";
      }
    
      return message;
    }
    
    console.log(checkAge(21));
    • A: "Sorry, you're too young."
    • B: "Yay! You're old enough!"
    • C: ReferenceError
    • D: undefined
    Answer

    Answer: C

    Variables with the const and let keywords are block-scoped. A block is anything between curly brackets ({ }). In this case, the curly brackets of the if/else statements. You cannot reference a variable outside of the block it's declared in, a ReferenceError gets thrown.


    85. What kind of information would get logged?

    fetch('https://www.website.com/api/user/1')
      .then(res => res.json())
      .then(res => console.log(res));
    • A: The result of the fetch method.
    • B: The result of the second invocation of the fetch method.
    • C: The result of the callback in the previous .then().
    • D: It would always be undefined.
    Answer

    Answer: C

    The value of res in the second .then is equal to the returned value of the previous .then. You can keep chaining .thens like this, where the value is passed to the next handler.


    86. Which option is a way to set hasName equal to true, provided you cannot pass true as an argument?

    function getName(name) {
      const hasName = //
    }
    • A: !!name
    • B: name
    • C: new Boolean(name)
    • D: name.length
    Answer

    Answer: A

    With !!name, we determine whether the value of name is truthy or falsy. If the name is truthy, which we want to test for, !name returns false. !false (which is what !!name practically is) returns true.

    By setting hasName equal to name, you set hasName equal to whatever value you passed to the getName function, not the boolean value true.

    new Boolean(true) returns an object wrapper, not the boolean value itself.

    name.length returns the length of the passed argument, not whether it's true.


    87. What's the output?

    console.log('I want pizza'[0]);
    • A: """
    • B: "I"
    • C: SyntaxError
    • D: undefined
    Answer

    Answer: B

    In order to get a character at a specific index of a string, you can use bracket notation. The first character in the string has index 0, and so on. In this case, we want to get the element with index 0, the character "I', which gets logged.

    Note that this method is not supported in IE7 and below. In that case, use .charAt().


    88. What's the output?

    function sum(num1, num2 = num1) {
      console.log(num1 + num2);
    }
    
    sum(10);
    • A: NaN
    • B: 20
    • C: ReferenceError
    • D: undefined
    Answer

    Answer: B

    You can set a default parameter's value equal to another parameter of the function, as long as they've been defined before the default parameter. We pass the value 10 to the sum function. If the sum function only receives 1 argument, it means that the value for num2 is not passed, and the value of num1 is equal to the passed value 10 in this case. The default value of num2 is the value of num1, which is 10. num1 + num2 returns 20.

    If you're trying to set a default parameter's value equal to a parameter that is defined after (to the right), the parameter's value hasn't been initialized yet, which will throw an error.


    89. What's the output?

    // module.js
    export default () => 'Hello world';
    export const name = 'Lydia';
    
    // index.js
    import * as data from './module';
    
    console.log(data);
    • A: { default: function default(), name: "Lydia" }
    • B: { default: function default() }
    • C: { default: "Hello world", name: "Lydia" }
    • D: Global object of module.js
    Answer

    Answer: A

    With the import * as name syntax, we import all exports from the module.js file into the index.js file as a new object called data is created. In the module.js file, there are two exports: the default export, and a named export. The default export is a function that returns the string "Hello World", and the named export is a variable called name which has the value of the string "Lydia".

    The data object has a default property for the default export, other properties have the names of the named exports and their corresponding values.


    90. What's the output?

    class Person {
      constructor(name) {
        this.name = name;
      }
    }
    
    const member = new Person('John');
    console.log(typeof member);
    • A: "class"
    • B: "function"
    • C: "object"
    • D: "string"
    Answer

    Answer: C

    Classes are syntactical sugar for function constructors. The equivalent of the Person class as a function constructor would be:

    function Person(name) {
      this.name = name;
    }

    Calling a function constructor with new results in the creation of an instance of Person, typeof keyword returns "object" for an instance. typeof member returns "object".


    91. What's the output?

    let newList = [1, 2, 3].push(4);
    
    console.log(newList.push(5));
    • A: [1, 2, 3, 4, 5]
    • B: [1, 2, 3, 5]
    • C: [1, 2, 3, 4]
    • D: Error
    Answer

    Answer: D

    The .push method returns the new length of the array, not the array itself! By setting newList equal to [1, 2, 3].push(4), we set newList equal to the new length of the array: 4.

    Then, we try to use the .push method on newList. Since newList is the numerical value 4, we cannot use the .push method: a TypeError is thrown.


    92. What's the output?

    function giveLydiaPizza() {
      return 'Here is pizza!';
    }
    
    const giveLydiaChocolate = () =>
      "Here's chocolate... now go hit the gym already.";
    
    console.log(giveLydiaPizza.prototype);
    console.log(giveLydiaChocolate.prototype);
    • A: { constructor: ...} { constructor: ...}
    • B: {} { constructor: ...}
    • C: { constructor: ...} {}
    • D: { constructor: ...} undefined
    Answer

    Answer: D

    Regular functions, such as the giveLydiaPizza function, have a prototype property, which is an object (prototype object) with a constructor property. Arrow functions however, such as the giveLydiaChocolate function, do not have this prototype property. undefined gets returned when trying to access the prototype property using giveLydiaChocolate.prototype.


    93. What's the output?

    const person = {
      name: 'Lydia',
      age: 21,
    };
    
    for (const [x, y] of Object.entries(person)) {
      console.log(x, y);
    }
    • A: name Lydia and age 21
    • B: ["name", "Lydia"] and ["age", 21]
    • C: ["name", "age"] and undefined
    • D: Error
    Answer

    Answer: A

    Object.entries(person) returns an array of nested arrays, containing the keys and objects:

    [ [ 'name', 'Lydia' ], [ 'age', 21 ] ]

    Using the for-of loop, we can iterate over each element in the array, the subarrays in this case. We can destructure the subarrays instantly in the for-of loop, using const [x, y]. x is equal to the first element in the subarray, y is equal to the second element in the subarray.

    The first subarray is [ "name", "Lydia" ], with x equal to "name", and y equal to "Lydia", which get logged. The second subarray is [ "age", 21 ], with x equal to "age", and y equal to 21, which get logged.


    94. What's the output?

    function getItems(fruitList, ...args, favoriteFruit) {
      return [...fruitList, ...args, favoriteFruit]
    }
    
    getItems(["banana", "apple"], "pear", "orange")
    • A: ["banana", "apple", "pear", "orange"]
    • B: [["banana", "apple"], "pear", "orange"]
    • C: ["banana", "apple", ["pear"], "orange"]
    • D: SyntaxError
    Answer

    Answer: D

    ...args is a rest parameter. The rest parameter's value is an array containing all remaining arguments, and can only be the last parameter! In this example, the rest parameter was the second parameter. This is not possible, and will throw a syntax error.

    function getItems(fruitList, favoriteFruit, ...args) {
      return [...fruitList, ...args, favoriteFruit];
    }
    
    getItems(['banana', 'apple'], 'pear', 'orange');

    The above example works. This returns the array [ 'banana', 'apple', 'orange', 'pear' ]


    95. What's the output?

    function nums(a, b) {
      if (a > b) console.log('a is bigger');
      else console.log('b is bigger');
      return
      a + b;
    }
    
    console.log(nums(4, 2));
    console.log(nums(1, 2));
    • A: a is bigger, 6 and b is bigger, 3
    • B: a is bigger, undefined and b is bigger, undefined
    • C: undefined and undefined
    • D: SyntaxError
    Answer

    Answer: B

    In JavaScript, we don't have to write the semicolon (;) explicitly, however the JavaScript engine still adds them after statements. This is called Automatic Semicolon Insertion. A statement can for example be variables, or keywords like throw, return, break, etc.

    Here, we wrote a return statement, and another value a + b on a new line. However, since it's a new line, the engine doesn't know that it's actually the value that we wanted to return. Instead, it automatically added a semicolon after return. You could see this as:

    This means that a + b is never reached, since a function stops running after the return keyword. If no value gets returned, like here, the function returns undefined. Note that there is no automatic insertion after if/else statements!


    96. What's the output?

    class Person {
      constructor() {
        this.name = 'Lydia';
      }
    }
    
    Person = class AnotherPerson {
      constructor() {
        this.name = 'Sarah';
      }
    };
    
    const member = new Person();
    console.log(member.name);
    • A: "Lydia"
    • B: "Sarah"
    • C: Error: cannot redeclare Person
    • D: SyntaxError
    Answer

    Answer: B

    We can set classes equal to other classes/function constructors. In this case, we set Person equal to AnotherPerson. The name on this constructor is Sarah, so the name property on the new Person instance member is "Sarah".


    97. What's the output?

    const info = {
      [Symbol('a')]: 'b',
    };
    
    console.log(info);
    console.log(Object.keys(info));
    • A: {Symbol('a'): 'b'} and ["{Symbol('a')"]
    • B: {} and []
    • C: { a: "b" } and ["a"]
    • D: {Symbol('a'): 'b'} and []
    Answer

    Answer: D

    A Symbol is not enumerable. The Object.keys method returns all enumerable key properties on an object. The Symbol won't be visible, and an empty array is returned. When logging the entire object, all properties will be visible, even non-enumerable ones.

    This is one of the many qualities of a symbol: besides representing an entirely unique value (which prevents accidental name collision on objects, for example when working with 2 libraries that want to add properties to the same object), you can also "hide" properties on objects this way (although not entirely. You can still access symbols using the Object.getOwnPropertySymbols() method).


    98. What's the output?

    const getList = ([x, ...y]) => [x, y]
    const getUser = user => { name: user.name, age: user.age }
    
    const list = [1, 2, 3, 4]
    const user = { name: "Lydia", age: 21 }
    
    console.log(getList(list))
    console.log(getUser(user))
    • A: [1, [2, 3, 4]] and SyntaxError
    • B: [1, [2, 3, 4]] and { name: "Lydia", age: 21 }
    • C: [1, 2, 3, 4] and { name: "Lydia", age: 21 }
    • D: Error and { name: "Lydia", age: 21 }
    Answer

    Answer: A

    The getList function receives an array as its argument. Between the parentheses of the getList function, we destructure this array right away. You could see this as:

    [x, ...y] = [1, 2, 3, 4]

    With the rest parameter ...y, we put all "remaining" arguments in an array. The remaining arguments are 2, 3 and 4 in this case. The value of y is an array, containing all the rest parameters. The value of x is equal to 1 in this case, so when we log [x, y], [1, [2, 3, 4]] gets logged.

    The getUser function receives an object. With arrow functions, we don't have to write curly brackets if we just return one value. However, if you want to instantly return an object from an arrow function, you have to write it between parentheses, otherwise everything between the two braces will be interpreted as a block statement. In this case the code between the braces is not a valid JavaScript code, so a SyntaxError gets thrown.

    The following function would have returned an object:

    const getUser = user => ({ name: user.name, age: user.age })


    99. What's the output?

    const name = 'Lydia';
    
    console.log(name());
    • A: SyntaxError
    • B: ReferenceError
    • C: TypeError
    • D: undefined
    Answer

    Answer: C

    The variable name holds the value of a string, which is not a function, and thus cannot be invoked.

    TypeErrors get thrown when a value is not of the expected type. JavaScript expected name to be a function since we're trying to invoke it. It was a string however, so a TypeError gets thrown: name is not a function!

    SyntaxErrors get thrown when you've written something that isn't valid JavaScript, for example when you've written the word return as retrun. ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access.


    100. What's the value of output?

    // 🎉✨ This is my 100th question! ✨🎉
    
    const output = `${[] && 'Im'}possible!
    You should${'' && `n't`} see a therapist after so much JavaScript lol`;
    • A: possible! You should see a therapist after so much JavaScript lol
    • B: Impossible! You should see a therapist after so much JavaScript lol
    • C: possible! You shouldn't see a therapist after so much JavaScript lol
    • D: Impossible! You shouldn't see a therapist after so much JavaScript lol
    Answer

    Answer: B

    [] is a truthy value. With the && operator, the right-hand value will be returned if the left-hand value is a truthy value. In this case, the left-hand value [] is a truthy value, so "Im' gets returned.

    "" is a falsy value. If the left-hand value is falsy, nothing gets returned. n't doesn't get returned.


    101. What's the value of output?

    const one = false || {} || null;
    const two = null || false || '';
    const three = [] || 0 || true;
    
    console.log(one, two, three);
    • A: false null []
    • B: null "" true
    • C: {} "" []
    • D: null null true
    Answer

    Answer: C

    With the || operator, we can return the first truthy operand. If all values are falsy, the last operand gets returned.

    (false || {} || null): the empty object {} is a truthy value. This is the first (and only) truthy value, which gets returned. one is equal to {}.

    (null || false || ""): all operands are falsy values. This means that the last operand, "" gets returned. two is equal to "".

    ([] || 0 || ""): the empty array[] is a truthy value. This is the first truthy value, which gets returned. three is equal to [].


    102. What's the value of output?

    const myPromise = () => Promise.resolve('I have resolved!');
    
    function firstFunction() {
      myPromise().then(res => console.log(res));
      console.log('second');
    }
    
    async function secondFunction() {
      console.log(await myPromise());
      console.log('second');
    }
    
    firstFunction();
    secondFunction();
    • A: I have resolved!, second and I have resolved!, second
    • B: second, I have resolved! and second, I have resolved!
    • C: I have resolved!, second and second, I have resolved!
    • D: second, I have resolved! and I have resolved!, second
    Answer

    Answer: D

    With a promise, we basically say I want to execute this function, but I'll put it aside for now while it's running since this might take a while. Only when a certain value is resolved (or rejected), and when the call stack is empty, I want to use this value.

    We can get this value with both .then and the await keywords in an async function. Although we can get a promise's value with both .then and await, they work a bit differently.

    In the firstFunction, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which is console.log('second') in this case. Then, the function resolved with the string I have resolved, which then got logged after it saw that the callstack was empty.

    With the await keyword in secondFunction, we literally pause the execution of an async function until the value has been resolved before moving to the next line.

    This means that it waited for the myPromise to resolve with the value I have resolved, and only once that happened, we moved to the next line: second got logged.


    103. What's the value of output?

    const set = new Set();
    
    set.add(1);
    set.add('Lydia');
    set.add({ name: 'Lydia' });
    
    for (let item of set) {
      console.log(item + 2);
    }
    • A: 3, NaN, NaN
    • B: 3, 7, NaN
    • C: 3, Lydia2, [object Object]2
    • D: "12", Lydia2, [object Object]2
    Answer

    Answer: C

    The + operator is not only used for adding numerical values, but we can also use it to concatenate strings. Whenever the JavaScript engine sees that one or more values are not a number, it coerces the number into a string.

    The first one is 1, which is a numerical value. 1 + 2 returns the number 3.

    However, the second one is a string "Lydia". "Lydia" is a string and 2 is a number: 2 gets coerced into a string. "Lydia" and "2" get concatenated, which results in the string "Lydia2".

    { name: "Lydia" } is an object. Neither a number nor an object is a string, so it stringifies both. Whenever we stringify a regular object, it becomes "[object Object]". "[object Object]" concatenated with "2" becomes "[object Object]2".


    104. What's its value?

    • A: 5
    • B: Promise {<pending>: 5}
    • C: Promise {<fulfilled>: 5}
    • D: Error
    Answer

    Answer: C

    We can pass any type of value we want to Promise.resolve, either a promise or a non-promise. The method itself returns a promise with the resolved value (<fulfilled>). If you pass a regular function, it'll be a resolved promise with a regular value. If you pass a promise, it'll be a resolved promise with the resolved value of that passed promise.

    In this case, we just passed the numerical value 5. It returns a resolved promise with the value 5.


    105. What's its value?

    function compareMembers(person1, person2 = person) {
      if (person1 !== person2) {
        console.log('Not the same!');
      } else {
        console.log('They are the same!');
      }
    }
    
    const person = { name: 'Lydia' };
    
    compareMembers(person);
    • A: Not the same!
    • B: They are the same!
    • C: ReferenceError
    • D: SyntaxError
    Answer

    Answer: B

    Objects are passed by reference. When we check objects for strict equality (===), we're comparing their references.

    We set the default value for person2 equal to the person object, and passed the person object as the value for person1.

    This means that both values have a reference to the same spot in memory, thus they are equal.

    The code block in the else statement gets run, and They are the same! gets logged.


    106. What's its value?

    const colorConfig = {
      red: true,
      blue: false,
      green: true,
      black: true,
      yellow: false,
    };
    
    const colors = ['pink', 'red', 'blue'];
    
    console.log(colorConfig.colors[1]);
    • A: true
    • B: false
    • C: undefined
    • D: TypeError
    Answer

    Answer: D

    In JavaScript, we have two ways to access properties on an object: bracket notation, or dot notation. In this example, we use dot notation (colorConfig.colors) instead of bracket notation (colorConfig["colors"]).

    With dot notation, JavaScript tries to find the property on the object with that exact name. In this example, JavaScript tries to find a property called colors on the colorConfig object. There is no property called colors, so this returns undefined. Then, we try to access the value of the first element by using [1]. We cannot do this on a value that's undefined, so it throws a TypeError: Cannot read property '1' of undefined.

    JavaScript interprets (or unboxes) statements. When we use bracket notation, it sees the first opening bracket [ and keeps going until it finds the closing bracket ]. Only then, it will evaluate the statement. If we would've used colorConfig[colors[1]], it would have returned the value of the red property on the colorConfig object.


    107. What's its value?

    console.log('❤️' === '❤️');
    • A: true
    • B: false
    Answer

    Answer: A

    Under the hood, emojis are unicodes. The unicodes for the heart emoji is "U+2764 U+FE0F". These are always the same for the same emojis, so we're comparing two equal strings to each other, which returns true.


    108. Which of these methods modifies the original array?

    const emojis = ['✨', '🥑', '😍'];
    
    emojis.map(x => x + '✨');
    emojis.filter(x => x !== '🥑');
    emojis.find(x => x !== '🥑');
    emojis.reduce((acc, cur) => acc + '✨');
    emojis.slice(1, 2, '✨');
    emojis.splice(1, 2, '✨');
    • A: All of them
    • B: map reduce slice splice
    • C: map slice splice
    • D: splice
    Answer

    Answer: D

    With splice method, we modify the original array by deleting, replacing or adding elements. In this case, we removed 2 items from index 1 (we removed '🥑' and '😍') and added the ✨ emoji instead.

    map, filter and slice return a new array, find returns an element, and reduce returns a reduced value.


    109. What's the output?

    const food = ['🍕', '🍫', '🥑', '🍔'];
    const info = { favoriteFood: food[0] };
    
    info.favoriteFood = '🍝';
    
    console.log(food);
    • A: ['🍕', '🍫', '🥑', '🍔']
    • B: ['🍝', '🍫', '🥑', '🍔']
    • C: ['🍝', '🍕', '🍫', '🥑', '🍔']
    • D: ReferenceError
    Answer

    Answer: A

    We set the value of the favoriteFood property on the info object equal to the string with the pizza emoji, '🍕'. A string is a primitive data type. In JavaScript, primitive data types don't interact by reference.

    In JavaScript, primitive data types (everything that's not an object) interact by value. In this case, we set the value of the favoriteFood property on the info object equal to the value of the first element in the food array, the string with the pizza emoji in this case ('🍕'). A string is a primitive data type, and interact by value (see my blogpost if you're interested in learning more)

    Then, we change the value of the favoriteFood property on the info object. The food array hasn't changed, since the value of favoriteFood was merely a copy of the value of the first element in the array, and doesn't have a reference to the same spot in memory as the element on food[0]. When we log food, it's still the original array, ['🍕', '🍫', '🥑', '🍔'].


    110. What does this method do?

    • A: Parses JSON to a JavaScript value
    • B: Parses a JavaScript object to JSON
    • C: Parses any JavaScript value to JSON
    • D: Parses JSON to a JavaScript object only
    Answer

    Answer: A

    With the JSON.parse() method, we can parse JSON string to a JavaScript value.

    // Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value:
    const jsonNumber = JSON.stringify(4); // '4'
    JSON.parse(jsonNumber); // 4
    
    // Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value:
    const jsonArray = JSON.stringify([1, 2, 3]); // '[1, 2, 3]'
    JSON.parse(jsonArray); // [1, 2, 3]
    
    // Stringifying an object  into valid JSON, then parsing the JSON string to a JavaScript value:
    const jsonArray = JSON.stringify({ name: 'Lydia' }); // '{"name":"Lydia"}'
    JSON.parse(jsonArray); // { name: 'Lydia' }

    111. What's the output?

    let name = 'Lydia';
    
    function getName() {
      console.log(name);
      let name = 'Sarah';
    }
    
    getName();
    • A: Lydia
    • B: Sarah
    • C: undefined
    • D: ReferenceError
    Answer

    Answer: D

    Each function has its own execution context (or scope). The getName function first looks within its own context (scope) to see if it contains the variable name we're trying to access. In this case, the getName function contains its own name variable: we declare the variable name with the let keyword, and with the value of 'Sarah'.

    Variables with the let keyword (and const) are hoisted, but unlike var, don't get initialized. They are not accessible before the line we declare (initialize) them. This is called the "temporal dead zone". When we try to access the variables before they are declared, JavaScript throws a ReferenceError.

    If we wouldn't have declared the name variable within the getName function, the javascript engine would've looked down the scope chain. The outer scope has a variable called name with the value of Lydia. In that case, it would've logged Lydia.

    let name = 'Lydia';
    
    function getName() {
      console.log(name);
    }
    
    getName(); // Lydia

    112. What's the output?

    function* generatorOne() {
      yield ['a', 'b', 'c'];
    }
    
    function* generatorTwo() {
      yield* ['a', 'b', 'c'];
    }
    
    const one = generatorOne();
    const two = generatorTwo();
    
    console.log(one.next().value);
    console.log(two.next().value);
    • A: a and a
    • B: a and undefined
    • C: ['a', 'b', 'c'] and a
    • D: a and ['a', 'b', 'c']
    Answer

    Answer: C

    With the yield keyword, we yield values in a generator function. With the yield* keyword, we can yield values from another generator function, or iterable object (for example an array).

    In generatorOne, we yield the entire array ['a', 'b', 'c'] using the yield keyword. The value of value property on the object returned by the next method on one (one.next().value) is equal to the entire array ['a', 'b', 'c'].

    console.log(one.next().value); // ['a', 'b', 'c']
    console.log(one.next().value); // undefined

    In generatorTwo, we use the yield* keyword. This means that the first yielded value of two, is equal to the first yielded value in the iterator. The iterator is the array ['a', 'b', 'c']. The first yielded value is a, so the first time we call two.next().value, a is returned.

    console.log(two.next().value); // 'a'
    console.log(two.next().value); // 'b'
    console.log(two.next().value); // 'c'
    console.log(two.next().value); // undefined

    113. What's the output?

    console.log(`${(x => x)('I love')} to program`);
    • A: I love to program
    • B: undefined to program
    • C: ${(x => x)('I love') to program
    • D: TypeError
    Answer

    Answer: A

    Expressions within template literals are evaluated first. This means that the string will contain the returned value of the expression, the immediately invoked function (x => x)('I love') in this case. We pass the value 'I love' as an argument to the x => x arrow function. x is equal to 'I love', which gets returned. This results in I love to program.


    114. What will happen?

    let config = {
      alert: setInterval(() => {
        console.log('Alert!');
      }, 1000),
    };
    
    config = null;
    • A: The setInterval callback won't be invoked
    • B: The setInterval callback gets invoked once
    • C: The setInterval callback will still be called every second
    • D: We never invoked config.alert(), config is null
    Answer

    Answer: C

    Normally when we set objects equal to null, those objects get garbage collected as there is no reference anymore to that object. However, since the callback function within setInterval is an arrow function (thus bound to the config object), the callback function still holds a reference to the config object. As long as there is a reference, the object won't get garbage collected. Since this is an interval, setting config to null or delete-ing config.alert won't garbage-collect the interval, so the interval will still be called. It should be cleared with clearInterval(config.alert) to remove it from memory. Since it was not cleared, the setInterval callback function will still get invoked every 1000ms (1s).


    115. Which method(s) will return the value 'Hello world!'?

    const myMap = new Map();
    const myFunc = () => 'greeting';
    
    myMap.set(myFunc, 'Hello world!');
    
    //1
    myMap.get('greeting');
    //2
    myMap.get(myFunc);
    //3
    myMap.get(() => 'greeting');
    • A: 1
    • B: 2
    • C: 2 and 3
    • D: All of them
    Answer

    Answer: B

    When adding a key/value pair using the set method, the key will be the value of the first argument passed to the set function, and the value will be the second argument passed to the set function. The key is the function () => 'greeting' in this case, and the value 'Hello world'. myMap is now { () => 'greeting' => 'Hello world!' }.

    1 is wrong, since the key is not 'greeting' but () => 'greeting'. 3 is wrong, since we're creating a new function by passing it as a parameter to the get method. Object interacts by reference. Functions are objects, which is why two functions are never strictly equal, even if they are identical: they have a reference to a different spot in memory.


    116. What's the output?

    const person = {
      name: 'Lydia',
      age: 21,
    };
    
    const changeAge = (x = { ...person }) => (x.age += 1);
    const changeAgeAndName = (x = { ...person }) => {
      x.age += 1;
      x.name = 'Sarah';
    };
    
    changeAge(person);
    changeAgeAndName();
    
    console.log(person);
    • A: {name: "Sarah", age: 22}
    • B: {name: "Sarah", age: 23}
    • C: {name: "Lydia", age: 22}
    • D: {name: "Lydia", age: 23}
    Answer

    Answer: C

    Both the changeAge and changeAgeAndName functions have a default parameter, namely a newly created object { ...person }. This object has copies of all the key/values in the person object.

    First, we invoke the changeAge function and pass the person object as its argument. This function increases the value of the age property by 1. person is now { name: "Lydia", age: 22 }.

    Then, we invoke the changeAgeAndName function, however we don't pass a parameter. Instead, the value of x is equal to a new object: { ...person }. Since it's a new object, it doesn't affect the values of the properties on the person object. person is still equal to { name: "Lydia", age: 22 }.


    117. Which of the following options will return 6?

    function sumValues(x, y, z) {
      return x + y + z;
    }
    • A: sumValues([...1, 2, 3])
    • B: sumValues([...[1, 2, 3]])
    • C: sumValues(...[1, 2, 3])
    • D: sumValues([1, 2, 3])
    Answer

    Answer: C

    With the spread operator ..., we can spread iterables to individual elements. The sumValues function receives three arguments: x, y and z. ...[1, 2, 3] will result in 1, 2, 3, which we pass to the sumValues function.


    118. What's the output?

    let num = 1;
    const list = ['🥳', '🤠', '🥰', '🤪'];
    
    console.log(list[(num += 1)]);
    • A: 🤠
    • B: 🥰
    • C: SyntaxError
    • D: ReferenceError
    Answer

    Answer: B

    With the += operator, we're incrementing the value of num by 1. num had the initial value 1, so 1 + 1 is 2. The item on the second index in the list array is 🥰, console.log(list[2]) prints 🥰.


    119. What's the output?

    const person = {
      firstName: 'Lydia',
      lastName: 'Hallie',
      pet: {
        name: 'Mara',
        breed: 'Dutch Tulip Hound',
      },
      getFullName() {
        return `${this.firstName} ${this.lastName}`;
      },
    };
    
    console.log(person.pet?.name);
    console.log(person.pet?.family?.name);
    console.log(person.getFullName?.());
    console.log(member.getLastName?.());
    • A: undefined undefined undefined undefined
    • B: Mara undefined Lydia Hallie ReferenceError
    • C: Mara null Lydia Hallie null
    • D: null ReferenceError null ReferenceError
    Answer

    Answer: B

    With the optional chaining operator ?., we no longer have to explicitly check whether the deeper nested values are valid or not. If we're trying to access a property on an undefined or null value (nullish), the expression short-circuits and returns undefined.

    person.pet?.name: person has a property named pet: person.pet is not nullish. It has a property called name, and returns Mara. person.pet?.family?.name: person has a property named pet: person.pet is not nullish. pet does not have a property called family, person.pet.family is nullish. The expression returns undefined. person.getFullName?.(): person has a property named getFullName: person.getFullName() is not nullish and can get invoked, which returns Lydia Hallie. member.getLastName?.(): variable member is non-existent therefore a ReferenceError gets thrown!


    120. What's the output?

    const groceries = ['banana', 'apple', 'peanuts'];
    
    if (groceries.indexOf('banana')) {
      console.log('We have to buy bananas!');
    } else {
      console.log(`We don't have to buy bananas!`);
    }
    • A: We have to buy bananas!
    • B: We don't have to buy bananas
    • C: undefined
    • D: 1
    Answer

    Answer: B

    We passed the condition groceries.indexOf("banana") to the if-statement. groceries.indexOf("banana") returns 0, which is a falsy value. Since the condition in the if-statement is falsy, the code in the else block runs, and We don't have to buy bananas! gets logged.


    121. What's the output?

    const config = {
      languages: [],
      set language(lang) {
        return this.languages.push(lang);
      },
    };
    
    console.log(config.language);
    • A: function language(lang) { this.languages.push(lang }
    • B: 0
    • C: []
    • D: undefined
    Answer

    Answer: D

    The language method is a setter. Setters don't hold an actual value, their purpose is to modify properties. When calling a setter method, undefined gets returned.


    122. What's the output?

    const name = 'Lydia Hallie';
    
    console.log(!typeof name === 'object');
    console.log(!typeof name === 'string');
    • A: false true
    • B: true false
    • C: false false
    • D: true true
    Answer

    Answer: C

    typeof name returns "string". The string "string" is a truthy value, so !typeof name returns the boolean value false. false === "object" and false === "string" both returnfalse.

    (If we wanted to check whether the type was (un)equal to a certain type, we should've written !== instead of !typeof)


    123. What's the output?

    const add = x => y => z => {
      console.log(x, y, z);
      return x + y + z;
    };
    
    add(4)(5)(6);
    • A: 4 5 6
    • B: 6 5 4
    • C: 4 function function
    • D: undefined undefined 6
    Answer

    Answer: A

    The add function returns an arrow function, which returns an arrow function, which returns an arrow function (still with me?). The first function receives an argument x with the value of 4. We invoke the second function, which receives an argument y with the value 5. Then we invoke the third function, which receives an argument z with the value 6. When we're trying to access the value x, y and z within the last arrow function, the JS engine goes up the scope chain in order to find the values for x and y accordingly. This returns 4 5 6.


    124. What's the output?

    async function* range(start, end) {
      for (let i = start; i <= end; i++) {
        yield Promise.resolve(i);
      }
    }
    
    (async () => {
      const gen = range(1, 3);
      for await (const item of gen) {
        console.log(item);
      }
    })();
    • A: Promise {1} Promise {2} Promise {3}
    • B: Promise {<pending>} Promise {<pending>} Promise {<pending>}
    • C: 1 2 3
    • D: undefined undefined undefined
    Answer

    Answer: C

    The generator function range returns an async object with promises for each item in the range we pass: Promise{1}, Promise{2}, Promise{3}. We set the variable gen equal to the async object, after which we loop over it using a for await ... of loop. We set the variable item equal to the returned Promise values: first Promise{1}, then Promise{2}, then Promise{3}. Since we're awaiting the value of item, the resolved promise, the resolved values of the promises get returned: 1, 2, then 3.


    125. What's the output?

    const myFunc = ({ x, y, z }) => {
      console.log(x, y, z);
    };
    
    myFunc(1, 2, 3);
    • A: 1 2 3
    • B: {1: 1} {2: 2} {3: 3}
    • C: { 1: undefined } undefined undefined
    • D: undefined undefined undefined
    Answer

    Answer: D

    myFunc expects an object with properties x, y and z as its argument. Since we're only passing three separate numeric values (1, 2, 3) instead of one object with properties x, y and z ({x: 1, y: 2, z: 3}), x, y and z have their default value of undefined.


    126. What's the output?

    function getFine(speed, amount) {
      const formattedSpeed = new Intl.NumberFormat('en-US', {
        style: 'unit',
        unit: 'mile-per-hour'
      }).format(speed);
    
      const formattedAmount = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD'
      }).format(amount);
    
      return `The driver drove ${formattedSpeed} and has to pay ${formattedAmount}`;
    }
    
    console.log(getFine(130, 300))
    • A: The driver drove 130 and has to pay 300
    • B: The driver drove 130 mph and has to pay $300.00
    • C: The driver drove undefined and has to pay undefined
    • D: The driver drove 130.00 and has to pay 300.00
    Answer

    Answer: B

    With the Intl.NumberFormat method, we can format numeric values to any locale. We format the numeric value 130 to the en-US locale as a unit in mile-per-hour, which results in 130 mph. The numeric value 300 to the en-US locale as a currency in USD results in $300.00.


    127. What's the output?

    const spookyItems = ['👻', '🎃', '🕸'];
    ({ item: spookyItems[3] } = { item: '💀' });
    
    console.log(spookyItems);
    • A: ["👻", "🎃", "🕸"]
    • B: ["👻", "🎃", "🕸", "💀"]
    • C: ["👻", "🎃", "🕸", { item: "💀" }]
    • D: ["👻", "🎃", "🕸", "[object Object]"]
    Answer

    Answer: B

    By destructuring objects, we can unpack values from the right-hand object, and assign the unpacked value to the value of the same property name on the left-hand object. In this case, we're assigning the value "💀" to spookyItems[3]. This means that we're modifying the spookyItems array, we're adding the "💀" to it. When logging spookyItems, ["👻", "🎃", "🕸", "💀"] gets logged.


    128. What's the output?

    const name = 'Lydia Hallie';
    const age = 21;
    
    console.log(Number.isNaN(name));
    console.log(Number.isNaN(age));
    
    console.log(isNaN(name));
    console.log(isNaN(age));
    • A: true false true false
    • B: true false false false
    • C: false false true false
    • D: false true false true
    Answer

    Answer: C

    With the Number.isNaN method, you can check if the value you pass is a numeric value and equal to NaN. name is not a numeric value, so Number.isNaN(name) returns false. age is a numeric value, but is not equal to NaN, so Number.isNaN(age) returns false.

    With the isNaN method, you can check if the value you pass is not a number. name is not a number, so isNaN(name) returns true. age is a number, so isNaN(age) returns false.


    129. What's the output?

    const randomValue = 21;
    
    function getInfo() {
      console.log(typeof randomValue);
      const randomValue = 'Lydia Hallie';
    }
    
    getInfo();
    • A: "number"
    • B: "string"
    • C: undefined
    • D: ReferenceError
    Answer

    Answer: D

    Variables declared with the const keyword are not referenceable before their initialization: this is called the temporal dead zone. In the getInfo function, the variable randomValue is scoped in the functional scope of getInfo. On the line where we want to log the value of typeof randomValue, the variable randomValue isn't initialized yet: a ReferenceError gets thrown! The engine didn't go down the scope chain since we declared the variable randomValue in the getInfo function.


    130. What's the output?

    const myPromise = Promise.resolve('Woah some cool data');
    
    (async () => {
      try {
        console.log(await myPromise);
      } catch {
        throw new Error(`Oops didn't work`);
      } finally {
        console.log('Oh finally!');
      }
    })();
    • A: Woah some cool data
    • B: Oh finally!
    • C: Woah some cool data Oh finally!
    • D: Oops didn't work Oh finally!
    Answer

    Answer: C

    In the try block, we're logging the awaited value of the myPromise variable: "Woah some cool data". Since no errors were thrown in the try block, the code in the catch block doesn't run. The code in the finally block always runs, "Oh finally!" gets logged.


    131. What's the output?

    const emojis = ['🥑', ['✨', '✨', ['🍕', '🍕']]];
    
    console.log(emojis.flat(1));
    • A: ['🥑', ['✨', '✨', ['🍕', '🍕']]]
    • B: ['🥑', '✨', '✨', ['🍕', '🍕']]
    • C: ['🥑', ['✨', '✨', '🍕', '🍕']]
    • D: ['🥑', '✨', '✨', '🍕', '🍕']
    Answer

    Answer: B

    With the flat method, we can create a new, flattened array. The depth of the flattened array depends on the value that we pass. In this case, we passed the value 1 (which we didn't have to, that's the default value), meaning that only the arrays on the first depth will be concatenated. ['🥑'] and ['✨', '✨', ['🍕', '🍕']] in this case. Concatenating these two arrays results in ['🥑', '✨', '✨', ['🍕', '🍕']].


    132. What's the output?

    class Counter {
      constructor() {
        this.count = 0;
      }
    
      increment() {
        this.count++;
      }
    }
    
    const counterOne = new Counter();
    counterOne.increment();
    counterOne.increment();
    
    const counterTwo = counterOne;
    counterTwo.increment();
    
    console.log(counterOne.count);
    • A: 0
    • B: 1
    • C: 2
    • D: 3
    Answer

    Answer: D

    counterOne is an instance of the Counter class. The counter class contains a count property on its constructor, and an increment method. First, we invoked the increment method twice by calling counterOne.increment(). Currently, counterOne.count is 2.

    Then, we create a new variable counterTwo, and set it equal to counterOne. Since objects interact by reference, we're just creating a new reference to the same spot in memory that counterOne points to. Since it has the same spot in memory, any changes made to the object that counterTwo has a reference to, also apply to counterOne. Currently, counterTwo.count is 2.

    We invoke counterTwo.increment(), which sets count to 3. Then, we log the count on counterOne, which logs 3.


    133. What's the output?

    const myPromise = Promise.resolve(Promise.resolve('Promise'));
    
    function funcOne() {
      setTimeout(() => console.log('Timeout 1!'), 0);
      myPromise.then(res => res).then(res => console.log(`${res} 1!`));
      console.log('Last line 1!');
    }
    
    async function funcTwo() {
      const res = await myPromise;
      console.log(`${res} 2!`)
      setTimeout(() => console.log('Timeout 2!'), 0);
      console.log('Last line 2!');
    }
    
    funcOne();
    funcTwo();
    • A: Promise 1! Last line 1! Promise 2! Last line 2! Timeout 1! Timeout 2!
    • B: Last line 1! Timeout 1! Promise 1! Last line 2! Promise2! Timeout 2!
    • C: Last line 1! Promise 2! Last line 2! Promise 1! Timeout 1! Timeout 2!
    • D: Timeout 1! Promise 1! Last line 1! Promise 2! Timeout 2! Last line 2!
    Answer

    Answer: C

    First, we invoke funcOne. On the first line of funcOne, we call the asynchronous setTimeout function, from which the callback is sent to the Web API. (see my article on the event loop here.)

    Then we call the myPromise promise, which is an asynchronous operation. Pay attention, that now only the first then clause was added to the microtask queue.

    Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the setTimeout callback. This means that Last line 1! gets logged first, since this is not an asynchonous operation.

    Since the callstack is not empty yet, the setTimeout function and promise in funcOne cannot get added to the callstack yet.

    In funcTwo, the variable res gets Promise because Promise.resolve(Promise.resolve('Promise')) is equivalent to Promise.resolve('Promise') since resolving a promise just resolves it's value. The await in this line stops the execution of the function until it receives the resolution of the promise and then keeps on running synchronously until completion, so Promise 2! and then Last line 2! are logged and the setTimeout is sent to the Web API. If the first then clause in funcOne had its own log statement, it would be printed before Promise 2!. Howewer, it executed silently and put the second then clause in microtask queue. So, the second clause will be printed after Promise 2!.

    Then the call stack is empty. Promises are microtasks so they are resolved first when the call stack is empty so Promise 1! gets to be logged.

    Now, since funcTwo popped off the call stack, the call stack is empty. The callbacks waiting in the queue (() => console.log("Timeout 1!") from funcOne, and () => console.log("Timeout 2!") from funcTwo) get added to the call stack one by one. The first callback logs Timeout 1!, and gets popped off the stack. Then, the second callback logs Timeout 2!, and gets popped off the stack.


    134. How can we invoke sum in sum.js from index.js?

    // sum.js
    export default function sum(x) {
      return x + x;
    }
    
    // index.js
    import * as sum from './sum';
    • A: sum(4)
    • B: sum.sum(4)
    • C: sum.default(4)
    • D: Default aren't imported with *, only named exports
    Answer

    Answer: C

    With the asterisk *, we import all exported values from that file, both default and named. If we had the following file:

    // info.js
    export const name = 'Lydia';
    export const age = 21;
    export default 'I love JavaScript';
    
    // index.js
    import * as info from './info';
    console.log(info);

    The following would get logged:

    {
      default: "I love JavaScript",
      name: "Lydia",
      age: 21
    }

    For the sum example, it means that the imported value sum looks like this:

    { default: function sum(x) { return x + x } }

    We can invoke this function, by calling sum.default


    135. What's the output?

    const handler = {
      set: () => console.log('Added a new property!'),
      get: () => console.log('Accessed a property!'),
    };
    
    const person = new Proxy({}, handler);
    
    person.name = 'Lydia';
    person.name;
    • A: Added a new property!
    • B: Accessed a property!
    • C: Added a new property! Accessed a property!
    • D: Nothing gets logged
    Answer

    Answer: C

    With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In this case, we pass the handler object which contains two properties: set and get. set gets invoked whenever we set property values, and get gets invoked whenever we get (access) property values.

    The first argument is an empty object {}, which is the value of person. To this object, the custom behavior specified in the handler object gets added. If we add a property to the person object, set will get invoked. If we access a property on the person object, get gets invoked.

    First, we added a new property name to the proxy object (person.name = "Lydia"). set gets invoked, and logs "Added a new property!".

    Then, we access a property value on the proxy object, and the get property on the handler object is invoked. "Accessed a property!" gets logged.


    136. Which of the following will modify the person object?

    const person = { name: 'Lydia Hallie' };
    
    Object.seal(person);
    • A: person.name = "Evan Bacon"
    • B: person.age = 21
    • C: delete person.name
    • D: Object.assign(person, { age: 21 })
    Answer

    Answer: A

    With Object.seal we can prevent new properties from being added, or existing properties to be removed.

    However, you can still modify the value of existing properties.


    137. Which of the following will modify the person object?

    const person = {
      name: 'Lydia Hallie',
      address: {
        street: '100 Main St',
      },
    };
    
    Object.freeze(person);
    • A: person.name = "Evan Bacon"
    • B: delete person.address
    • C: person.address.street = "101 Main St"
    • D: person.pet = { name: "Mara" }
    Answer

    Answer: C

    The Object.freeze method freezes an object. No properties can be added, modified, or removed.

    However, it only shallowly freezes the object, meaning that only direct properties on the object are frozen. If the property is another object, like address in this case, the properties on that object aren't frozen, and can be modified.


    138. What's the output?

    const add = x => x + x;
    
    function myFunc(num = 2, value = add(num)) {
      console.log(num, value);
    }
    
    myFunc();
    myFunc(3);
    • A: 2 4 and 3 6
    • B: 2 NaN and 3 NaN
    • C: 2 Error and 3 6
    • D: 2 4 and 3 Error
    Answer

    Answer: A

    First, we invoked myFunc() without passing any arguments. Since we didn't pass arguments, num and value got their default values: num is 2, and value is the returned value of the function add. To the add function, we pass num as an argument, which had the value of 2. add returns 4, which is the value of value.

    Then, we invoked myFunc(3) and passed the value 3 as the value for the argument num. We didn't pass an argument for value. Since we didn't pass a value for the value argument, it got the default value: the returned value of the add function. To add, we pass num, which has the value of 3. add returns 6, which is the value of value.


    139. What's the output?

    class Counter {
      #number = 10
    
      increment() {
        this.#number++
      }
    
      getNum() {
        return this.#number
      }
    }
    
    const counter = new Counter()
    counter.increment()
    
    console.log(counter.#number)
    • A: 10
    • B: 11
    • C: undefined
    • D: SyntaxError
    Answer

    Answer: D

    In ES2020, we can add private variables in classes by using the #. We cannot access these variables outside of the class. When we try to log counter.#number, a SyntaxError gets thrown: we cannot access it outside the Counter class!


    140. What's missing?

    const teams = [
      { name: 'Team 1', members: ['Paul', 'Lisa'] },
      { name: 'Team 2', members: ['Laura', 'Tim'] },
    ];
    
    function* getMembers(members) {
      for (let i = 0; i < members.length; i++) {
        yield members[i];
      }
    }
    
    function* getTeams(teams) {
      for (let i = 0; i < teams.length; i++) {
        // ✨ SOMETHING IS MISSING HERE ✨
      }
    }
    
    const obj = getTeams(teams);
    obj.next(); // { value: "Paul", done: false }
    obj.next(); // { value: "Lisa", done: false }
    • A: yield getMembers(teams[i].members)
    • B: yield* getMembers(teams[i].members)
    • C: return getMembers(teams[i].members)
    • D: return yield getMembers(teams[i].members)
    Answer

    Answer: B

    In order to iterate over the members in each element in the teams array, we need to pass teams[i].members to the getMembers generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use yield*.

    If we would've written yield, return yield, or return, the entire generator function would've gotten returned the first time we called the next method.


    141. What's the output?

    const person = {
      name: 'Lydia Hallie',
      hobbies: ['coding'],
    };
    
    function addHobby(hobby, hobbies = person.hobbies) {
      hobbies.push(hobby);
      return hobbies;
    }
    
    addHobby('running', []);
    addHobby('dancing');
    addHobby('baking', person.hobbies);
    
    console.log(person.hobbies);
    • A: ["coding"]
    • B: ["coding", "dancing"]
    • C: ["coding", "dancing", "baking"]
    • D: ["coding", "running", "dancing", "baking"]
    Answer

    Answer: C

    The addHobby function receives two arguments, hobby and hobbies with the default value of the hobbies array on the person object.

    First, we invoke the addHobby function, and pass "running" as the value for hobby and an empty array as the value for hobbies. Since we pass an empty array as the value for hobbies, "running" gets added to this empty array.

    Then, we invoke the addHobby function, and pass "dancing" as the value for hobby. We didn't pass a value for hobbies, so it gets the default value, the hobbies property on the person object. We push the hobby dancing to the person.hobbies array.

    Last, we invoke the addHobby function, and pass "baking" as the value for hobby, and the person.hobbies array as the value for hobbies. We push the hobby baking to the person.hobbies array.

    After pushing dancing and baking, the value of person.hobbies is ["coding", "dancing", "baking"]


    142. What's the output?

    class Bird {
      constructor() {
        console.log("I'm a bird. 🦢");
      }
    }
    
    class Flamingo extends Bird {
      constructor() {
        console.log("I'm pink. 🌸");
        super();
      }
    }
    
    const pet = new Flamingo();
    • A: I'm pink. 🌸
    • B: I'm pink. 🌸 I'm a bird. 🦢
    • C: I'm a bird. 🦢 I'm pink. 🌸
    • D: Nothing, we didn't call any method
    Answer

    Answer: B

    We create the variable pet which is an instance of the Flamingo class. When we instantiate this instance, the constructor on Flamingo gets called. First, "I'm pink. 🌸" gets logged, after which we call super(). super() calls the constructor of the parent class, Bird. The constructor in Bird gets called, and logs "I'm a bird. 🦢".


    143. Which of the options result(s) in an error?

    const emojis = ['🎄', '🎅🏼', '🎁', '⭐'];
    
    /* 1 */ emojis.push('🦌');
    /* 2 */ emojis.splice(0, 2);
    /* 3 */ emojis = [...emojis, '🥂'];
    /* 4 */ emojis.length = 0;
    • A: 1
    • B: 1 and 2
    • C: 3 and 4
    • D: 3
    Answer

    Answer: D

    The const keyword simply means we cannot redeclare the value of that variable, it's read-only. However, the value itself isn't immutable. The properties on the emojis array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0.


    144. What do we need to add to the person object to get ["Lydia Hallie", 21] as the output of [...person]?

    const person = {
      name: "Lydia Hallie",
      age: 21
    }
    
    [...person] // ["Lydia Hallie", 21]
    • A: Nothing, object are iterable by default
    • B: *[Symbol.iterator]() { for (let x in this) yield* this[x] }
    • C: *[Symbol.iterator]() { yield* Object.values(this) }
    • D: *[Symbol.iterator]() { for (let x in this) yield this }
    Answer

    Answer: C

    Objects aren't iterable by default. An iterable is an iterable if the iterator protocol is present. We can add this manually by adding the iterator symbol [Symbol.iterator], which has to return a generator object, for example by making it a generator function *[Symbol.iterator]() {}. This generator function has to yield the Object.values of the person object if we want it to return the array ["Lydia Hallie", 21]: yield* Object.values(this).


    145. What's the output?

    let count = 0;
    const nums = [0, 1, 2, 3];
    
    nums.forEach(num => {
    	if (num) count += 1
    })
    
    console.log(count)
    • A: 1
    • B: 2
    • C: 3
    • D: 4
    Answer

    Answer: C

    The if condition within the forEach loop checks whether the value of num is truthy or falsy. Since the first number in the nums array is 0, a falsy value, the if statement's code block won't be executed. count only gets incremented for the other 3 numbers in the nums array, 1, 2 and 3. Since count gets incremented by 1 3 times, the value of count is 3.


    146. What's the output?

    function getFruit(fruits) {
    	console.log(fruits?.[1]?.[1])
    }
    
    getFruit([['🍊', '🍌'], ['🍍']])
    getFruit()
    getFruit([['🍍'], ['🍊', '🍌']])
    • A: null, undefined, 🍌
    • B: [], null, 🍌
    • C: [], [], 🍌
    • D: undefined, undefined, 🍌
    Answer

    Answer: D

    The ? allows us to optionally access deeper nested properties within objects. We're trying to log the item on index 1 within the subarray that's on index 1 of the fruits array. If the subarray on index 1 in the fruits array doesn't exist, it'll simply return undefined. If the subarray on index 1 in the fruits array exists, but this subarray doesn't have an item on its 1 index, it'll also return undefined.

    First, we're trying to log the second item in the ['🍍'] subarray of [['🍊', '🍌'], ['🍍']]. This subarray only contains one item, which means there is no item on index 1, and returns undefined.

    Then, we're invoking the getFruits function without passing a value as an argument, which means that fruits has a value of undefined by default. Since we're conditionally chaining the item on index 1 offruits, it returns undefined since this item on index 1 does not exist.

    Lastly, we're trying to log the second item in the ['🍊', '🍌'] subarray of ['🍍'], ['🍊', '🍌']. The item on index 1 within this subarray is 🍌, which gets logged.


    147. What's the output?

    class Calc {
    	constructor() {
    		this.count = 0 
    	}
    
    	increase() {
    		this.count++
    	}
    }
    
    const calc = new Calc()
    new Calc().increase()
    
    console.log(calc.count)
    • A: 0
    • B: 1
    • C: undefined
    • D: ReferenceError
    Answer

    Answer: A

    We set the variable calc equal to a new instance of the Calc class. Then, we instantiate a new instance of Calc, and invoke the increase method on this instance. Since the count property is within the constructor of the Calc class, the count property is not shared on the prototype of Calc. This means that the value of count has not been updated for the instance calc points to, count is still 0.


    148. What's the output?

    const user = {
    	email: "e@mail.com",
    	password: "12345"
    }
    
    const updateUser = ({ email, password }) => {
    	if (email) {
    		Object.assign(user, { email })
    	}
    
    	if (password) {
    		user.password = password
    	}
    
    	return user
    }
    
    const updatedUser = updateUser({ email: "new@email.com" })
    
    console.log(updatedUser === user)
    • A: false
    • B: true
    • C: TypeError
    • D: ReferenceError
    Answer

    Answer: B

    The updateUser function updates the values of the email and password properties on user, if their values are passed to the function, after which the function returns the user object. The returned value of the updateUser function is the user object, which means that the value of updatedUser is a reference to the same user object that user points to. updatedUser === user equals true.


    149. What's the output?

    const fruit = ['🍌', '🍊', '🍎']
    
    fruit.slice(0, 1)
    fruit.splice(0, 1)
    fruit.unshift('🍇')
    
    console.log(fruit)
    • A: ['🍌', '🍊', '🍎']
    • B: ['🍊', '🍎']
    • C: ['🍇', '🍊', '🍎']
    • D: ['🍇', '🍌', '🍊', '🍎']
    Answer

    Answer: C

    First, we invoke the slice method on the fruit array. The slice method does not modify the original array, but returns the value that it sliced off the array: the banana emoji. Then, we invoke the splice method on the fruit array. The splice method does modify the original array, which means that the fruit array now consists of ['🍊', '🍎']. At last, we invoke the unshift method on the fruit array, which modifies the original array by adding the provided value, ‘🍇’ in this case, as the first element in the array. The fruit array now consists of ['🍇', '🍊', '🍎'].


    150. What's the output?

    const animals = {};
    let dog = { emoji: '🐶' }
    let cat = { emoji: '🐈' }
    
    animals[dog] = { ...dog, name: "Mara" }
    animals[cat] = { ...cat, name: "Sara" }
    
    console.log(animals[dog])
    • A: { emoji: "🐶", name: "Mara" }
    • B: { emoji: "🐈", name: "Sara" }
    • C: undefined
    • D: ReferenceError
    Answer

    Answer: B

    Object keys are converted to strings.

    Since the value of dog is an object, animals[dog] actually means that we’re creating a new property called "[object Object]" equal to the new object. animals["[object Object]"] is now equal to { emoji: "🐶", name: "Mara"}.

    cat is also an object, which means that animals[cat] actually means that we’re overwriting the value of animals["[object Object]"] with the new cat properties.

    Logging animals[dog], or actually animals["[object Object]"] since converting the dog object to a string results "[object Object]", returns the { emoji: "🐈", name: "Sara" }.


    151. What's the output?

    const user = {
    	email: "my@email.com",
    	updateEmail: email => {
    		this.email = email
    	}
    }
    
    user.updateEmail("new@email.com")
    console.log(user.email)
    • A: my@email.com
    • B: new@email.com
    • C: undefined
    • D: ReferenceError
    Answer

    Answer: A

    The updateEmail function is an arrow function, and is not bound to the user object. This means that the this keyword is not referring to the user object, but refers to the global scope in this case. The value of email within the user object does not get updated. When logging the value of user.email, the original value of my@email.com gets returned.


    152. What's the output?

    const promise1 = Promise.resolve('First')
    const promise2 = Promise.resolve('Second')
    const promise3 = Promise.reject('Third')
    const promise4 = Promise.resolve('Fourth')
    
    const runPromises = async () => {
    	const res1 = await Promise.all([promise1, promise2])
    	const res2  = await Promise.all([promise3, promise4])
    	return [res1, res2]
    }
    
    runPromises()
    	.then(res => console.log(res))
    	.catch(err => console.log(err))
    • A: [['First', 'Second'], ['Fourth']]
    • B: [['First', 'Second'], ['Third', 'Fourth']]
    • C: [['First', 'Second']]
    • D: 'Third'
    Answer

    Answer: D

    The Promise.all method runs the passed promises in parallel. If one promise fails, the Promise.all method rejects with the value of the rejected promise. In this case, promise3 is rejected with the value "Third". We’re catching the rejected value in the chained catch method on the runPromises invocation to catch any errors within the runPromises function. Only "Third" gets logged, since promise3 is rejected with this value.


    153. What should the value of method be to log { name: "Lydia", age: 22 }?

    const keys = ["name", "age"]
    const values = ["Lydia", 22]
    
    const method = /* ?? */
    Object[method](keys.map((_, i) => {
    	return [keys[i], values[i]]
    })) // { name: "Lydia", age: 22 }
    • A: entries
    • B: values
    • C: fromEntries
    • D: forEach
    Answer

    Answer: C

    The fromEntries method turns a 2d array into an object. The first element in each subarray will be the key, and the second element in each subarray will be the value. In this case, we’re mapping over the keys array, which returns an array that the first element is the item on the key array on the current index, and the second element is the item of the values array on the current index.

    This creates an array of subarrays containing the correct keys and values, which results in { name: "Lydia", age: 22 }


    154. What's the output?

    const createMember = ({ email, address = {}}) => {
    	const validEmail = /.+\@.+\..+/.test(email)
    	if (!validEmail) throw new Error("Valid email pls")
    
    	return {
    		email,
    		address: address ? address : null
    	}
    }
    
    const member = createMember({ email: "my@email.com" })
    console.log(member)
    • A: { email: "my@email.com", address: null }
    • B: { email: "my@email.com" }
    • C: { email: "my@email.com", address: {} }
    • D: { email: "my@email.com", address: undefined }
    Answer

    Answer: C

    The default value of address is an empty object {}. When we set the variable member equal to the object returned by the createMember function, we didn't pass a value for the address, which means that the value of the address is the default empty object {}. An empty object is a truthy value, which means that the condition of the address ? address : null conditional returns true. The value of the address is the empty object {}.


    155. What's the output?

    let randomValue = { name: "Lydia" }
    randomValue = 23
    
    if (!typeof randomValue === "string") {
    	console.log("It's not a string!")
    } else {
    	console.log("Yay it's a string!")
    }
    • A: It's not a string!
    • B: Yay it's a string!
    • C: TypeError
    • D: undefined
    Answer

    Answer: B

    The condition within the if statement checks whether the value of !typeof randomValue is equal to "string". The ! operator converts the value to a boolean value. If the value is truthy, the returned value will be false, if the value is falsy, the returned value will be true. In this case, the returned value of typeof randomValue is the truthy value "number", meaning that the value of !typeof randomValue is the boolean value false.

    !typeof randomValue === "string" always returns false, since we're actually checking false === "string". Since the condition returned false, the code block of the else statement gets run, and Yay it's a string! gets logged.

    Online Censorship's Institutional Power

    Hacker News
    madattheinternet.substack.com
    2024-05-16 20:48:39
    Comments...
    Original Article

    A person’s most valuable asset is their reputation, and there’s no better place to build one’s cachet than online. For this reason, there is a convergence of extreme wealth, power, and influence building up around the backbone of the Internet like a cancer. Without immediate organization and reaction from the atomized groups considering themselves “anti-censorship”, we will soon live in a less free world with a less open Internet where rich and influential people can dictate their own trustworthiness and slander their opposition with impunity.

    In the 11 years I have managed my forum, the Kiwi Farms, I have seen firsthand the power in allowing people to talk about people. Anyone who is permitted to freely share what they’d like about another is enabled to punch far above their own weight. When a forum organized like the Kiwi Farms hosts stories, media, and documents that never go away, it can become a permanent blight on a diligently maintained reputation belonging to surprisingly important people. When that demerit is made on someone rich and well-connected, they may dedicate years of their life to trying to erase it.

    Liz Fong-Jones is a transgender multi-millionaire, formerly employed by Google, but now involved in at least two San Francisco tech startups: Honeycomb and Tall Poppy.1 His résumé and portfolio has been leveraged to try and deplatform the Kiwi Farms since 2017. What started with a single email has expanded over seven years into a conspiracy targeting the most sensitive and important components of what makes up the Internet.

    The story of Liz Fong-Jones trying to take down the Kiwi Farms is indicative of what will soon be done to all controversial web content if there is not coordinated effort made to make the Internet, and the companies which compose it, more neutral and accountable.

    On August 18th, 2017, Liz Fong-Jones used his company’s <lizf@google.com> email address to send a complaint. The targeted provider hosted my website’s email service.2 At the time, we used Cloudflare’s security services, and a common way to bypass Cloudflare was to look at the mail server. Cloudflare does not protect email, and often the unprotected mail server for websites will be the same server or provider as the actual protected web server. Fong-Jones complained we hosted personal information, hoping that this would cause our website to go down.

    The information in question was about Trans LifeLine, a hotline for transgender people in crisis staffed by transgender volunteers. At the time, Trans LifeLine was operated by Greta Gustava and Nina Chabaul. These organizers would post extravagant lifestyle photos on their public Instagrams, meanwhile the Trans LifeLine hotline service rarely had anyone online to accept emergency calls. This led Kiwi Farms users to suspect they were stealing from their charity, so we began documenting both their lifestyle and their hotline’s performance (or lack thereof).

    Documents leaked to us by people who had worked with them showed that there was almost no organization, no internal support structure, and no training. Transgender people recruited by TLL to be call agents would then be put on lines to deal with immediately at-risk suicidal transgender people with scant information on how to actually help. Some callers reported being hung up on. Operators reported trauma from having to answer life-or-death phonecalls without any idea of what to do or say.

    Years later, and thanks to information made available only on the Kiwi Farms, they would be ousted from the organization for fraud.3 Trans LifeLine’s operators would later file under penalty of perjury that Greta and Nina had inured hundreds of thousands of dollars.4 Liz Fong-Jones tried to cover this up while it was happening by silencing the only people who were, at this point in time, both aware of and capable of discussing transgender issues in a less-than-flattering way without being banned.

    This would begin the long trend of transgender activists saying “ignore the bad things on Kiwi Farms, they’re made up” with the punchline being that we’d end up proven right over time, and with damage done that could have been mitigated if we were trusted sooner. It would take Fong-Jones 6 years to admit that Trans LifeLine was a scam at the time he was supporting them. He explains he now only donates money to causes where he can directly influence the way it operates.5 Liz Fong-Jones should be thanking us, but he still holds a vicious grudge because we reported the abuse of his Google work email.

    It's necessary to be non-anonymous to the organisations that intermediate your giving in order to get a seat at the governance table and ensure that funds are being appropriately spent. That was a very very painful lesson I learned from the fiasco that was the early days of Trans Lifeline, where the inexperienced initial board did not meaningfully keep the founders in check / insist on audits, and the major donors (including myself) didn't think to ask for board seats to provide oversight, leading to us all getting defrauded.6

    You will never hear the story of how Kiwi Farms identified fraud in a charity, because it is not written about. There is not a single article from a supposedly trustworthy media source about this scandal. No journalist in the world can catalog what the Kiwi Farms gets right, because the truth is a secondary concern to them, sitting under what is politically expedient.

    Fong-Jones would continue working at Google for another 2 years. Anonymous reports regarding internal politics within the company where Fong-Jones worked paint a picture of a continuous menace, always looking for new victims to cause problems for. Fong-Jones even finds himself named in the famous James Damore discrimination lawsuit against Google for discriminatory posts made on internal Google forums.7

    He claims to have resigned in 2019, after the Google Walkout protests he helped organize. Insiders reported that Google does not give severances, unless you are asked to quit. This indicates that Fong-Jones was likely paid to leave, as opposed to his claims he resigned. Trying to fire a person in such a politically protected category, especially when they are as litigious and disruptive as Fong-Jones is, would cost more than the $90,000 he was given just to go away.

    A report from tech forum Y-Combinator. That name is important.

    During his employment with Google, he had acquired cryptocurrency and stake in the company. It is assumed that Fong-Jones’s net worth is in the millions. Indeed, Fong-Jones has stated he has an interest in finance and wants to make wealth building a part of his career.

    After leaving Google, he joined tech startup Honeycomb as Chief Field Technology Officer. Honeycomb is a business-to-business software company that sells ‘solutions’ directly to major tech companies, such as Dropbox and Slack, video game companies including CCP (EVE Online) and Behaviour (Dead by Daylight), and finance companies like Vanguard, which is one of the largest investment firms in the world.

    Honeycomb is extremely progressive and has stood by Liz Fong-Jones for years, even after he inexplicably announced to the world in November 2019 that he had been credibly accused of sexual assault, which he chooses to refer to as a “Consent Accident”.8

    Liz Fong-Jones explaining how he was accused of rape, downplaying it as a misunderstanding about dog hair.

    You won’t find any information about this online, no matter which search engine you use. Instead, you will find gushing articles, portfolio websites, Wikipedia entries, and more talking about what a successful, important person Fong-Jones is. How can someone accused of rape simply walk way from this without any of the progressive organizations around them caring?

    Search engine optimization (SEO) is one of Liz Fong-Jones’s other personal interests, as he enjoys a perfectly pedicured digital footprint. He is an investor and board member of Tall Poppy, a reputation management company.9 This company is also business-to-business, and advertises itself as “proactive action against online harassment and personal security threats”. The name comes from an expression in Australia and New Zealand, and means that successful people get unfairly criticized: ‘the tall poppy gets cut down’.

    They have a decent list of investors and advisors,10 with two names jumping out.

    Y-Combinator has invested in them. Y-Combinator is the forum which had hosted negative posts about Liz Fong-Jones quoted in this article, that I am having trouble finding now on the live version of the site.

    Inner Loop Capital is also interesting, as Tall Poppy is outside the usual scope of their portfolio. They list on their website that they invest in “digital infrastructure”, which are generally low-level companies silently contributing to how the Internet runs. These infrastructure companies will be relevant later.

    Tall Poppy boasts its customer list,11 which includes large companies like Spotify, viciously litigious associations like the Science Fiction & Fantasy Writers of America (SFWA), NGOs like the Global Disinformation Index, and Amazon’s extremely influential streaming platform Twitch.

    They have received glowing endorsements from Ellen Pao, former CEO of Reddit, Anita Sarkeesian of GamerGate fame, Katherine Maher, former CEO of Wikimedia, and Liz Lee, who has been involved with Twitter and Morgan Stanley (one of the most powerful wealth management organizations in the United States).

    Ellen Pao was an interim CEO for Reddit in 2015. She was the head of the company when it decided to ban r/FatPeopleHate. Reddit traditionally had a policy of tolerating free speech, even when upsetting. It may be hard to believe, considering the state of Reddit today, but this was a very unpopular decision. Ellen Pao was even forced to couch these reforms in language like: “we’re banning behavior, not ideas”.

    There were many changes she made, all unpopular. Her stay at Reddit was very brief. She was removed and Reddit apologized, saying they would make things right. This never happened.12 It was clear that Pao was hired to make sweeping changes, setting the stage for the new Reddit moving forward, then step aside during the outrage so that she would take the fall. Not a single policy Ellen Pao implemented was ever reversed by Reddit’s corporate, and they have since been compounded and expanded upon.

    Ellen Pao married an openly gay black man, but has been going through an incredibly scandalous divorce since 2019. Details on this divorce are hard to come by online. It raises questions as to what exactly Ellen Pao has been paying for.

    Katherine Maher is a former Wikimedia CEO and current CEO of NPR.13 She is an avid ideologue whose reputation is so incredibly poisonous that her position on the Signal Foundation has raised serious concerns if the beloved privacy app Signal is fundamentally compromised.14

    This direct connection helps explain how Liz Fong-Jones is able to generate significant positive press for himself, and is permitted to craft narratives on Wikipedia articles he is directly affected by and has incredible conflicts of interests with, including for his company Honeycomb and for the Kiwi Farms. His contributions are made by suggestion only (via the “Talk Pages”),15 but since he is direct friends with Wikipedia admins who manage these pages, they are always included in as favorable a light to him as possible.

    Wikipedia is supposed to be a “free and open” platform for cataloguing the knowledge of mankind. Katherine states here that this is no longer useful, and that “free and open” perpetuates a “White, male, Westernized construct” and is exclusionary to communities “without written tradition”. “These ideas of radical openness … did not live up to the intention”.

    Wikipedia is by no measure a free and open platform. You are only permitted to edit Wikipedia using specific IP addresses, meaning anyone concerned about their privacy may not edit Wikipedia. Since Wikipedia admins and Wikimedia C-Level executives may be friends with people trying to ruin your life, this necessitates de-anonymizing yourself to hostile actors to even create an account.

    Then, you will discover that almost every important Wikipedia page is under special protections, especially controversial pages like the Kiwi Farms, living people such as Liz Fong-Jones, and his companies like Honeycomb. You will need a certain level of reputation within the Wikipedia community to even attempt editing these pages. Protected and high-risk pages like the Kiwi Farms’s are watched for changes by hundreds of bureaucrats continuously. Your edits will be critically scrutinized, whereas the edits of Liz Fong-Jones and his personal Wikipedia admin friends will pass with rubber stamps.

    One major reason your edits may be reverted is for “original research”. Original research is anything extrapolated from a primary resource. This includes government websites and the Kiwi Farms itself, if you’re writing about the Kiwi Farms.

    What Wikipedia likes is secondary resources from trusted publications. Trusted publications are explicitly whitelisted news media websites.16 Kiwi Farms users in 2022 asked Wikipedia to start being impartial on the subject and stop trusting biased news articles. This prompted 10-year Wikipedia veteran editor Bilorv to state, “If Wikipedia had existed when expert consensus was that the Earth is flat then we would have asserted that position as fact”.17 The men who burned Giordano Bruno at the stake for discrediting geocentrism now write for Wikipedia. At least Bruno’s executioners got paid; Bilorv’s 38,828 edits were made to Wikipedia for free purely for the self-satisfaction and ego.

    So, in practice, Maher’s revolutionary “not free, and not open” Wikipedia means that any wealthy technocrat may buy fluff pieces from legacy news websites, and can request these articles be added to Wikipedia articles by their admin friends, specifically to accomplish political goals.

    Incidentally, the Wikipedia article for the Kiwi Farms is nothing but sloppy accusations citing articles which contain no evidence themselves. Whatever the news writes becomes the truth, and the news writes what Liz Fong-Jones tells them to write. He is often directly contributing to the news articles, or is the subject of favorable interviews with these publications, which he then personally passes through to Wikipedia admins to complement and grow articles in the direction he pleases.

    Wikipedia’s true power comes in its presence on search engines. It is almost always the first result of any search, its contents are fed into the infobox summaries found on search results, and its data is accepted uncritically by AI chatbots. If I ask Google Gemini to describe the Kiwi Farms in a sentence, it tells me “a controversial web forum known for its users' online harassment and stalking campaigns against various individuals and communities”, despite the Kiwi Farms having explicit and enforced rules against contacting people off-site (i.e. harassment). To the average person, Wikipedia is the truth, and whatever is written on Wikipedia is what will be believed.

    Liz Fong-Jones’s reputation management looks like this:

    1. Crafts a media narrative with contacts in the press.

    2. Cements this narrative as publicly held truth using his Wikipedia contacts.

    3. Sends links to these articles directly to ISPs himself as proof of abuse.

    4. Remove from search results, or the Internet completely, any upsetting pages.

    In this way, he can “prove” criminal behavior through a line of “reputable sources”, despite no actual evidence for criminal behavior, because no criminal behavior exists.

    This works both to harm websites like mine, and to his benefit in crafting his and his company’s reputation to his liking. It works especially well because he’s very low-profile and not known outside of his fields, where there is no political crossfire to hold Wikipedia accountable. Instead, the only voice identifying this behavior is the Kiwi Farms, which has already been thoroughly maligned.

    This email from Blake Willis of Zayo Paris exemplifies the trust in Wikipedia and the power of Liz Fong-Jones’s connections within the industry. I must stress that the decision to terminate Internet service at the level suggested in this email exchange is unheard of. This is the equivalent of the power company cutting off an abortion clinic or coal mine because they are too controversial. A mere ten years ago, a decision like this would have been completely unthinkable.

    There is a sentiment I want to overcome: that the Kiwi Farms—as only a moderate sized, niche community that is often times mean-spirited—does not effectively act as a canary in the coal mine for the broader Internet. I will demonstrate that the lessons being learned from this meddling are testing a broader strategy applicable to all.

    In 2022, after disgraced fraudster Clara “Keffals” Sorrenti would falsely claim the Kiwi Farms had orchestrated a swatting of his domicile in Canada, Liz Fong-Jones would lend his talents to try and finally destroy the Kiwi Farms. This included Liz Fong-Jones appearing in person at Syndey to protest Cloudflare, which provided security services to us.18 The idea was that by getting our security service to abandon us, we would be opened up to illegal cybersecurity attacks that would bring us down. It worked, and very powerful people took notice.19

    Liz Fong-Jones hoped to achieve total censorship of a community made of tens of thousands of users. His efforts, and his achievements, are now being used as a proof-of-concept for academic research. If Liz Fong-Jones succeeds, the model he is constructing will be applied to easier targets than the Kiwi Farms. I also stress that the Kiwi Farms has been unusually flexible and able to resist deplatforming, in no small part because I as an individual am very unusual. Most people would have the good sense to quit and abandon their projects well before it gets to the point it has with the Kiwi Farms. This is doubly true for websites which must operate cash positive as a successful business, whereas the Kiwi Farms lives off cryptocurrency donations, a privilege unique to dedicated communities with very tech-savvy users.

    Liz Fong-Jones personally gave a presentation at Cambridge, concisely detailing his own efforts to deplatform the Kiwi Farms at every conceivable technical level.20 Shockingly, the most effective targets were the most important to the broader Internet, such as T1 Internet backbone company Cogent, based out of D.C., who to this day will block any of their own customers who allow the Kiwi Farms to use them.

    I think even Liz Fong-Jones was surprised at how quickly the Internet backbones began censoring at his request, because it took months for him to even try. Once he realized they would do what he asked, it became his go-to strategy. Why bother with the small, conscientious companies at the bottom when you can threaten to kneecap their entire business out the gate with top-down censorship?

    The following Cambridge academic paper was released, which directly follows the deplatforming efforts made against the Kiwi Farms. Interestingly, it also follows the impact on user numbers and post participation in the community using publicly available data. It accurately details how post rates slowed due to low availability. For instance, while we almost always were available on Tor, many users chose not to download special browsers to continue accessing the forum. Cambridge sees that as a win.21

    This figure is extrapolated over a very nice timeline figure that outlines precisely the long-lasting, enduring attacks made at every level of infrastructure, including illegal attacks aimed at putting the site offline by directly compromising our software.

    The Kiwi Farms is so central to these researchers and their work, they have appeared on a cybercrime podcast Hackting Out to discuss the Kiwi Farms (albeit indirectly). 22

    They have also delivered this report to the Institute of Electrical and Electronics Engineers (IEEE) just this year.23

    The IEEE is an incredibly important organization whose members decide international standards for technological development. It works together with, and has significant membership crossover with, the Internet Engineering Task Force (IETF). These groups publish RFCs proposing changes to how the Internet works.

    Liz Fong-Jones and his friends in academia would hope to persuade the IEEE and IETF make the entire world smaller, more centrally organized, more brittle, and easier to break apart. These changes could be implemented at a technical level so innate to how the Internet works, that it would be almost impossible to explain to a layman what has even happened.

    The Cambridge study is oriented to persuade important engineers that they must break the Internet so that mean websites can effectively be removed everywhere, and these studies are being made off where Liz Fong-Jones is currently failing to bring down the Kiwi Farms. Their political pressures conflict with the First Amendment, as we do nothing illegal. Now, they apply pressure inside academics, corporations, and trade organizations to instead circumvent our rights.

    "If all else fails, litigate" citing an article from The Guardian.
    A slide from Liz Fong-Jones’s presentation at Cambridge.

    Liz Fong-Jones sued Vincent Zhen, the owner of Flow Chemical Pty Ltd, in Australia for AU$400,000 for defamation.24 To demonstrate how insane this is, I will chart the distance between Vincent and the posts which Liz Fong-Jones alleges defame him.

    1. Vincent, an Australian, owns Flow Chemical, an Australian company.

    2. Flow Chemical has IP addresses through APNIC, an Australian non-profit.

    3. Flow Chemical leases some IP addresses to 1776 Solutions, LLC in Wyoming.

    4. I, a Floridian, own 1776 Solutions, LLC.

    5. 1776 Solutions, LLC has provided service to my other company, Lolcow LLC.

    6. Lolcow LLC (West Virginia) owns the Kiwi Farms’s assets and licenses for posts.

    7. Users of the Kiwi Farms, who are mostly American, made posts about LFJ.

    8. LFJ alleges these posts are both untrue and defamatory.

    Therefore, the courts believe Vincent personally owes half a million dollars.

    I know Vinny and speak to him maybe four times a year on average. We live on different continents in completely different timezones and it is hard to maintain a friendship over that sort of distance. As a result, Vincent knows almost nothing about the Kiwi Farms or what I do, and has no say in how I use the IP addresses I pay for.

    In affidavits supplied to Australian court, Liz Fong-Jones has promised under penalty of perjury that these IP addresses are critical to the Kiwi Farms’s operations, uptime, and (most importantly) ability to deliver mean posts about him to the world-wide Internet.

    We have not used these IP addresses in a year, and only used them publicly for less than a year. How critical these IP addresses are can be easily determined by the fact that the Kiwi Farms remains available to the world-wide Internet, and that we do not use any Flow Chemical IP addresses in doing so. It would be accurate to say that we enjoy more uptime without using Vinny’s IP addresses, due to very technical reasons that Liz Fong-Jones has learned to exploit — broadly, how to complain to ISPs and get entire networks removed from the Internet.

    Vinny is very stubborn. He trusted the Government to recognize the flagrantly spurious and fallacious nature of these accusations and dismiss them on its own, sua sponte. He also is a busy person who has better things to do with his time and money than be sued by a lunatic. I continually advised him against inaction, perhaps once a month every month, until he was guilty by default.

    He is working on the slow and expensive process of overturning the default.

    The real victory of this judgment is that Liz Fong-Jones can now pretend it says the Kiwi Farms is illegal and/or creates civil liability for its hosts. Indeed, it has appeared in numerous articles published by the usual suspects who tend to polish Liz Fong-Jones, and these articles have somehow found their way to the Kiwi Farms’s Wikipedia page, despite zero direct involvement between Kiwi Farms and Flow Chemical or Vincent.

    Liz Fong-Jones is nothing if not incredibly spiteful. The money and resources he has acquired are merely tokens for him to purchase human misery.

    Last month, Sony released a video game called Stellar Blade to the PS5, which had featured a protagonist in very revealing clothing, which the developers had promised would not be modified when released to the West. Sony did end up tailoring her outfits to be less revealing, and this decision prompted outrage. A petition to undo this cosmetic defect accrued 84,000 signatures in two weeks.25

    Stellar Blade’s petition is the largest outcry against censorship in recent memory, and it has so far failed to get Sony’s decision reversed. This failure highlights to me what I believe should be obvious: public outcry and petitions do not get things done. Money does. Whatever monied power convinced Sony to make these changes outweighs the perceived economic threat of gamers promising not to buy their game.

    The anti-censors rallied around this cause en masse, no doubt thanks to how easy it is to complain on social media and sign a petition. Meanwhile, there is a vine of thorns wrapping around the esophagus of the Internet. Our ability to even communicate is at risk of being destroyed, and the people who intend to destroy them have networked an obscene amount of wealth and power without being noticed. Indeed, the monied powers actively working to destroy the Internet find themselves intertwined with supposedly anti-censorship entities without trouble.

    For instance, the closest thing to institutional power online for anti-censorship is Rumble, which has recently started a cloud service that consists of a single datacenter, a single ISP (Cogent), and a single security service (Path).

    Rumble highlights, in particular, the anti-censor’s total and complete inability to learn lessons from other anti-censors. I have personally attempted to communicate to Rumble by email, to CEO Chris Pavlovski, and to Head of Product Rick Racela the imminent and urgent danger that relying solely on Cogent and Path presents to their companies, and all of their customers.

    Cogent has taken unprecedented, deranged steps to stop the Kiwi Farms from being able to operate, including threatening to disconnect entire datacenters in Poland for allowing us to continue to host there. The decisions to prohibit the Kiwi Farms and my company 1776 Solutions from operating on Cogent networks come from the very top. Two separate sales representatives from Cogent have confirmed to me that a C-level decision was made to stop me from acquiring a hookup with them. I have attempted to call in on Cogent investor meetings during public Q&A and was screened out of the caller pool.

    I stress that, even a few years ago, a T1 ISP making waves to try and censor online content would have been international news, a terrible blow to their reputation within the industry, and no company would possibly trust them with supplying transit.

    Path’s CTO is Corey Barnhill (now August Heart), a pedophile. Corey is on record admitting to watching a 9-year-old girl be sodomized.26 His company, Path, has attempted to illegally seize my hard drives by sending fake Canadian court orders to my datacenters. Path proudly advertises they were the first ISP to disconnect the Kiwi Farms at an ISP level, and boasted about this directly to Liz Fong-Jones.

    Despite this, Rumble still uses them. What’s worse, Rumble’s video site apparently uses Path for application level mitigation as well, which means Path (a mismanaged, near-bankrupt “security” company currently being evicted from datacenters for missing months of payments27) is probably the SSL endpoint for Rumble. If true, it means Path & Corey Barnhill can intercept and read all communications to Rumble’s website. I have warned them about this for months!28

    At a very basic and fundamental level, the key players in anti-censorship are fractured and isolated from one another. They do not have cohesive goals and frequently allow irrelevant personal issues divide them. At best, their efforts are split and duplicated, and at worst, they are openly hostile to one another.

    No such issues exist in the pro-censorship crowd. Drowned in capital from megacorporations, which they share between friends like bottles of wine, they plot a web of academic journals, media publications, and presentations at important international organizations to achieve their goals. They live in penthouse suites outside of San Francisco callously deciding which small, atomized, defenseless component of anti-censorship they will tie up in litigation and defame next.

    There is no equivalent for anti-censorship. No one stands at the IEEE or IETF and discusses how the Internet is about to collapse into dystopia. The few who do merely cheer it on. Anti-censorship does not network and ignores the lessons already learned. They are too afraid of what will said about them in the media, when the media is already a demonstrably poisoned network of people who can’t wait to strangle the life out of them.

    The most important anti-censorship organization was the Electronic Frontier Foundation (EFF). The one time the EFF tried to write in defense of the Kiwi Farms, they had to anonymize their authors because the two women who wrote it were threatened by a transgender mob.29 To this day, the EFF will take the side of the mob who threatens them and hates them, over any organization in genuine need of defense which may lack a favorable Wikipedia article.

    At the time the Kiwi Farms deplatforming was starting to show cracks in the Internet backbones, the EFF even launched a petititon website called “Protect the Stack”, dedicated to trying to preserve the neutrality of the Internet.30 They have never contacted the Kiwi Farms directly to learn about where the stack is in danger, and as a result they have accomplished nothing! Despite the size, prestige, and financial support of the EFF, Protect the Stack has accomplished nothing!

    It is no wonder, when they are staffed with the likes of Cooper Quinton, a senior security researcher with the EFF31 whose hobbies include wishing death on users of a website who have openly supported the EFF for years.32 Quinton is proof-of-concept that anti-censorship wastes its breath trying to involve itself with the existing, rotting structures of the past’s anti-censorship. Those organizations are subverted and only new ones with renewed purpose can work.

    "I wish everyone involved with kiwi farms a very merry getting hit by a bus."

    I would like to end this article with a call to action. “Here is the problem, here is the solution.” While I would generally encourage intelligent cooperation between Anti-Censorship movements, I have no hope for that. Anti-censorship is inherently individualistic, as those types benefit from freedom the most.

    Some cohesion is necessary. The anti-censorship crowd is mostly preoccupied with lining their own pockets. Every anti-censorship startup seems hellbent on being the first person to “solve” the censorship issue, without any cooperation from others, so that they may take in all the “glory”. There is no conservative think-tank doing what the pro-censorship camps do every day: combining intelligence, power, and money. Instead, we each run our own race, and make less progress overall, falling further behind in our endeavors every day, winning only superficial victories with video games and in local jurisdictions, while pro-censorship wins on the big stage and behind the curtains of the international organizations who actually make decisions.

    There will be no participation trophies at the gallows.

    For those with resources, I emphasize that confederation is required to survive the next decade. There are companies making up the Internet which are toxic and needing to be scraped out, and companies which are principled and needing to be built up. The good is out there, and good people are trying, but they don’t get the attention they need. A serious person with serious aspirations could start a pro-free speech trade organization or coalition, but it needs to be done in earnest and with resources out the gate, and it cannot exclude members and what they would bring to the table simply by the negativity of their Wikipedia article.

    For the average person, instead of asking you to do a specific thing, I ask you to consider something: Every day, Liz Fong-Jones wakes up and dedicates the whole of his existence to making the world a worse place. He decides how he is going to enrich himself, who he is going to exploit, where he’s going to invest his wealth and grow his personal power, and how he’s going to expand his network of nepotistic friends.

    What are you doing? Are you spending your days productively? Are you putting effort into growing your own wealth and improving your own standing? Are you waking up each day to a personal situation that is better than yesterday’s?

    Anti-censorship, in general, appears most sensitive to pop culture changes, like media localization, video game outfits, and movie race swaps. I fear this may be because anti-censorship has become complacent and defeatist. It appears to many that perhaps the only achievable victories are keeping a movie remake’s character White. I think many are spending their time absorbed in media because our real situation seems so dire. The plane is crashing and everyone just wants a nice in-flight movie.

    I ask that everyone makes their every day more productive than Liz Fong-Jones and his friends have made theirs.

    History of the Italian Electrical System

    Hacker News
    samuele963.github.io
    2024-05-16 20:39:08
    Comments...
    Original Article

    The Italian electrical system has a fairly complicated history; from different voltages and frequencies to the type of plugs used, almost everything about it has changed over the last century, or is in the process of changing.

    While nowadays it's well known that North America uses 120V and Europe (as well as most other places) use 230V, this wasn't the case - for decades parts of Europe, such as Italy, also used 120V, either entirely or only for certain applications, and switched voltages later on.

    This page documents this history, specifically regarding the situation in Italy, and the various changes that happened over time as the electrical system evolved.

    The beginning

    As with most countries, electrical supplies in the early days of electrification were divided between different regions and even across cities, as grids were owned by many small regional power companies; thus, voltages and frequencies (42Hz was quite common) could vary a lot between each other.

    This is made quite evident on this list, taken from the Italian Wikipedia page about electrical distribution, which shows the various voltages in use in major urban centres in Italy back in the day. Note that some cities are listed twice - this was because of multiple companies operating in the same cities, each with their own type of supply.

    A list of the various line voltages in use in the major towns and cities Italy before their unification. The voltages can vary quite widely, for example Terni is listed as using 120/210V, whereas Frosinone used 150/260V. Additionally, some towns are listed twice, as they were served by two different power companies.

    Later on the smaller companies were acquired by larger ones, and in the 60s a national electric company - ENEL - was formed. Part of their goal was to unify the various supplies, and move to a unified standard. However, one thing remained for a few more decades...

    The dual tariff system

    During this time, electricity was mainly used for lighting, and later on also simple devices such as fans and radios. If you wanted to use any appliances you had to pay for a higher rate of electricity, which was metered and taxed differently - the idea was, that if you were rich enough to own, for example, a washing machine (which was very expensive at the time), you definitely had enough money to pay for the appliances supply.

    To prevent people from using the cheaper lighting supply for appliances, this was powered at a different voltage - for example, 120 or 150V - and often was also limited to only a few kilowatts. Appliances, on the other hand, used a higher voltage, generally 220V (though 260V was also a thing), which also helped with efficiency.

    A voltage selector switch, found on an old tube radio. Taps for many different voltages are present. As a result of this, some electrical devices made back then aren't usable now without a transformer to step down the voltage - this is quite common on smaller tube radios and fans which were meant to be used with the lighting supply. Other devices, instead, had voltage selector taps on the back - some of these were for 120/150V-only, but often these also included an option for 220V (for tube radios, this was generally the case for ones with a built-in transformer), which makes it possible to use them even today.

    How these supplies worked

    The way this worked was quite simple: 127/220V three-phase transformers were common, which provided 120V between one of the phases and neutral, for the lighting supplies, and 220V between phases for the appliances supply. So, if you only needed to power lights, you received a single phase and a neutral, while if you also had an appliances supply you had two phases (or three phases for industrial applications) and a neutral, and two separate power meters.

    This arrangement is somewhat similar to the electrical supplies used in North America nowadays, where 120V is used for most appliances and 240 or 208V is used for heavy appliances, though one major difference is that split phase was very uncommon here.

    Two types of plug

    An overview of the two different sized of Type L plug. Because of these dual supplies, and the two voltages they used, two different types of plug became common, and are nowadays both known as type L: a "small" 10A one meant for the lighting supply, and thus generally used for 120V, and a "big" 16A one meant for appliances, and thus generally used for 220V.

    "Big" sockets were incompatible with "small" plugs and viceversa, a useful feature to prevent breaking your precious electrical appliances.

    Moving to 220V

    Over time, as electricity became common, more and more people bought electrical appliances and thus most houses had two power meters and both 120 and 220V sockets in their home. As time moved on, 220V became used for more and more things, and people began wiring up 10A socket for use on 220V (which lead to some interesting results when a 120V devices was plugged to a 220V socket); as such, the whole structure of "small" sockets being for 120V and "big" ones being for 220V slowly began to fall.

    Additionally, even lighting supplies began getting migrated to 220V - at that point lighting was mostly the only thing a house would have used 120V for - but, even after the migration, dual metering continued to exist for a while longer. Even by the mid-70s 120V supplies were still in use, necessitating two meters, and houses with 220V only could either have one or two meters.

    A picture of a Bipasso socket, which accepts both 10A and 16A plugs. The line and neutral holes are shaped specifically to be able to accomodate both. Because of these dual supplies, and the two voltages they used, two different types of plug became common, and are During this time adaptors to go between the two different types of socket became common, and the purposeful lack of intercompatibility between the two went from a useful feature to a growing problem, especially as single-meter 220V supplies became more common.

    On these installations, 10A sockets were often also used on the same exact circuits as 16A ones, making the separation even more pointless. A solution to this came in the form of the Bipasso sockets, 16A sockets which also accepted 10A plugs. These became more common for new installations, starting in the 70s-80s, solving the compatibility problem.

    The legacy

    Nowadays 120V supplies are no longer a thing - the last one was shut down in Lazio in 1999, thus marking the end of that era, though by then they had become extremely rare already. However, certain elements of that legacy still remain: the most notable part is the use of the two type L plugs, as well as Schuko ones.

    Additionally, some areas still use the old 127/220V transformers; houses in these areas receive two phases, both live at 127V with respect to earth. Special care must be taken in buildings fed by those transformers, to make sure proper double-pole (2P) breakers are used, to avoid things remaining live accidentally.

    Unfortunately, some electric car chargers don't like this sort of supply, and will outright refuse to work on it. This is apparently a somewhat common problem in parts of Rome, where not all "dual phase" transformers have been replaced yet. Thankfully, in general, these supplies are quite uncommon in Italy, and will get rarer and rarer as remaining ones get phased out as transformers get upgraded.

    Show HN: We built the fastest Android dev ecosystem

    Hacker News
    dashwave.io
    2024-05-16 20:38:45
    Comments...
    Original Article

    New Feature: Custom Workflows

    Cloud based android dev tool for

    Fast pre-cached builds with one click pre-built dev environments for rapid, collaborative and productive android development

    Accelerated Builds on Cloud

    Pre-cached cloud build environments with state of the art caching to support rapid build generation anywhere in dev pipeline

    Supports build on Java/Kotlin, ReactNative and Flutter

    time saved per developer per wk

    trusted developers globally

    Breathtakingly fast ⚡️

    Enhanced build speed upto 20x

    Pre-cached build environments

    Enterprise grade distributed, dependency and configuration caching

    Pluggable Interface

    Build anywhere, locally or CI. Setup in 5 mins 🕠

    See more features ->

    Github PR Checks️

    Automated builds on code push/pull

    Flexible Configurations

    Setup multiple triggers on varied build configurations

    Rich Analytics

    Get daily ROI stats on builds

    See more features ->

    Build on Dashwave

    Emulate and share as a link

    Comment and collaborate

    Save time on looooooooong delayed feedback loops

    upto 2 hours daily
    savings on delayed feedbacks

    Learn more ->

    At the heart of Developer Experience

    designed to address productivity bottlenecks for android developers

    to support rapid and collaborative development

    Ready to Integrate - Setup in 5 minutes!

    Integrated seamlessly with

    To create local builds on cloud download our Jetbrains plugin

    Dashwave

    Dashwave Cloud Build

    This plugin provides direct access to Dashwave's cloud build engines

    security

    Cloud Secure

    Your Data Security, Our Top Priority

    Dashwave cloud uses best in class security principles to ensure that your data is shielded. Enterprise users can benefit from self-hosted secure installation of Dashwave in their own cloud or on-prem.

    Data Encryption in Transit and Rest

    Industry-standard encryption protocols to protect our users' data in transit and rest

    Access Control

    Enable selective and authorised access to code, builds and emulation

    Regular Backups

    Regular backups and recovery on demand for data

    rocket

    Supercharge your development with Dashwave

    JEP Draft: Support HTTP/3 in the HttpClient

    Hacker News
    openjdk.org
    2024-05-16 20:35:21
    Comments...
    Original Article

    Summary

    Update the HTTP Client to support the HTTP/3 protocol.

    Goals

    • Update the implementation of the HttpClient to send and receive HTTP/3 requests and responses.
    • Require only minor changes to the HttpClient API and to application code.

    Non Goals

    • It is not a goal to change the default version from HTTP/2 to HTTP/3: use of HTTP/3 is an opt-in (see risk and assumptions below).
    • It is not a goal to provide an API for the underlying QUIC protocol on which HTTP/3 is based.
    • It is not a goal to provide an API for the Transport Layer Security (TLS) implementation changes that might be required to implement QUIC-TLS
    • It is not a goal to provide a server-side implementation of the HTTP/3 protocol, though one may be developed for testing purposes

    Motivation

    A modern HTTP Client was added to the Java Platform in Java 11 via JEP 321. The Client API is protocol agnostic and currently supports versions HTTP/1.1 and HTTP/2 of the HTTP protocol. It is designed to support future HTTP protocol versions with minimal API changes.

    Here is an example using the HTTP Client, which sends a GET request to https://openjdk.org/ and receives the response as a string:

    var httpClient = ... // e.g. HttpClient.newBuilder().proxy(...).build();
    var request = HttpRequest.newBuilder(URI.create("https://openjdk.org/")).GET().build();
    var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
    assert response.statusCode() == 200;
    String htmlText = response.body();

    In this example there is nothing explicit in the use of the API that depends on the HTTP protocol version. The application code is agnostic to the protocol.

    In 2022, a new version of the HTTP protocol, HTTP/3, was standardized by the Internet Engineering Task Force (IETF). HTTP/3 is an evolution of HTTP/2 based on QUIC (pronounced "quick"), a new transport protocol over the User Datagram Protocol (UDP). Unlike previous versions of HTTP, HTTP/3 doesn't use TCP/IP. The QUIC protocol provides a reliable transport layer, using TLS 1.3 encryption at the transport level.

    Supporting HTTP/3 will enable HTTP Client applications to benefit from the many improvements offered by the new protocol, such as:

    • potentially faster handshakes;
    • removal of head-of-line blocking issues; and
    • more reliable transport, especially in those environments with poor internet connections causing packet loss.

    HTTP/3 and QUIC are already widely adopted by major companies, supported by many browser implementations, and developers are expected to demand support in the Java Platform.

    Description

    The Http Client API will remain backwards compatible with only minor enhancements to support HTTP/3. Specifically, only one area of API change is absolutely required, that to override the default protocol version and explicitly request that HTTP/3 be used.

    To send a request using HTTP/3, a user of the API must opt in to HTTP/3 by setting the default version of their HttpClient to HTTP/3 or by explicitly setting the version of the HttpRequest to HTTP/3. If the target server doesn't support HTTP/3 the request may be transparently downgraded to HTTP/2 (or HTTP/1.1). In the example shown above, enabling HTTP/3 would simply require selecting HTTP/3 using the new addition to the API. For instance:

    Selecting HTTP_3 either as default version for the client:

    var httpClient = HttpClient.newBuilder()
                               .version(HttpClient.Version.HTTP_3)
                               .proxy(...).build();

    Or as explicit version for the request:

    var request = HttpRequest.newBuilder(URI.create("https://openjdk.org"))
                             .version(HttpClient.Version.HTTP_3)
                             .GET().build();

    Nothing else needs changing.

    The following API enhancements might also be considered:

    • limited configuration for tuning the HTTP/3 implementation, for instance by means of JDK-specific system properties, or possibly by small API changes.
    • specific subclasses of IOException or SSLException may need to be introduced for detailing HTTP/3 specific errors.
    • enhancements to the PushPromiseHandler interface to support the HTTP/3 capability of sharing promise responses between different request/response streams opened on the same connection.
    • optional configuration options added to the HttpClient.Builder or HttpRequest.Builder for tuning discovery of the target QUIC endpoint.

    Testing

    New tests for HTTP/3 will be developed. Existing tests for the HttpClient, that do not depend on a specific version of the protocol and which already use data providers to test the HttpClient functionality through HTTP/1.1 and HTTP/2, will be extended to test the same functionality through HTTP/3. One time interoperability testing might be performed against existing known HTTP/3 servers.

    Risks and Assumptions

    The effort to come up with a finished implementation is estimated as large. While the additional API surface is not expected to be significant, the volume of specification material that constitutes the substantive QUIC protocol is rather large. The majority of effort is expected to reside within implementing the QUIC protocol itself. Providing a public API for the QUIC protocol is however not a goal of this JEP.

    This first implementation of HTTP/3 will not support working with other security providers than the default SunJSSE provider. Working with 3rd party JSSE providers would require adding/modifying the current JSSE Provider SPI, and would require third party providers to implement those methods. This might be the object of another future JEP.

    A new HTTP_3 constant is added to the HttpClient.Version enum. This could cause an IncompatibleClassChangeError if the new constant reaches a switch statement compiled before the addition of the constant, when the switch statement has no default clause. For compatibility reasons, it seems therefore more prudent to require HTTP_3 to be an opt-in: a caller that opts in for HTTP_3 should be prepared to receive responses that contain an HTTP_3 version. A caller that didn't opt-in, such as a caller that was coded before the introduction of the new constant, might not expect it.

    In addition, HTTP/3 doesn't define any upgrade mechanism. To figure out whether a server supports HTTP/3, a client would have to either send the first request through HTTP/1.1 or HTTP/2 and hope to receive an alternate service header or frame, or attempt to initiate a QUIC handshake at the given URL. Because QUIC is based on UDP, determining that QUIC is not supported by the peer can only be achieved by waiting for a response until a timeout expires. Making HTTP_3 the default version would therefore cause a cost to be incurred by each request sent to a new server.

    This policy could be revisited in years to come, if adoption of HTTP/3 becomes more widespread.

    The HTTP/3 and QUIC specification are significantly large and make allowance for what client and server endpoints MUST or MAY implement. The initial implementation of this JEP may only implement a minimal subset of the specifications.

    Dependencies

    The QUIC Protocol is defined by the following RFCs:

    • RFC 8999: Version-Independent Properties of QUIC
    • RFC 9000: A UDP-Based Multiplexed and Secure Transport
    • RFC 9001: Using TLS to Secure QUIC
    • RFC 9002: QUIC Loss Detection and Congestion Control

    The HTTP/3 protocol is defined by the following RFCs:

    In addition, the following RFCs are of interest for discovering QUIC endpoints and measuring path MTU:

    • RFC 7838: HTTP Alternative Services
    • RFC 8899: Packetization Layer Path MTU Discovery for Datagram Transports
    • RFC 4821: Packetization Layer Path MTU Discovery

    Some other RFCs are also of interest but may not be supported by the first implementation:

    Exit Strategy: The Case for Single-Stair Egress

    Hacker News
    www.architecturalrecord.com
    2024-05-16 20:29:18
    Comments...
    Original Article

    Image in modal.

    American land-use reformers intent on addressing present-day housing shortages have, for the last decade, focused their efforts on amending zoning codes—the very rules that gradually downzoned most urban land in the U.S., effectively outlawing multifamily housing, spurring suburban sprawl, and fanning the current crisis. Recently, however, a group of young architects and planners has brought attention to another code barrier that limits design options for large multifamily buildings: the multiple egress routes mandated by most American building codes. The argument, in short, is to re-legalize single-stair apartment buildings, also known as “point-access blocks”—a typology that was once commonplace and remains so in much of the world, including the European Union, where fireproof single-stair designs are allowed. If combined with zoning reform, such code reform would enable attractive, light-filled multifamily housing to be built cost-effectively on countless urban sites that would otherwise be developed as single-family homes.

    Commentators often wonder why new apartment buildings across the United States tend to look alike, not-so-subtly implicating architects and developers. One key reason is that decisions around organization and massing are prescribed by, or strongly incentivized by, regulations. In the limited areas where zoning codes allow for apartments, these rules have given us the notorious “five over one.” In code lingo, these are a Type V light wood frame of up to five stories built over a single story of Type I fireproof podium (typically steel or concrete), with a double-loaded corridor and a stair at each end. Long, windowless corridors slice through the middle of deep floor plates. Non-corner units only have windows on one side, opposite the entry door—favoring studios and one-bedroom layouts.

    By contrast, single-stair buildings across Europe tend to have shallower floor plates, “floor-through” light on at least two sides of each unit, and a shared central courtyard. Older American cities also feature outstanding examples of these “garden apartments”: New York’s first garden-apartment blocks, in Jackson Heights, Queens, were celebrated in Architectural Record in 1920 for their array of unit layouts and variety of outdoor spaces. Indeed, single-stair designs deliver more of the light, air, and acoustic privacy typically provided by detached single-family buildings. Light on two or three sides facilitates multibedroom suites even in compact floor plates. These buildings also facilitate community building. In Jackson Heights, for example, whole-block developments are composed of many buildings in series, each governed by its own co-op board, and each, with 20 or so units arranged around a single stair, is small enough for residents to get to know each other. (New York and Seattle are the only two American cities that continued to allow single-stair buildings throughout the 20th century.)

    Operation Number 8.

    1

    Operation Number 8.

    2

    Andrew J. Thomas, the prolific housing architect, was lauded in the August 1920 issue of RECORD for Operation No. 8, a series of apartment buildings in Queens, New York (1, 2,). Images © Architectural Record

    Single-stair designs also unlock economically feasible multifamily development on small infill lots. On such sites, two interior stairwells and a corridor would take up so much of the allowable floor plate that multifamily buildings are rendered infeasible unless adjacent lots are acquired. On some large lots, by contrast, the greater floor-plan efficiency of single-stair designs would probably be offset by the higher cost of fireproof construction and the need for a greater number of elevators, as double-loaded corridor designs enable one elevator to serve many units. In these cases, five-over-ones may continue to be built unless construction costs change dramatically. At the same time, developing large lots with multiple single-stair buildings would unlock a unique amenity: park-like shared interior courtyards. If on small lots, single-stair designs compete on both cost and quality, on large lots, they compete on quality.

    Ultimately, building-code reform complements zoning-code reform. A building code allowing single-stair buildings can’t do much if zoning codes still ban multifamily designs in the first place. But allowing multifamily buildings in areas currently zoned for single-family homes may be more palatable to neighbors if they are faced not with the prospect of monolithic, whole-block five-over-ones but rather with narrower, family-friendly buildings. Even at similar height and average density, multiple 20-unit single-stair buildings form more neighborly, less anonymous interior communities than one enormous whole-block apartment building with 100 units sharing a hallway.

    Operation No. 8 Queens.

    Operation No. 8, Queens, New York.
    Photo © Architectural Record

    Why, then, did the U.S. embark upon a path so different from Europe’s? Quite simply, there was a radical divergence in fire-safety approaches during the 20th century and insufficient exchange of best practices. As Stephen Smith, director of the North American Center for Building, argues, American approaches aim to make combustible light wood-frame buildings easier to escape by providing multiple paths of egress; European codes, by contrast, require fire-resistant materials and compartmentation to prevent fires from spreading in the first place. Statistically, the evidence is clear: fire-death rates are consistently lower in Europe than in the U.S. and Canada. Nonetheless, it may be prudent to cap the height of single-stair buildings to ensure egress via fire ladder. This is the approach followed both by New York and Seattle, which cap the height of single-stair buildings at six stories while requiring fire-rated structures and sprinklers.

    What outcomes might we expect from allowing six-story point-access blocks throughout the country? Based on evidence from New York and Seattle, double-loaded corridor designs would probably outcompete point-access-block designs for new buildings only on sites where neighborhood amenities and transit access push up land prices to the point that they support building heights beyond the reach of a fire ladder. But these places are exceptional, not typical. Today, the outlook for reform of both zoning and building codes is brightening. Pro-housing coalitions across the United States have won early battles to re-legalize multifamily housing in states like California, Montana, Oregon, Minnesota, and others. Now building-code reform is gaining steam too. Honolulu quietly re-legalized single-stair apartments in 2012, copying Seattle’s code. Last year, California, Oregon, and Washington each successfully legalized single-stair construction, effective in 2025 or 2026. Half a dozen other states are considering enabling legislation. Reform is on the march.

    104 years ago, this publication celebrated the liberation of New York from dark, airless tenements by new point-access blocks. Today, new adaptations of the same typology continue to win design competitions across the European Union. Single-stair construction commands the support of the Fire Department of New York and the Seattle Fire Department, and state governments across the West Coast have acted accordingly to legalize it. Why not do so across the rest of the United States too?

    Click diagram to enlarge

    Operation Number 8.

    A diagram illustrating the maximum prescriptive height of single-stair buildings.
    Image © Conrad Speckert / www.secondegress.ca

    Alex Armlovich lives in New York and leads the housing-policy team at Niskanen Center, a Washington, D.C.–based think tank.

    Five charged for cyber schemes to benefit North Korea's weapons program

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-16 20:17:13
    ​The U.S. Justice Department charged five individuals today, a U.S. Citizen woman, a Ukrainian man, and three foreign nationals, for their involvement in cyber schemes that generated revenue for North Korea's nuclear weapons program. [...]...
    Original Article

    North Korea

    ​The U.S. Justice Department charged five individuals today, a U.S. Citizen woman, a Ukrainian man, and three foreign nationals, for their involvement in cyber schemes that generated revenue for North Korea's nuclear weapons program.

    They were allegedly involved between October 2020 and October 2023 in a campaign coordinated by the North Korean government "to infiltrate U.S. job markets through fraud in an effort to raise revenue for the North Korean government and its illicit nuclear program."

    Two of them, Christina Marie Chapman and Oleksandr Didenko, were arrested on May 15 in Litchfield Park, Arizona, and in Poland on May 7, 2024, with the DOJ now seeking Didenko's extradition to the United States.

    They were both charged with conspiracy to defraud the United States, aggravated identity theft, and conspiracy to commit money laundering, wire fraud, identity fraud, and bank fraud.

    Three other foreign nationals, known only by their aliases (Jiho Han, Haoran Xu, and Chunji Jin), were also charged with conspiracy to commit money laundering.

    If convicted, Chapman faces a maximum of 97.5 years in prison, while Didenko's maximum penalty can reach 67.5 years. Each of the John Does also faces a maximum penalty of 20 years.

    "Chapman and her co-conspirators committed fraud and stole the identities of American citizens to enable individuals based overseas to pose as domestic, remote IT workers," said Nicole M. Argentieri, the head of the Justice Department's Criminal Division.

    Today, the U.S. State Department announced a reward of up to $5 million for any information related to Chapman's co-conspirators, the North Korean IT workers charged today, and their manager, only known as Zhonghua.

    Reward for information on North Korean IT workers
    Reward for information on North Korean IT workers (State Department)

    North Koreans worked remotely via U.S. laptop farms

    According to the indictment, Chapman housed the North Korean IT workers' computers in her own home, creating a "laptop farm" to make it appear as though her co-conspirators' devices were in the United States.

    They were hired as remote software and application developers with multiple Fortune 500 companies, including an aerospace and defense company, a major television network, a Silicon Valley technology company, and a high-profile company.

    They were paid millions for their work, and Chapman processed their paychecks from U.S. companies through her financial accounts.

    Didenko also ran an online platform known as UpWorkSell (whose domain was seized by the DOJ), knowingly providing services to allow North Koreans to use false identities while hunting for remote IT work positions.

    UpWorkSell seizure banner
    UpWorkSell seizure banner (BleepingComputer)

    "Didenko is alleged to have managed as many as approximately 871 proxy identities, provided proxy accounts for three freelance IT hiring platforms, and provided proxy accounts for three different money service transmitters," the DOJ said.

    "In coordination with co-conspirators, Didenko facilitated the operation of at least three U.S.-based 'laptop farms,' hosting approximately 79 computers. Didenko sent or received $920,000 in U.S.D. payments since July 2018."

    Their scheme compromised over 60 U.S. identities and affected more than 300 U.S. companies. It also resulted in false tax liabilities for more than 35 U.S. citizens and generated at least $6.8 million in revenue for overseas IT workers.

    Today, the FBI also issued an advisory with more information on how North Korea's IT workers undermine the security of companies that hire them and guidance on how to spot North Korean IT worker schemes.

    Previously, the United States also published joint advisories with foreign partners warning of North Korean IT worker schemes and sanctioned multiple organizations involved in North Korea's IT worker revenue generation schemes.

    Taboos and Self-Censorship Among U.S. Psychology Professors

    Hacker News
    journals.sagepub.com
    2024-05-16 20:10:38
    Comments...

    Norway recommends replacing SSL VPN to prevent breaches

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-16 20:07:45
    The Norwegian National Cyber Security Centre (NCSC) recommends replacing SSLVPN/WebVPN solutions with alternatives due to the repeated exploitation of related vulnerabilities in edge network devices to breach corporate networks. [...]...
    Original Article

    World network attacks

    The Norwegian National Cyber Security Centre (NCSC) recommends replacing SSLVPN/WebVPN solutions with alternatives due to the repeated exploitation of related vulnerabilities in edge network devices to breach corporate networks.

    The organization recommends that the transition be completed by 2025, while organizations subject to the 'Safety Act' or those in critical infrastructure should adopt safer alternatives by the end of 2024.

    NCSC's official recommendation for users of Secure Socket Layer Virtual Private Network (SSL VPN/WebVPN) products is to switch to Internet Protocol Security (IPsec) with Internet Key Exchange (IKEv2).

    SSL VPN and WebVPN provide secure remote access to a network over the internet using SSL/TLS protocols, securing the connection between the user's device and the VPN server using an "encryption tunnel."

    IPsec with IKEv2 secures communications by encrypting and authenticating each packet using a set of periodically refreshed ke

    "The severity of the vulnerabilities and the repeated exploitation of this type of vulnerability by actors means that the NCSC recommends replacing solutions for secure remote access that use SSL/TLS with more secure alternatives. NCSC recommends Internet Protocol Security (IPsec) with Internet Key Exchange (IKEv2)," reads the NCSC announcement.

    While the cybersecurity organization admits IPsec with IKEv2 isn't free of flaws, it believes switching to it would significantly reduce the attack surface for secure remote access incidents due to having reduced tolerance for configuration errors compared to SSLVPN.

    The proposed implementation measures include:

    • Reconfiguring existing VPN solutions or replacing them
    • Migrating all users and systems to the new protocol
    • Disabling SSLVPN functionality and blocking incoming TLS traffic
    • Using certificate-based authentication

    Where IPsec connections are not possible, the NCSC suggests using 5G broadband instead.

    Meanwhile, NCSC has also shared interim measures for organizations whose VPN solutions do not offer the IPsec with IKEv2 option and need time to plan and execute the migration.

    These include implementing centralized VPN activity logging, strict geofencing restrictions, and blocking access from VPN providers, Tor exit nodes, and VPS providers.

    Other countries have also recommended using IPsec over other protocols, including the USA and the UK.

    An abundance of exploited SSLVPN flaws

    Unlike IPsec, which is an open standard that most companies follow, SSLVPN does not have a standard, causing network device manufacturers to create their own implementation of the protocol.

    However, this has led to numerous bugs discovered over the years in SSL VPN implementations from Cisco, Fortinet, and SonicWall that hackers actively exploit to breach networks.

    As an example, Fortinet revealed in February that the Chinese Volt Typhoon hacking group exploited two FortiOS SSL VPN flaws to breach organizations, including a Dutch military network.

    In 2023, the Akira and LockBit ransomware operations exploited an SSL VPN zero-day in Cisco ASA routers to breach corporate networks, steal data, and encrypt devices.

    Earlier that year a Fortigate SSL VPN vulnerability was exploited as a zero-day against government, manufacturing, and critical infrastructure.

    NCSC's recommendations come after the organization recently alerted about an advanced threat actor exploiting multiple zero-day vulnerabilities in Cisco ASA VPNs used in critical infrastructure since November 2023.

    Cisco disclosed the particular campaign as 'ArcaneDoor,' attributing it to the threat group tracked as 'UAT4356' or 'STORM-1849,' who gained unauthorized access to WebVPN sessions associated with the device's SSL VPN services.

    The attacks involved the exploitation of two zero-days, namely CVE-2024-20353 and CVE-2024-20359, which enabled the hackers to achieve authentication bypass, device takeover, and privilege elevation to administrative rights.

    Although Cisco fixed the two vulnerabilities on April 24, the cybersecurity and networking equipment firm couldn't identify how the threat actors initially gained access to the device.

    Tidbits – May 16 – Reader Comments: Trump Trial, Arms to Netanyahu, Campus Protests – Impact on Gaza War, Colleges, Society, Elections; Palestine, Gaza, Israel; Haiti; Kenya; Sing in Solidarity; Song Nights for Social Change; Cartoons; More …

    Portside
    portside.org
    2024-05-16 20:01:44
    Tidbits – May 16 – Reader Comments: Trump Trial, Arms to Netanyahu, Campus Protests – Impact on Gaza War, Colleges, Society, Elections; Palestine, Gaza, Israel; Haiti; Kenya; Sing in Solidarity; Song Nights for Social Change; Cartoons; More … jay Thu, 05/16/2024 - 15:01 ...
    Original Article

    .

    Resources:

    .
     

    Announcements:

    .

    Michael Cohen  --  Cartoon by Nick Anderson


     

    Nick Anderson
    May 14, 2024
    Counterpoint

    Re: Netanyahu Ignored Every Warning. Now Biden Is Telling Israel: ‘Enough Is Enough’
     

    Way too little, way too late.

    Ben Cupp
    Posted on Portside's Facebook page

          =====

    I have one criticism: Netanyahu has been asking for a swift kick in the ass for years not weeks or months. He has consistently challenged the U.S. and Joe Biden: announcing the development of new housing in the West Bank while Biden was visiting as Vice President, the notorious speech to Congress at the invitation of the Republicans and invitation Bibi may have solicited and other occasions of thumbing his nose at the U.S.  It might have been beneficial for Israel had the rebuke come much earlier.

    Aside from the proprieties, it is not very clever for a small country to antagonize a great power especially when the small country is dependent upon the large one for critical materiel. Noone thinks an Israeli Prime Minister should bow down before an American President but showing respect for the views of an important ally is common sense something, unfortunately, that  Netanyahu lacks. ..

    Ed

    Putting His Foot Down  --  Cartoon by Adam Zyglis

    Adam Zyglis
    May 9, 2024
    The Buffalo News

    Re: Why I’m Not Calling the Police on My Students’ Encampment
     

    Sac State has a president that created a dialog between groups

    Earl Marty Price
    Posted on Portside's Facebook page

    Pinocchio on Trial  --  Cartoon by Rob Rogers

    Rob Rogers
    May 14, 2024
    robrogers.com

    Re: Will the Palestinian Groups Create a New Palestinian Political Project?
     

    I disagree. As long as there is not a solid agreement and plan by the various Palestinian political groups so as to negotiate with their full power, Israel will continue its military power to continue war against the people of Palestine even with world opinion on the side of them.  Power comes from the central elements not the peripheral support.

    So get it together, Palest together Palestinian Factions.

    Donna Carter

    Re: Palestine and History: Macklemore v. Hillary Clinton
     

    “I have never understood the trope that Israel made generous offers to the Palestinians (it never did) but that the Palestinians rejected them, and therefore the Palestinians should be deprived of all their basic rights forever.”

    Dave Lott
    Posted on Portside's Facebook page

    Re: Who Created the Israel-Palestine Conflict?
     

    Yes, your answer that it was US Immigration laws 100 years ago, hit the nail on the head.

    My parents stepped right off of the pages of "The Tevya Stories" and "the stage and screen of Fiddler on the Roof."

    They came to the US; that was everyone's first choice. Only when new Immigration Laws were passed and the Polish Jews could no longer get into the country, did they "settle" for going to Israel. That's where my parents' siblings went when they could no longer get into the US by changing their names to relatives who were citizens and passing as siblings (my mother) and a little later by creating "mail order brides" (my father's sister). Israel was no-one's first choice. (A Chinese friend told me that her relatives used documentation from dead relatives or bought such documentation).

    To my parents, Israel was someplace that your body would roll to, underground, on "Judgement Day". I guess it was their version of Heaven. I have no idea how much of this they believed or what they invented to explain to the children.

    I never knew the years which of those laws were passed and have only the sketchiest details of the processes they went through to get themselves and their siblings in. But I remember frequent family discussions of whether they would support Israel or the US if they had a war. ALWAYS, first they agreed a war between the two would never happen since they were both democracies but in the hypothetical case of such a war, they would support the US; that was their country.

    Arlene Halfon

    Re: A Simple Fact: There Will Be a Palestinian State. Its Location: Palestine
     

    Why is Israel in the Eurovision song contest in the first place? It's a Middle Eastern country... unless Israelis see themselves as Europeans who happen to be in the Middle East. If that's the case, what are the indigenous Israelis to this assumption or assertion? Palestinian Jews and, therefore not "white'?

    Hell, if Israel can be part of the Eurovision Song Contest, so can Jordan and Lebanon and Turkey... and for that matter, all of North Africa.

    All this reveals that the centrality of racism has its own logic that has been developed since 1444 and nurtured and "legitimized" by the evolution of capitalism and its global dominance.

    In Struggle,

    Sam Anderson

    The Early Worm gets the RFK Jr.!  --  Cartoon by Lalo Alcaraz

    Lalo Alcaraz
    May 9, 2024
    Lalo Alcaraz on X

    Re: The US Plan To Outsource Its Imperialism in Haiti to Kenya
     

    This is fantastic article. As a US citizen married to a Kenyan and living in Kenya as expat, I have seen American military presence increase. In fact, the tow in which I live has KDF base and American and British military training Kenyan soldiers. This has occurred the last year that I've noticed. They even have private military contractors that stay at Matuu Ndallas hotel in Matuu, Machakos, Kenya.

    A reader in Africa

          =====

    Question for Mr. Al-Bulushi:  Have you heard anything about Eric Prince, former Blackwater owner and CIA supposed front man, being involved as a contractor to the US or Kenya to provide mercenaries or body guard or guarding top security bldgs...  He is always trying to make a fast buck and be a king maker.  Peace!

    Buzz Davis former Army officer member of Veterans for Peace in Tucson

    Re: What Beethoven’s Ninth Teaches Us

    Yes. On the 200th anniversary of the 9th Symphony, we streamed, it played by the West Eastern Divan Symphony organized by Edward Said and Daniel Barenboim to promote friendship and understanding. Despite everything we won't forget our hopes for peace.

    Sonia Cobbins
    Posted on Portside's Facebook page

          =====

    From the West-Eastern Divan Orchestra to the Barenboim-Said Akademie

    Watch here   West_Eastern_Divan_Orchestra

    Re: Repo Man at 40: A Journey Deep Into the Heart of LA Punk in the Age of Reagan

    (posting on Portside Culture)
     

    excerpt:

    As Roger Ebert would write in a review from 1984, “this is the kind of movie that baffles Hollywood, because it isn’t made from any known formula and doesn't follow the rules.” Adding context to these observations, Sam McPheeters, in “A Lattice of Coincidence,” included with the 2013 Criterion Collection edition, describes Repo Man as “an apocalypse tale with no doomsday, a punk movie with no concert, a science fiction story with less than ten seconds of aliens.”

    Lorraine Suzuki
    Posted on Portside's Facebook page

    Growing Hypocrisy  --  Cartoon by Jen Sorensen

    I’ve noticed that some people who seem fine with rampant development — and in some cases have profited mightily from it — suddenly become very concerned about growth when the need to build affordable housing arises in their own neighborhood. I do think that growth without any thought to the kind of dense development being created can also be a disaster. Are the new buildings ugly and so cheaply constructed that residents can hear everything their neighbors do through the walls? Are we allowing vehicle size to increase enormously at the same time we are trying to put people in ever denser spaces where they walk and bike? Are we regulating vehicle noise (and leaf blowers!) so people can live and sleep in these denser spaces? Are we keeping some nature? It seems to me that we need to do a number of things differently if we are to create livable cities that accommodate more people.

    Receive my weekly newsletter and help keep this work sustainable by joining the Sorensen Subscription Service! Also on Patreon.

    Jen Sorensen
    May 8, 2024
    jensorensen.com

    List of Universities and Colleges with Encampments and Protests - as of May 15

    Radical Nonviolence:100 Years of the War Resisters League  --  Brooklyn  -- May 16 - September 13  (War Resisters League (WRL) and Interference Archive)

    Image by Pablo Picasso and the War Resisters League

    War Resisters League (WRL) and Interference Archive present a collection of material from the archive and WRL celebrating 100 years of the oldest secular pacifist organization in the United States.

    WRL produced street literature, posters, study guides, brochures, organizing manuals, books, and periodicals that focused on direct action, divestment, tax and draft resistance and ending the nuclear arms race.

    Opening May 16th Curated by Christina Danielle Bartson, Ruth Benn, Sky Hall, Ed Hedemann, Amelia Langas, Brooke Shuman, and Yifan X

    Email us! info@interferencearchive.org

    Witnessing Palestine   --  Chicago  --  June 2  (Eyewitness Palestine)


     

    Sunday, June 2,2024 | 4:30-8:00 PM

    📍Al Hambra Palace | Chicago, IL

    On June 2, 2024, Eyewitness Palestine will be hosting an Evening of Witnessing Palestine Through Stories, Flavor, and Culture with an incredible line-up of artists and speakers, including the First Lady of Arabic Hip-Hop @shadiamansour, West Bank-based journalist @mariambarghouti, 2x award-winning Storyteller& Content Crrator @jenanmatari, Activist @lanzybear, @uscpr Executive Director @ahmadabuznaid, and Live Music by the incredible @nibalmalshi. Book your tickets now for an heartfelt evening of Palestinian speakers, culture, art and food as we take a night to honor Palestine.

    Founded in 2001, Eyewitness Palestine is a transformational education program that inspires and trains participants to be accountable lifelong social justice advocates in the Palestine solidarity movement and within their own communities. We are building a world where Palestine is liberated and all are free!

    Eyewitness Palestine
    PO Box 73798
    Washington, DC 20056

    866.936.1650

    Sing in Solidarity Presents: The World is My Country  --  New York  June 16


     

    Sunday, June 16 2024 at 6:30 PM

    Buy Tickets  

    Songs of Peace and Freedom for the Workers of the World

    So capitalism is disappointing? Forget it! A better world is possible for everyone. Sing in Solidarity, the choir of Democratic Socialists of America, presents a cabaret of international songs for peace, liberty, and socialism in our lifetime. Our high-energy left-wing anthems from around the world will have you leaping from your seats and hoisting high the red flag. Join us for a very special night of solidarity and song and find out how you can join in the fight to demand an end to apartheid and settler colonialism worldwide.

    Doors 6:30 PM, Show 7PM

    “For our demands most moderate are – We only want the earth.”

     - James Connolly, Irish Trade Union Leader, 1907

    “From Palestine to Mexico, all the walls have got to go!”

    - 21st Century Anti-Colonial Refrain

    About the Cabaret

    For their second cabaret at Drom, Sing in Solidarity presents a selection of international antiwar, anti-fascist, and anticapitalist workers songs. Inspired by global socialist and decolonial struggles, this anti-imperialist choral cabaret takes a voyage around the world, touching upon movement music from Palestine, South Africa, Ireland, and more.  With special musical guests Ongama Mhloto, Huda Asfour, and Dorian Wallace.

    About Sing in Solidarity

    Whether marching to “The Internationale” on May Day, leading a picket line with “Roll the Union On,” or performing music from The Threepenny Opera in concert, Sing in Solidarity, the choir of NYC-DSA, uses their voices to strengthen the socialist community through song. Begun in 2017, the choir draws its repertoire from the rich tradition of international revolutionary song: its mission to disseminate anti-capitalist music, build internationalism, and unite the struggles of working and oppressed peoples through culture and song. A fully open movement choir, we believe that anyone can sing. No auditions necessary.  Join our choir today!

    About New York City Democratic Socialists of America

    We’re the NYC chapter of the largest socialist organization in the U.S., Democratic Socialists of America – DSA. We believe a better world is possible and we’re building it right here in New York City. New York is one of the most unequal cities in the country, but it doesn’t have to remain that way. As democratic socialists, we’re building working class power to challenge the dominance of the wealthy and the powerful in the five boroughs. Together, we aim to transform New York into a place where working people have the power to ensure that everyone can live a dignified life. If you want to build a better world, join us!

    Watch here

    Song Nights For Social Change: Commemorating The 60th Anniversary Of Mississippi Freedom Summer & Celebrating The Lives Of Goodman, Schwerner, & Chaney - Free Virtual Concert  --  June 23

    June 23, 2024 07:00 PM EDT

    Musical Guests: Si Kahn, Magpie (Terry Leonino & Greg Artzner), Reggie Harris, and Carolyn Hester
    Host: Susan Erenrich

    Here’s the link to register for the upcoming Free Virtual Song Night For Social Change. You must register in order to attend. Hope to see you on June 23, 2024.

    Smart Pointers in (GNU) C

    Hacker News
    snai.pe
    2024-05-16 19:56:55
    Comments...
    Original Article

    I am a big fan of C, but some part of me always yearn to have just enough higher level constructs.

    The impracticality of memory allocation in C is one of my pet peeves. Being very easily distracted, I tend to forget to free my memory, or close my resources, so you might guess that when I learned about smart pointers in C++, I was immediately hooked.

    As a freshman in my IT engineering school, our first semester was mostly about programming in C. We were assigned pretty simple, solo projects, until the big project came in — we had to implement a POSIX bourne shell, as a team of 4 people, and we were warned that if we leaked, we would eat a pretty hardcore malus on our final grade. We also had to use gcc 4.9 as our compiler.

    Because I knew that my teammates and I were certainly not perfect, I decided to try and make our life easier. I first thought about wrapping malloc to register all allocated data, and then free everything before exiting, but it wasn’t a satisfying solution.

    I went and read a little more about gcc’s attributes, and found __attribute__ ((cleanup(f)): according to the documentation, this variable attribute would call the function f on the variable before exiting the current scope.
    I was delighted.

    Implementing an auto-cleaning variable

    I went on and figured that I would simply make some kind of would-be type attribute to make the variable free itself after going out of scope:

    #define autofree __attribute__((cleanup(free_stack)))
    
    __attribute__ ((always_inline))
    inline void free_stack(void *ptr) {
        free(*(void **) ptr);
    }

    The usage was pretty straight forward:

    1
    2
    3
    4
    5
    
    int main(void) {
        autofree int *i = malloc(sizeof (int));
        *i = 1;
        return *i;
    }
    

    But while it worked well for these tests, when I started refactoring the existing code with the new keyword, it simply didn’t prove to be that useful, because most of the dynamically allocated data was complex data, with (also dynamically allocated) members, and since you can’t slap a cleanup attribute on a struct member, I had to do better.

    I needed some kind of destructor function mechanism.

    I decided to prepend some metadata to the allocated memory – this ought to be the most non-intrusive way to work my way to the new goal:

    |------------------------|---------------------- // -----|
    | metadata    | padding? | actual data                   |
    |------------------------|---------------------- // -----|
    ^                        ^ returned address (word aligned)
     `- start of allocated
        block
    

    I needed two functions: one to allocate the memory, and one to free it. Hence came into existence smalloc and sfree:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    struct meta {
        void (*dtor)(void *);
        void *ptr;
    };
    
    static struct meta *get_meta(void *ptr) {
        return ptr - sizeof (struct meta);
    }
    
    __attribute__((malloc))
    void *smalloc(size_t size, void (*dtor)(void *)) {
        struct meta *meta = malloc(sizeof (struct meta) + size);
        *meta = (struct meta) {
            .dtor = dtor,
            .ptr  = meta + 1
        };
        return meta->ptr;
    }
    
    void sfree(void *ptr) {
        if (ptr == NULL)
            return;
        struct meta *meta = get_meta(ptr);
        assert(ptr == meta->ptr); // ptr shall be a pointer returned by smalloc
        meta->dtor(ptr);
        free(meta);
    }
    

    Both functions are pretty straight-forward: smalloc allocates memory to host both the requested data size and the metadata we need. It then initializes said metadata and stores the destructor, and returns the pointer to the start of the uninitialized user data.

    sfree behaves exactly like free, in that it does nothing if NULL is passed, and otherwise deallocates the memory. The only difference is that it calls the destructor stored during the call to smalloc before the actual deallocation, so that the cleanup step can be performed.

    Given these two functions, I could rewrite my autofree macro:

    #define smart __attribute__((cleanup(sfree_stack)))
    
    __attribute__ ((always_inline))
    inline void sfree_stack(void *ptr) {
        sfree(*(void **) ptr);
    }

    I figured that this was kind of looking more and more like a smart pointer, so I went ahead and renamed autofree to smart.

    One of the immediate consequences of sfree running a destructor was that sfree was the universal deallocator, akin to the delete keyword in C++.

    This means that for any type managed by smalloc I could just call sfree on it without worrying about the real destructor function, and I would know that it would have been destroyed – this was a huge improvement.

    One drawback here is that even for simple types, we had to specify a valid destructor, and this is not always desirable for simple types, so I allowed NULL to be a valid parameter to mean that there is no destructor.

    I also took the time to add a way to put user-defined data into the metadata block, since it could have some nice applications, like length-aware arrays, or extending existing library structures.

    With all of the above done, we pretty much have the needed foundations in place for unique_ptr and shared_ptr. In fact, we currently have unique_ptr.

    The only thing left is shared_ptr then – easier said than done. Shared pointers rely on thread-safe reference counting. From there, two choices: locks, or atomics.

    Using locks is easy, but it makes smart pointer impossible to use in signal handlers; not much of a problem, but still annoying.

    A lock-free implementation would be ideal, but there is a big issue with that: lock-free implementations rely on a compare-and-swap mechanism on the wrapped pointer – here, the pointer is not wrapped. This sucks, but if we make the assumption that no destruction shall happen during an async context, it’s kind of fine (Oh boy, this will definitely make people jump out of their seat). On a side note, I have yet to see a proper solution to that, and I would like to avoid having double pointed types to solve the issue – if anyone has an idea, feel free to send me a message or send a pull request on the github repository.

    For now, I included an atomic integer in the metadata, and a sref function: each time it is called on a shared pointer, the internal reference counter increments by 1, and each time sfree is called on said pointer, it is decremented by 1.

    We still need a way to make a difference between unique and shared pointers, smalloc-wise. To do that, I added another parameter to specify the kind.

    Oh, well. That’s a lot of parameters, now. We have the size, the destructor, the user data, the size of said data, and now the kind of resulting pointer. We started with a simple concept, but if I have to specify five parameters for each allocation, I’d rather go back to malloc and free.

    Macros to the rescue

    One of the first improvements we could do, is to make smalloc variadic — after all, the destructor and the user metadata are completely (and should be) optional. The issue with this is that we need to pass some kind of indicator of the number of variadic parameters. Some use NULL as a sentinel, but it’s not that practical, and some use a parameter to specify that number, but it’s not that better.

    The solution here is to go with the additional parameter, and wrap everything with a macro. The macro would count the number of variadic parameters and dispatch them to the real smalloc function.

    Add two other macros for unique_ptr and smart_ptr to call smalloc with the proper kind parameter, and we have a practical smart pointer library:

    If I’d like to have an unique pointer with a destructor, I’d use unique_ptr(sizeof (T), dtor);.
    For a shared pointer with no destructor but user data, shared_ptr(sizeof (T), &data, sizeof (data));… and this is, at last, absolutely satisfying.

    Edit 15/01/2015: On the advice of /u/matthieum on reddit, I changed the size parameter of my unique_ptr and shared_ptr macros to use the actual type – this makes the usage even easier. On top of that, I implemented smart arrays, and managed to take in array type parameters like int[9] and infer the size of the element type and the length of the array.

    Wrapping everything up…

    There we have it, smart pointers for everyone. I had fun pushing the language a bit further to make it do things it normally would not, although the project itself needs to mature a bit more before being ready for some kind of production.

    I have wrapped everything in a github repository, for everyone to toy with. Installation instruction & usage samples are included in the readme. Have fun reading through, curious developer!

    Who Wants 30k Used Teslas?

    Hacker News
    nymag.com
    2024-05-16 19:47:58
    Comments...
    Original Article
    A Hertz Tesla electric vehicle is displayed during the Hertz Corporation IPO at the Nasdaq in New York

    Photo: Brendan McDermid/Reuters

    At the start of the year, after Hertz announced it was selling off its fleet of Teslas — backtracking on a plan to buy up 100,000 of the electric vehicles — the news sounded good for Bijay Pandey, a 34-year-old self-employed data worker in Irving, Texas. “I have another vehicle, and I was trying to add one for my wife because gas prices were too high,” he said. When he found out that it came with a $4,000 tax credit — even better. “That’s what attracted me,” he added. So, the day after Valentine’s Day, he bought a red 2022 Long Range Model 3 with 70,000 miles on it. It ended up costing just about $25,000, not a bad deal for a car that can sell for about $47,000 new.

    But almost immediately, there were problems. After getting a temporary title, he found the car wasn’t reading voltage correctly. Soon, a body shop found a quarter-size hole in the undercarriage he hadn’t seen before, which led to revelations of deeper issues inside. “The high-voltage battery pack is damaged and could cause extreme safety concerns,” a Tesla technician texted him. Because the hole was “exterior damage,” it wasn’t covered by the warranty, which meant a $13,078.58 repair bill. Hertz said that it would swap the car for Pandey, but for about two months he waited — making $500 payments on his auto loan — before getting a replacement. “I realized why they were trying to get rid of those Teslas,” he said. “If anything happens to a Tesla, then the bill is too high.”

    Hertz is an early contender for Wall Street’s schlimazel of the decade, the big unlucky lemon that just can’t seem to get anything right. The run of high-profile disasters began more than four years ago when the rental-car company went into bankruptcy during the early weeks of the pandemic, weighed down by $19 billion in debt and facing a global pause on travel. It sold off its fleet of vehicles to pay back creditors, became one of the first meme stocks, and — thanks to a raging bull market — emerged from bankruptcy in record time.

    But that win may have been unlucky in its own way — Hertz was left trying to build back up its fleet during a time when the cost of new vehicles was skyrocketing. In 2021, at the height of the Tesla hype boom, Hertz announced it would make 20 percent of its cars electric — it never got to quite that level, but it did end up buying about 30,000 Teslas. (It bought other EVs, too, but most of the fleet comes from Elon Musk’s company). Since it returned to the public market in 2021, Hertz has lost more than $12 billion in value, and its CEO Stephen Scherr — the former CFO of Goldman Sachs — stepped down.

    Hertz’s latest challenge is trying to get out of its entanglement with Tesla. In retrospect, it just looks like a bad idea. Companies like Hertz make money when they rent out cars as often as possible, which means their vehicles will often have more miles than the average vehicle, and, in turn, have more problems that need expensive maintenance. A side deal renting the EVs to Uber drivers — who often have to drive hundreds of miles a day to make a profit — wore down the cars even more, which also weighed down their resale value. Last month, the company announced that it had sold about 10,000 EVs — about a third of the total fleet it intends to offload. At first blush, that looked like Hertz would be ahead of schedule. But the pace of sales is starting to slow. One salesman at a Hertz in Smithtown, New York, told me that sales have dropped from as much as 30 a week in January and February to about five a week in April. Online forums are full of people steering prospective buyers away from Hertz vehicles. One factor may be price. “Hertz does not provide haggling on price,” he said. “It is what it is.”

    When Hertz first announced it was selling off most of its EVs, it blamed lower demand among the traveling public than it had expected. “They have an oversupply” of Teslas, said John Plimpton Babcock, an analyst at Bank of America who covers the car-rental company. That lower turnover meant less profit, he added.

    It makes sense Hertz would try to sell off its fleet now. Purchases of brand-new EVs are stalling out after a decade or so of stratospheric growth. Auto loans have interest rates starting at about 5 percent and go skyward from there. A shortage of reliable charging stations, and worries about batteries losing power in cold weather, have all hurt public interest in owning — and perhaps even renting — an EV.

    In response to questions about its Tesla sales, a Hertz spokeswoman forwarded comments from the company’s CEO, Gil West, that the company expects that the sell-off of the remaining 20,000 EV will be “complete by the end of the year.” The company also said that, as far as Pandey’s car was concerned, “we worked closely with him to deliver a Tesla that met his needs and preference.”

    Who Wants 30,000 Used Teslas?

    Companies need AI services revenues, not cost savings

    Hacker News
    www.ft.com
    2024-05-16 19:43:11
    Comments...
    Original Article

    Padlock icon

    Subscribe to unlock this article

    Try unlimited access
    Only $1 for 4 weeks

    Then $75 per month.
    Complete digital access to quality FT journalism on any device. Cancel anytime during your trial.

    Explore more offers.

    Standard Digital

    Weekend Print + Standard Digital

    Essential digital access to quality FT journalism on any device. Pay a year upfront and save 20%.

    Standard Digital

    Weekend Print + Standard Digital

    FT Weekend newspaper delivered Saturday plus essential digital access.

    Standard Digital

    Weekend Print + Standard Digital

    Complete digital access to quality FT journalism with expert analysis from industry leaders. Pay a year upfront and save 20%.

    Explore our full range of subscriptions.

    Why the FT?

    See why over a million readers pay to read the Financial Times.

    Find out why

    The most confusing emojis in every US state in 2024

    Hacker News
    preply.com
    2024-05-16 19:34:56
    Comments...
    Original Article

    The world of language offers many ways to communicate, whether through words, body language, or even small digital icons called emojis. Emojis can be found in text messages, social media comments, and basically anywhere else you communicate digitally. These small but impactful characters add emotion, visual appeal, and personality to your message.

    With thousands of emojis to choose from, ranging from a simple pizza slice to icons layered with meaning, the language of emojis can be complex. Just like some people may refer to their shoes as “sneakers” while others call them “tennis shoes,” people can interpret common emojis differently depending on a variety of factors, including where they live.

    As advocates of language learning, we at Preply wanted to understand more about how non-verbal communication in the form of emojis translates to the general public. To decode the conversations, we surveyed 2,201 Americans about current and upcoming emojis to find out what they think the emojis mean most. Read on to find out the most confusing emojis in every state, as well as learn more about the upcoming emojis that may cause some confusion in future conversations.

    Key findings

    • 💅, 💨, and 🙃 are the most confusing emojis in 2024.
    • Someone else’s use of an emoji has caused confusion for 81%.
    • Almost half, 48%, have seen a misinterpreted emoji create an uncomfortable situation.
    • The phoenix emoji is the most confusing out of those being released in 2024.

    America’s most confusing emojis in 2024

    While emojis can make conversations easier – allowing you to send a simple thumbs up 👍 instead of typing out a yes or adding more to your agreement – they can also leave the other person confused. In fact, 81% of our respondents say they’ve been confused by someone else’s use of an emoji. This happens when someone sends an emoji that seems out of context to the person on the other end but makes perfect sense to the sender.

    To find out the most confusing emojis in 2024, we at Preply took the top ten most confusing emojis from 2023 and surveyed respondents again about their meaning. We then used standard deviation to analyze answer choices to figure out which ones puzzle Americans the most.

    If you thought the most confusing emoji would be a face displaying a hard-to-read emotion, think again! The research found the most confusing emoji is actually one painting a finger with nail polish. While 40% use the icon to signify classy or being bougie, others say it means “just nail polish,” “Don’t mind me hehe,” and “self-care.” The confusing emojis that follow on the list are dashing away 💨 and the upside-down face 🙃.

    To be fair, although emojis have their given titles upon their creation, their use is open to interpretation. So don’t let others’ definitions deter your use of creative characters – just be sure to clarify if the recipient seems confused.

    The most confusing emojis in 2024

    Most confusing emojis in every state

    As with any form of language, people tend to interpret things differently, even if they live in the same state. For example, when it comes to fizzy drinks, depending on what state you’re in, it can either be called “soda” or “pop.” The lack of understanding of these words can leave you wondering if you need to sign up for private English lessons.

    Although they’re not physical words, emojis aren’t exempt from confusion. In fact, we found the most confusing emoji in each state through our analysis. Those most confused by the nail polish emoji live in the West, South, or Midwest. Those most confused by the dashing away emoji live in the Midwest, Northeast, or South, and those most confused by the upside-down face live in the South.

    The most confusing emoji in every state

    Whether because of cultural backgrounds, societal norms, or linguistic influences, people in the same state can give different meanings to the same emoji. While someone may interpret your 👍 as approval or agreement, another may take it as a passive-aggressive or dismissive response. Unfortunately, leaving things up to interpretation can cause discomfort. For example, 48% have seen a misinterpreted emoji create an uncomfortable situation.

    Preply language expert Sylvia Johnson tells us more about how emojis, especially those containing hand expressions or gestures, may be interpreted differently based on cultural cues:

    “Emojis are widely used in digital communication worldwide. However, these small digital images meant to represent an idea, mood, or emotion could be interpreted differently depending on cultural contexts. The interpretation of emojis can also reflect generational differences, personal interpretations, and more. As they continue to evolve into a language of their own in digital communication, users need to take extra care in selecting which emojis to use, especially when the context involves cross-cultural communication.

    👍 Thumbs Up

    In Western cultures, this emoji often signifies affirmation or agreement, symbolizing “good” or “yes.” However, in certain Middle Eastern cultures, it’s considered offensive, akin to showing the middle finger in the United States.

    👌 OK Sign

    This emoji translates to “OK,” “perfect,” or “excellent” in many parts of the Western world. However, in Brazil and parts of Southern Europe, it’s considered obscene. Australian aboriginal people regard it as a symbol of evil. In Japan, it signals money, and in some Middle Eastern countries, it refers to the evil eye.

    ✌️ Victory Sign

    Prevalently, this emoji stands for “peace” in the UK and US. However, if the palm is faced inward in Britain and Australia, it is akin to giving the middle finger.”

    Americans’ interpretations of the new emojis coming in 2024

    If the thousands of emojis already available for use aren’t enough, 118 new emojis will be available for use in Spring 2024, according to Emojipedia. To understand how these new emojis will resonate with Americans, we surveyed respondents on three specific ones: head shaking horizontally, head shaking vertically, and a phoenix.

    Out of the three, we found that the phoenix will most likely confuse receivers, with 64% finding it confusing. While many people did interpret it as a phoenix, others considered using it as a way to express other things like being on fire and rebirth. Unique responses to that emoji ranged from someone thinking it was a flaming pegasus to another thinking it should be Elon Musk’s new X (formally Twitter) icon.

    The other two emojis displaying shaking heads also caused confusion. While for some, the head-shaking horizontally emoji looked like saying “no,” others interpreted it as being happy or even dizzy. The head shaking vertically also had some split responses for its meaning, from “yes” to “sleepy.” As these new emojis enter the chat, it’s important to keep in mind possible interpretations for them and to always ask for clarification if something comes off as confusing.

    The most confusing new emojis

    The most common emojis people don’t use as intended

    Through Preply’s analysis, we also found the top rebelled-against emojis, meaning the emojis that people use for different meanings than what their title suggests they mean. The top emoji people don’t use as intended is the persevering face, with only 5% using it as intended and the majority using it to signify frustration. The next two rebelled against emojis were the fearful face and nail polish.

    Although a title can suggest a specific meaning, the possibilities for the use of a particular emoji can sometimes be endless. If you combine enough emojis, the receiver can even have fun decoding your response. Using your imagination to express sentiments in certain situations can add personality to the conversation.

    There is room for creativity in any form of language, especially within the use of emojis, and adding personality to language can help make a more engaging conversation. If you feel like your speech could use some creativity to help carry on conversations, taking conversational English lessons can give you the tools you need to have more meaningful conversations.

    Top Emojis people don't use as intended

    Becoming a clearer communicator through Preply

    It’s interesting to see how society can adapt to specific meanings for beloved digital characters that are different from what they were created to mean. However, not everyone is well versed in the language of emojis, which can cause confusion or discomfort in conversations, as if someone were speaking a foreign language. This can also be difficult when the specific use of emojis is continually evolving within generations.

    When communicating with someone, it’s crucial to discern how they communicate best. Understanding someone’s communication style can help you communicate more clearly and effectively with them. This requires you to be adept in different communication styles and languages, which can be done through taking language classes.

    Although at Preply, we don’t offer classes on the use of emojis, we do offer other courses that can help level up your verbal communication. From online Spanish classes to classes that help you expand your vocabulary and more, our tutors will guide you in learning a new language that can help you communicate more clearly with those around you.

    Methodology

    In February 2024, we surveyed 2,2021 Americans in 40 states about how they interpret different emojis. By analyzing the standard deviation per question, we were able to determine the most confusing emojis in 2024. Respondents ranged in age from 18 to 76 years old, and were 49% female, 48% male, and 2% nonbinary.

    You probably don't need to validate UTF-8 strings

    Hacker News
    viralinstruction.com
    2024-05-16 19:21:17
    Comments...
    Original Article

    Written 2024-05-16

    Strings are important to all programmers, but to us bioinformaticians, they are an absolutely central. The layout of strings is just a slice of bytes in memory, so you'd think the string data type is not an interesting design space when designing a programming language - but you'd be wrong! In this post, I'll compare and contrast the design of strings in Rust and Julia.

    Why not also compare Python's strings?

    Python was my first programming language, and is a language I'm deeply familiar with, so it'd be obvious to include Python's str in the comparison. Unfortunately, Python comes from such a different place than Rust or Julia - it was designed in the 1990's, and it was never designed to be used for computationally demanding tasks. For a thorough explanation of Python's strings, I recommend reading Victor Skvortsov's deep dive on the subject.

    Perhaps the main difference from Python to Julia and Rust is that the latter languages are from the early 2010's, where the UTF8 encoding scheme had become the dominant string encoding - ~98% of web sites are encoded in UTF8 according to Wikipedia. As such, when Julia and Rust were designed, it was obvious to represent strings as byte arrays encoded in UTF8. Explaining UTF8 itself is outside the scope of this post, but I recommend reading up on it if you do any serious string processing in your own code.

    Mutability

    In Julia, data types are declared as mutable or immutable types, and String is one of the immutable ones. Mutating strings requires unsafe functions[1] and may cause undefined behaviour. The reason Julia strings are immutable is a question of semantics: A string's value is identical to its content. If strings were mutable and I changed a string from "box" to "fox", it's not the same string that has changed, but instead a new string that was created from the same memory, similarly to how the number 4 and the number 5 are distinct numbers, even though it's possible to mutate a piece of memory from storing a 4 to storing a 5.

    In Rust, it is variables and not types which are mutable or immutable, and so Strings can be mutated though a mutable variable or reference. Strings also supports dynamic resizing (e.g. my_string.push).

    Why doesn't Julia have per-variable mutability instead of per-type mutability? One reason is simplicity: Per-type mutability obviates the need to have two kinds of bindings: x and mut x. Another issue is Julia's lack of a borrowchecker: If all data can be mutated through a mutable variable, for the compiler to know if some data is immutable, it needs to know that no other part of the program holds a mutable reference to it, and so the compiler needs to enforce something like Rust's ownership rules. In contrast, if the values of some types are always immutable, the compiler knows data of that type is immutable no matter who holds references to it.

    As always, immutability comes with a performance penalty: Mutating values is generally faster than creating new ones. This cause a problem when working with immutable types: For efficiency, we want to be able to mutate strings, but for the compiler to treat strings as immutable, we want to never be able to observe them being mutated. To solve this problem, Julia uses the following interesting pattern in its internals:[2]

    mem = unsafe_wrap(Memory{UInt8}, Base._string_n(8))
    copyto!(mem, 0x61:0x68)
    str = String(mem)

    In this code:

    1. The internal function Base._string_n(8) creates a string with 8 bytes of uninitialized memory

    2. The unsafe_wrap calls returns a Memory{UInt8} view of the string. Because there are no longer any references to the string after creating mem and so the string cannot be observed, mutating mem is legal

    3. We mutate the memory, in this example using copyto!

    4. Finally, String(mem) creates a string from the memory. Mutating the memory after this call is illegal.

    It's not exactly pretty. Perhaps a better design would expose _string_n as public, have String(::Memory{UInt8}) copy, and introduce unsafe_takestring(::Memory{UInt8}) to create zero-copy strings from memory. Or perhaps not. The risks of accidentally stumbling into undefined behaviour territory might make APIs like this a minefield.

    Struct definitions

    The definition of String in Rust is pretty straightforward:

    pub struct String {
        vec: Vec<u8>,
    }

    The Vec<u8> contains the content of the string, encoded in UTF8. Vec is, of course, also implemented in Rust. If I inlined the composition of Vec and the composition of those structs etc, then String has the following layout:

    struct IllustrativeString {
        ptr: *u8,
        capacity: usize,
        len: usize,
    }

    Note that the actual in-memory ordering of fields of Rust structs is an implementation detail decided by the compiler.

    More commonly used is the str type, which can be considered a string view. It's almost always (always?) a borrowed reference, so it's mostly seen as &str. This type is built into the Rust compiler, but contains only a pointer and a length.

    It's quite the meme that Rust has tonnes of different string types: String, str, OsString, OsStr, CString, Cstr and possibly more. Part of this complexity comes from Rust having to duplicate every type to have an owned and a borrowed version. Interestingly, the same borrowchecker which enables Rust to avoid creating types in immutable/mutable pairs, forces Rust to create owned/borrowed pairs of types.

    In Julia, String is implemented in C and is one of the few completely opaque types in the language, i.e. its layout can't be introspected from Julia itself. However, I believe it consists of this data, stored on the heap, in order:

    1. The length of the string, in a word-sized integer

    2. The UTF8 data of the string itself

    3. A trailing null byte, for easier C interop

    In Julia, it's passed around as a single pointer to this heap data. Besides the most basic functionality such as instantiating strings, and getting the number of bytes in the string and a pointer to its content, essentially all operations on strings are defined in Julia code.

    Indexing into strings

    In both Rust and Julia, you can slice into strings to get a substring. For example, here, in Julia:

    julia> "alphabeta"[3:5]
    "pha"

    These indices are byte indices and the result is a newly allocated String (similar to how slicing into an array allocates a new array). The first and last index must be the starting bytes of characters, else you get a runtime error:

    julia> "alpæabeta"[3:5]
    ERROR: StringIndexError: invalid index [5], valid nearby indices [4]=>'æ', [6]=>'a'

    Rust works the same way, except it returns a &str and so does not allocate.

    Rust and Julia differ in that Julia allows indexing with a scalar to produce a Char. This, too, will fail if the index provided is not the first byte index of a Char in the string. This scheme allows O(1) access to characters, providing the caller knows the byte index of the character.

    Rust intentionally does not allow indexing with integers, alledgedly in order to not confuse users into believing the index represent a character index instead of a byte index - but I think that's not a very convincing argument given that slicing already does work using byte indices.

    Accessing the underlying bytes of a string

    This is done in two quite different ways in Rust and Julia that are characteristic of the languages:

    In Rust, my_string.as_bytes() returns the data of the string as a byte slice - &[u8]. Notably, the slice type (&[T]) is the most basic type in Rust to represent a view into a contiguous chunk of memory with elements of type T. In fact, when operating on Vec<T>, if you don't need to resize the vector, it is idiomatic to write functions that take a slice &[T] instead of the vector itself. Rust will automatically convert (dereference) the vector to a slice when calling the function (because Vec<T> implements the trait Deref<Target = &[T]>), and in this manner, the function is more generic and will also work on, for example, the bytes of a string.

    In contrast, in Julia, codeunits(my_string) produces a dedicated CodeUnits{UInt8, String} object that wraps my_string and is an instance of AbstractVector{UInt8}.

    Both objects provide zero-cost access to the bytes using a vector-like type. Where they differ most starkly is how they allow generic user code to operate on this array-like object:

    Julia relies on the fact that CodeUnits subtypes AbstractVector, and that the CodeUnits objects therefore can be used with any code that works with generic AbstractVector values. Since many different types in Julia, such as ranges, similarly subtype AbstractVector, the user has a strong incentive to write their functions generically enough to accept AbstractVector. In turn, this leads to Julia code being highly composable. For example, if someone wrote a library with a function that was intended for, say Vector, I can most likely plug in a CodeUnits, or even a range, and it'll still work.

    In this case, Rust enables generic code in the exact opposite manner: Instead of unifying different types with a disparate implementation into a single interface, it allows many different types to share the same data layout: Strings, vectors, paths and more can be represented as a byte slice &[u8].

    Compared to the Julia approach, this is much less generic - for example, ranges cannot dereference into a slice, so methods taking &[T] won't work on ranges. On the flip side, because the data layout of a slice is well-defined, it's possible to provide much more optimised code for slices than for an abstract vector - for example, one can call memchr on any &[u8], but not on any abstract vector. Also, the behaviour of a function that takes a single, concrete type - a slice - is easier to reason about than code that may operate on any type that subtypes AbstractVector.

    Enforced valid UTF8

    Okay, this is the big one: In Rust, strings are always valid UTF8, and attempting to create a string with invalid UTF8 will panic at runtime:

    fn main() {
        println!("{}", std::str::from_utf8(b"\xff\x02").unwrap());
    }
    thread 'main' panicked at src/main.rs:2:53:
    called `Result::unwrap()` on an `Err` value: Utf8Error { valid_up_to: 0, error_len: Some(1) }

    In contrast, Julia allows invalid UTF8 in strings:

    julia> s = String(b"\xff\x02")
    "\xff\x02"
    
    julia> isvalid(s)
    false

    In my opinion, this is the most interesting difference between Rust and Julia strings. These behaviours are very much intentional, and when I've asked around about this design decision, both the Rust and Julia community argue forcefully in favor of the design of their language.

    What's up with that difference? Let's dig in!

    First, remember the value propositions of the two languages. To put it pointedly:

    • Rust treats all code as production-quality code. The very existence of quick and dirty code is against Rust's values, so it's no problem if Rust frustrates and hinders your attempts at prototyping - it's only protecting you from sinning.

    • Julia treats all code as prototype code, and encourages hacking. The language will provide zero help with procuding code that is maintainable and robust, and if you're aiming to do so, the recommendation is simply "be disciplined".

    My argument is that the approaches taken by Rust and Julia makes sense given their respective language design goals. However, I believe Julia's paradigm of "UTF8 by convention" is overall the better design in most situations, and probably also would have been better for Rust.

    How do you handle invalid UTF8?

    Suppose you are writing a function that needs to read the lines of a text file. The file is probably UTF8, but how do you know? It could've been saved in another format like latin1, or it could be saved in UTF8, but have been slightly corrupted since then.

    What is the design space here? How could Julia behave, if we were to redesign it from scratch?

    One option is to have String constructors throw an exception when encountering invalid UTF8. This would, ironically, create a correctness footgun: Your code would work fine during testing, all up until the moment it (unexpectedly) hits a non-UTF8 file and crashes. That violates a tenant of good code: If your code crashes unexpectedly, it should be because your code is bad, not because the data you process is bad. Also, this approach prevents you from actually handling non-UTF8, because simply exiting the program when encountering non-UTF8 is not handling it - you program in fact, does not work with non-UTF8.

    Another option is to not crash immediately when encountering non-UTF8, but defer the decision to the user. For example, Julia could return some MaybeUTF8Bytes object that then needs to be unwrapped to either error or get a valid UTF8 string. This is what Rust does. This way, it forces the user to consider the existence of other encodings (or currupted data). This has two issues:

    • First, it adds extra boilerplate to your code. This might be acceptable in a language like Rust where correctness comes above all, but imagine having to unwrap maybe-strings in a REPL or a notebook when doing interactive data science. Fuck no.

    • Second, practically speaking, most users are just going to unwrap your maybe-string indiscriminately, anyway. By far most Rust programs I've seen take this approach. The fact that actually handling the error case is so rare makes me feel that very little correctness is gained from the extra ceremony.

    The third option is to make the UTF8 check opt-in. Julia would accept strings with arbitrary (non-UTF8) bytes, and if the user cares to handle the edge case, they would have to run some sort of isvalid check themselves. This is where Julia has landed. Interestingly, the Zig language takes it even further and says that strings are just arrays of u8, similar to C. Julia differs from Zig and C in that its string are a distinct type, which is useful to prevent type confusion, and for specializing some methods for strings, such as displaying them differently.

    The advantage of Julia's approach here is clear: Less boilerplate, and by default the ability to handle other encodings. The disadvantage? Well, perhaps it's not so great as you think:

    You probably don't actually care whether your string is UTF8

    No wait, that doesn't make any sense. If you don't verify your string is UTF8, your 'string' could be arbitrary bytes which you can't make sense of. How do you meaningfully process data if you don't know its structure?

    Here's the thing: I'll grant that you need to know your input bytes are structured, but the structure you care about isn't UTF8.

    Let's consider two kinds of program that handles strings:

    Some programs are input structure agnostic, such as cat, hexdump, and ripgrep. They're agnostic because they don't really process strings, but the content of arbitrary files, no matter their format. Really, they just process byte streams, so here, UTF8 validation is clearly counterproductive.

    Speaking of which - if you want to be able to write these kinds of programs, then you probably also want other string types that is not necessarily UTF8. Rust handles this by also having the extra types OsString and OsStr, as well as CString and CStr. In fact, ripgrep is based on the bstr type in Rust - which, just like Julia's strings are non-validated UTF8-by-convention. The author of ripgrep has written a blog post about the motivation for bstr which is worth reading and re-iterates some of the same arguments I've put forth here. Having to use all these strings types are wonderfully rigorous, but also a meme-worthy level of pedanticness, and not exactly a nice user experience for the programmer.

    But what about programs which do care about the structure of their input? An example could be a program which reads a JSON file, or a CSV file, or a tabular output file. However, in every single case I can think of, programs which read structured data have stricter requirements of their input than being merely UTF8, so UTF8 validation doesn't buy you anything.

    For example, JSON is a subset of UTF8, so when parsing JSON, you can't just check for the input being UTF8 - you would need to match the input against a much smaller set of accepted bytes which constitute valid JSON, probably using a state machine or such. This is also the case when dealing with CSV files, TOML files, TSV files, and every other format in existence.

    Practially speaking, every time you read an input file, you either only care about it as a stream of bytes, or else you need to parse it into a format which is more strict than UTF8. What kind of program could possibly take input data and requires it to be UTF8, but have no more restrictions on its input? There is one type of program I can think of: Functions whose output is obliged to return UTF8, because its consumer tells you it requires UTF8. An example would be a JSON parser, where strings in JSON format must be UTF8, but can be arbitrary UTF8. However, this is UTF8 for the sake of it being UTF8 - they need to be UTF8 because JSON demands they are UTF8, not because of any real-life constrains on the data.

    Let me demonstrate what I mean: If you know that a string is UTF8 but not anything else about its format, what useful knowledge have you gained about the string?

    • Do you know how to render it? Probably no. UTF8 is so large and sprawling that very few programs can faithfully render all of UTF8.

      • Is this one emoji or several on your system? 👩🏼‍❤️‍💋‍👨🏻

      • Is this char correctly monospaced on your system?

      • Does mouse highlighting work correctly for this string in your browser? पन्ह पन्ह त्र र्च कृकृ ड्ड न्हृे إلا بسم الله

    • Do you know at least know how to compute its printed length? No. The length of an UTF8 cannot be determined because it depends on the font, the terminal that renders it, the emoji recognized, and much more.

    • Okay, but then do you know how many characters the string is composed of? Also no - it's implementation dependent which groups of codepoints is recognized as extended grapheme clusters (individual characters). Also the definition of a single character is kind of fuzzy around the edges in some languages.

    • Okay, but at least you can correctly do some simple transforms of the string? I.e. you can split it by spaces, right? Well, not really - at least it's complicated. The string "ac" contains a zero-width space between the two letters. This is not classified as whitespace by convention, but it's expected that the string must be broken at space when wrapping. In contrast, "a c" contains a non-breaking space - a space where the line must not break. What about "a
c"? This contains a paragraph separator and is not split according to Julia's split, even though it's a whitespace character. And so on and so forth.

    • Let's make it simpler. What about .to_lowercase()? Surely, that must work correctly on UTF8? Well, no - a string being UTF8 is not enough to correctly lowercase a string. Is the lowercase of Σ σ or ς? Well, it depends. Does Σ appear as part of a formula, or as Greek prose? And, if it's Greek prose, does the letter occur at the end of a word? What about the lowercase of SS - is it ss or ß? Well, it depends on the structure of the input - is it German or Norwegian?

    In fact, I'm struggling with coming up with a single thing that you can correctly and consistently do with UTF8 text that you can't do with a bunch of opaque bytes - not including self-justifying reasons like "you can count the number of UTF8 codepoints in a UTF8 string".

    Preempting some arguments

    What about a tool like cut? In order to cut a line by, say, \t, you need to know how \t is encoded, but you don't need to know anything else. So, for a tool like cut, you need to know exactly that the encoding is UTF8.

    Yes, well, or latin1 - the most common encoding scheme after UTF8. Forcing UTF8 would incorrectly reject latin1 files.

    Anyway, a more important reason is: Why is cut used - i.e. why do you need the second tabular column? Let's say you use it to parse a two-column TSV file using a Unix pipe, like tail file.tsv -n +2 | cut -f 2 | awk '{s += $1} END {print s}'.

    Well, in that case, if the program needs to validate that it operates on well-formatted data, then it needs to validate that the file is actually a two-column TSV file as is being assumed by the pipline. It's completely insufficient to just validate the input is UTF8.

    If you have a string and don't know it's valid UTF8, simple operations like lowercasing, iterating, and checking the number of codepoints give meaningless, undefined results. This violates the principle that programs should not produce faulty results silently.

    That's not right - all of these operations can be perfectly well defined on malformed UTF8 strings. We can simply decide to not lowercase ill-formed codeunit sequences and not include them when counting codepoints[3].

    Now you could say that that's not semantically meaningful - simply skipping ill-formed sequences may be correct according so some arbitrary ruleset, but if I write a program which tries to uppercase \xff\xff\x00\xa1, then nothing meaningful will come out of it - something clearly went wrong. You'd be right! But it's no less meaningless than trying to uppercase ҧăɗޒҒ|˫Ǎߑ, which is perfectly valid UTF8 - again, knowing something is UTF8 does not give it semantic meaning.

    Arguments for enforced UTF8

    I can come up with two good reasons for enforcing valid UTF8: First, Rust's way of returning Option or Result forces the programmer to at least consider non-UTF8ness. So, enforced UTF8 is beneficial when the programmer:

    1. Wants to correctly handle non-UTF8 data, and simultaneously

    2. Would otherwise forget that non-UTF8 data exists.

    I find that combination rather unlikely though I'm sure it's the case for someone.

    The second reason is that the user might call into a library that actually happens to require that a string is valid UTF8, and only UTF8. I'm not sure what kind of library which reasonably wants that, but perhaps a text rendering library?

    Rust's and Julia's string APIs

    I'd be remiss not to compare this aspect of strings, even though it's not really part of the design of the string type itself: The APIs of the functions used to manipulate strings.

    Julia's string APIs is pretty good - but as usual, Rust's APIs are excellent:

    • Rust's APIs consistently take and return &(mut) str where possible. This is ergonomic due to the same reason Rust can expose the codeunits of strings as a byte slice: String implements Deref<Target = &str>. This means Rust's string functions are zero-allocation where possible, and work with strings as well as substrings. In contrast, Julia's functions mostly return SubString where possible, but often doesn't have implementations optimised for taking SubString, and too often allocate needlessly.

    • Rust have specialized ASCII versions of several functions, e.g. make_ascii_lowercase, split_ascii_whitespace and trim_ascii. Often, users really only work with ASCII, and in those cases, specializing the functions can make them significantly faster.

    • The functions split_once and lines are often useful. Unfortunately, Julia doesn't have non-allocating versions of these.

    • The API for mutating strings in Rust is significantly better than in Julia. In Julia, the standard way is to allocate a Vector{UInt8}, mutate it, then copy it to a string when it's done. One issue with this is that this requires your string manipulation to happen on the byte level - you can't easily append a character to the vector, for example. Another issue is that it forces multiple allocations since the bytes needs to be copied.

    Julia does seem to be slowly catching up to Rust over time. For example, I used to gripe that Julia didn't have a non-allocating splitter, in-place line reading, a reverse splitter, non-allocating string search methods, but these have been added the last few years.

    Conclusion

    Strings are carefully designed in both Rust and Julia, and while strings are implemented as 'just' a byte array in both languages, there are some small but significant differences in their designs. Some of the differences stem from overarching language differences - more precisely Rust's borrowchecker, and Julia's abstract types.

    Overall, Julia's strings are a more opaque data type that behaves in a special, priviledged manner, compared to strings in Rust. This is somewhat inevitable as Julia is not self-hosted, so the compiler has to be non-Julian at some low level.

    A major design difference is that Rust strings are enforced to be valid UTF8, whereas Julia's aren't. I believe Julia made the better choice here overall, although Rust's extra validation fits well into the language's core values. Other than this issue, Rust's strings are manipulated through methods with a stellar API, which Julia could learn a lesson or two from.

    [2] These are subject to change, as it's Julia's internals. Also, this precise pattern so far only exist in beta releases of Julia, not able stable versions. There is not currently any public API that allows allocation of uninitialized strings.
    [3] See the Unicode standard version 15.0, chapter 3, section C10 and D89.

    The New Midlife Crisis

    Hacker News
    www.firstthings.com
    2024-05-16 19:10:18
    Comments...
    Original Article

    Check all the boxes, then chuck it all aside at forty to follow your muse. Play by the rules and win, only to decide that you don’t want the prize. Most of the rebellions were minor. The devoted housewife informed her husband that she would not be cooking dinner for the family on Tuesday and Thursday nights, as she was finally taking the art class she had always dreamed of. The cliché for men was the red convertible. But some people set off explosions: quitting jobs, filing for divorce, engaging in affairs.

    For Baby Boomers, the midlife crisis was very nearly a rite of passage. John Updike made a career of chronicling the earthquakes that rattled the mannered world of upper-middle-class suburbanites. But that world of well-scrubbed children, stay-at-home wives, and afternoon cocktails seems as remote today as King Arthur’s court. For most millennials, the idea of being a forty-year-old ad executive on a commuter train, oppressed by routine and convention as he returns to his spacious suburban home, wife of eighteen years, and two teenage children, is just a fantasy. For those who haven’t yet found a spouse or bought a house, it might seem not a nightmare but a dream.

    Before you can tire of life as a housewife, you need a house and a husband whose income can maintain a family. Before you can embark on an affair, you need to get married. It is hard to buy a sports car at forty if you’re still paying off student loans, or to enjoy a second youth while looking after your first baby. In the 1960s, 1970s, and 1980s, only about 6 percent of forty-year-olds had never been married. Today it is true of one in four. A 2021 report found that one in six adults were childless, and that number is likely to increase.

    In the 1960s, the Canadian psychoanalyst Elliott Jaques coined the term “midlife crisis.” The term described a confrontation with mortality that occurred in one’s mid-thirties, when “family and occupation have become established . . . and children are at the threshold of adulthood.”

    Jaques’s term did not catch on until the 1970s, when Gail Sheehy, a journalist for New York magazine, used it in Passages, her bestselling book. The term became part of the therapeutic patois of the upper middle class in the closing decades of the twentieth century. It was the catch-all explanation for the feelings of dissatisfaction and unhappiness that afflicted the educated classes when things seemed outwardly auspicious. Why would a man, recently promoted to senior partner at a prestigious law firm, feel restless? Midlife crisis. Why would his wife, a mother of happy and healthy children, feel unfulfilled? Midlife crisis.

    Sheehy understood the midlife crisis in broadly feminist terms. As children grew older and the burdens of childcare eased, women could explore new possibilities. Loss of fertility was to be welcomed rather than dreaded: “Once the worries of pregnancy are thrown out along with the tampons and contraceptives, women in good health will often experience a reawakening of sexual desire, as well as great enthusiasm for directing their creativity into new channels.” The family box has been checked; there’s more to life for the college-educated woman.

    As the historian Susanne Schmidt has noted, Sheehy’s description of the midlife crisis corresponded to what Betty Friedan, in The Feminine Mystique (1963), had called “the problem that has no name.” After interviewing suburban women in their thirties and forties, Friedan painted a picture of widespread dissatisfaction. As these women endured day after day of tidying the house, shopping for groceries, cooking meals, and ferrying the children before lying joylessly beside their husbands at night, they were afraid to ask themselves, “Is this all?” Friedan suggested that they should cease to think of themselves exclusively as wives and mothers, and instead pursue degrees, careers, and political engagement.

    Alongside this feminist understanding of the midlife crisis was a masculinist one. It received more extensive treatment in literature and media, which is why in its popular usage “midlife crisis” was applied primarily to men—their fantasies, foibles, and mishaps. In works like John Cheever’s “The Swimmer,” the middle-aged man finds himself changed in ways he can hardly understand—at one moment strong and admired, in the next weak and pitied. Facing mortality, Cheever’s protagonist embarks on a surreal journey through all the swimming pools of his prosperous suburban town. Cheever was evoking what psychologists called a man’s “second adolescence”—a natural rite of passage whose manifestations were to be understood, not condemned.

    Medical authorities writing on the male midlife crisis presented it as potentially a moment of liberation. The psychiatrist George Vaillant described the professional men undergoing midlife crises in terms that evoked Friedan:

    From age twenty-five to thirty-five they tended to work hard, to consolidate their careers, and to devote themselves to the nuclear family. . . . Rather than question whether they had married the right woman, rather than dream of other careers, they changed their babies’ diapers and became lost in conformity.

    Breaking free of conformity often meant shattering the marital bond. After all, the right woman at twenty-five might be the wrong woman at forty. The psychologist Daniel Levinson drew out the implications of the second adolescence: The same wifely virtues that once had helped a man build a comfortable life and successful career—her thriftiness and prudent concern, her way of looking after a man as well as his children—could in later years become smothering. Like the adolescent boy who needs to establish an identity apart from his mother, the married man may need freedom from his wife, who now seems “overly controlling.” Naturally enough, he finds it in the arms of a different woman, one who is “more understanding, sharing, and sensually evocative.” In those decades of conformist middle-class culture, men nurtured fantasies of living like James Bond.

    The midlife crisis was a problem of the privileged—a recognition that something was wrong in a life in which everything seemed right. The crisis endures, but the conditions have been reversed. Baby Boomers were raised to expect happiness in domestic life. A man’s career and a woman’s wifely duties served the household gods. My generation received very different instructions. It’s not as though Sex and the City was urged as a guide to life. But we were told to find ourselves and establish ourselves professionally before settling down.

    As a result, a new anxiety arrives at midlife. “The problem that has no name” has been replaced by the “biological clock.” Upper-middle-class women still experience a moment of recognition, often in their mid-thirties. They still confront the fact that the dominant image of success hasn’t delivered everything they want their lives to include. But it is a husband and children they are now likely to miss, not a career, travel, and nightlife.

    Works of popular art have begun to document the new crisis. Barbie, the 2023 blockbuster directed by Greta Gerwig, is a modern Pinocchio story. Initially, Barbie is a deathless, sexless being—unconcerned with men or children, immune to thoughts of mortality. No mere doll, she is the model career woman. “She has her own money, her own house, her own car, her own career. Because Barbie can be anything, women can be anything.” She is living Betty Friedan’s dream. But when Barbie becomes human, she must come to terms with biological realities. The film ends with her visit to an ob-gyn. In real life, the visits are to IVF clinics.

    Men have much more time on their clocks, a fact that allows millennial males now entering middle age to defer any deliberation about what they want out of life. Instead of a second adolescence, they seem determined to enjoy perpetual adolescence. (Is it any wonder that female millennial professionals are desperate when they wake up at age thirty-five and realize they want a husband?) But how long can men defer the reckoning? The Worst Person in the World, a 2021 film by the Norwegian director Joachim Trier, offers an answer. It features a man who suddenly learns he has cancer. He is the paragon of creative-class success, an underground comic-book artist whose most famous creation has been turned into a movie. But he never managed to have the children he wanted. He lost the woman he loved. All he has left are his collections of comic books and records.

    Baby Boomers got married, owned homes, and had kids. The price was conformity. No doubt it could be stultifying. But for most people, the crisis was mild. You could waste money on a sports car and still have grandchildren someday. That was true even if your affairs led to a messy divorce. What of my generation? Our plan of life has been to put off the old patterns of adulthood. There will be plenty of time for that, we’ve been told. For now there’s a vacation, a concert, a promotion to think about. But something is missing in a life made up of only these things. As one unmarried friend told me before she left New York, “I like my lifestyle, but not my life.”

    Matthew Schmitz is founder and editor of Compact. 

    Image by Karolina Grabowska, public domain. Image cropped.

    Wind farms can offset their emissions within two years, new study shows

    Hacker News
    newsroom.taylorandfrancisgroup.com
    2024-05-16 18:48:04
    Comments...
    Original Article
    Breaking research

    After spinning for under two years, a wind farm can offset the carbon emissions generated across its entire 30-year lifespan, when compared to thermal power plants.

    That’s according to a new peer-reviewed study published in the Journal of the Royal Society of New Zealand – which also shows within six months a turbine can generate all the energy consumed across its life-cycle.

    The research uses data from the Harapaki onshore wind farm in Hawke’s Bay, New Zealand – however the authors of the paper explain that their findings would be replicated across most, if not all, wind farms internationally.

    “The wind turbine technology employed in New Zealand is consistent with that used internationally,” explains lead author Isabella Pimentel Pincelli from the Sustainable Energy Systems research group, Wellington Faculty of Engineering, at Te Herenga Waka Victoria University of Wellington.

    “Although the carbon offset depends on the exact older technology the wind turbines are replacing, we would expect a similar offset internationally. In New Zealand it is gas turbines, but many countries will be displacing fossil fuel generators.

    “The outcomes of our study underscore the environmental efficiency of onshore wind farms and their important role in the energy transition. Notably, the manufacturing of wind turbines is the primary contributor to the carbon and energy footprints, highlighting a critical area for targeted environmental mitigation strategies.”

    The study reviewed current literature on wind farms, as well as using real construction data to take into account everything from the manufacturing of individual turbine parts, to transporting them into place, to decommissioning the entire wind farm at Harapaki – which comprises 41 turbines.

    The results indicate that this particular farm will leave a carbon footprint of 10.8 gCO2eq/kWh, which equates to a greenhouse gas payback time of 1.5–1.7 years for avoided combined cycle gas turbines, and an energy payback time of 0.4–0.5 years.

    Co-author Professor Alan Brent, Chair in Sustainable Energy Systems at Wellington, explains while the results underscore how onshore wind plants are aligned with the principles of sustainable development, more can still be explored with making the manufacturing process more eco-friendly.

    “The environmental impacts of the installation and transportation phases are important. Together they accounted for nearly 10% of the overall emissions,” states Brent, a Professor of Sustainable Energy Systems.

    “It therefore remains crucial to continue implementing improvements aimed at limiting negative environmental impacts while maximizing positive contributions throughout the supply chain of onshore wind plants.

    “Notably, the manufacturing of wind turbines is the primary contributor to the carbon and energy footprints, highlighting a critical area for targeted environmental mitigation strategies.”

    To address the carbon outlay of the process of developing such wind farms, the expert team recommend developing a recycling process for end-of-life blades.

    Currently blades are disposed of in landfill due to commercial feasibility, but by recycling the blades – either mechanically or chemically – could drop the emissions from the current 10.8 gCO2eq to a potential 9.7.

    Additionally, the team recommend that research is carried out regularly in this area as with the “rapid advancements of technologies” it will be “necessary to ensure research remains reflective of current practices to accurately inform decision-making processes”.

    This study has some methodological limitations. First, it focuses only on the energy intensity and emissions throughout the life cycle of the wind farm, even though there are other environmental impacts, such as ozone depletion, human toxicity, acidification, eutrophication, and resource depletion. Social, wildlife, or economic impacts were also not considered.


    John Goerzen: Review of Reputable, Functional, and Secure Email Service

    PlanetDebian
    changelog.complete.org
    2024-05-16 18:42:31
    I last reviewed email services in 2019. That review focused a lot of attention on privacy. At the time, I selected mailbox.org as my provider, and have been using them for these 5 years since. However, both their service and their support have gone significantly downhill since, so it is time fo...
    Original Article

    I begin with Mailbox, as it was my top choice in 2019 and the incumbent.

    Until this year, I had been quite happy with it. I had cause to reach their support less than once a year on average, and each time they replied the same day or next day. Now, however, they are failing on reliability and on support.

    Their spam filter has become overly aggressive. It has blocked quite a bit of legitimate mail. When contacting their support about a prior issue earlier this year, they initially took 4 days to reply, and then 6 days to reply after that. Ouch. They had me disable some spam settings.

    It didn’t really help. I continue to lose mail. I don’t know how much, because they block a lot of it before it even hits the spam folder. One of my friends texted to say mail was dropping. I raised a new ticket with mailbox, which took them 5 days to reply to. Their reply was unhelpful. “As the Internet is not a static system, unforeseen events can always occur.” Well yes, that’s true, and I get it, false positives exist with email. But this was from an ISP’s mail system with an address that had been established for years, and it was part of a larger pattern of rejecting quite a bit of legit mail. And every interaction with them recently hasn’t resulted in them actually doing anything to resolve anything. It’s just a paragraph or two of reply that does nothing and helps nothing.

    When I complained that it took 5 days to reply, they said “We have not been able to reply sooner as we are currently experiencing a high volume of customer enquiries.” Even though their SLA for my account is a not-great “48 business hour” turnaround, they still missed it and their reason is “we’re busy.” I finally asked what RBL had caught the blocked email, since when I checked, the sender wasn’t on any RBL. Mailbox’s reply: they only keep their logs for 7 days, so next time I contact them within 7 days. Which, of course, I DID; it was them that kept delaying. Ugh! It’s like they’ve become a cable company.

    Even worse is how they have been blocking mail from GrapheneOS’s discussion form. See their thread about it. In short, Graphene’s mail server has a clean reputation and Mailbox has no problem with it. But because one of Graphene’s IPv6 webservers has an IPv6 allocation of a size Mailbox doesn’t like, they drop mail. It’s ridiculous, and Mailbox was dismissive of this well-known and well-regarded Open Source project. So if the likes of GrapheneOS can’t get good faith effort to deliver their mail, what chance does an individual like me have?

    I’m sorry, but I’m literally paying you to deliver email for me and provide good support. If you can’t do either of those, you don’t get to push that problem down onto me. Hire appropriate staff.

    On the technical side, they support aliases, my own clients, and have a reasonable privacy policy. Their 2FA support exists for the web interface (though weirdly not the support site), though it is somewhat weird. They do not support app passwords.

    A somewhat unique feature is the @secure.mailbox.org domain. If you try to receive mail at that address, mailbox.org will block it unless it uses TLS. Same for sending. This isn’t E2EE, but it does at least require things not be in plaintext for the last hop to Mailbox.

    Verdict: not recommended due to poor reliability and support.

    Mailbox.Org summary:

    • Website: https://mailbox.org/en/
    • Reliability: iffy due to over-aggressive spam filtering
    • Support: Poor; takes 4-6 days for a reply and replies are unhelpful
    • Individual access passwords: No
    • 2FA: Yes, but with a PIN instead of a password as the other factor
    • Filtering: Full SIEVE feature set and GUI editor
    • Spam settings: greylisting on/off, reject some/all spam, etc. But they’re insufficient to address Mailbox’s overzealousness, which support says I cannot workaround within the interface.
    • Server storage location: Germany
    • Plan as reviewed: standard [pricing link]
      • Cost per year: EUR 30 (about $33)
      • Mail storage included: 10GB
      • Limits on send/receive volume: none
      • Aliases: 50 on your domain name, 25 on mailbox.org
      • Additional mailboxes: Available; each one at the same fee as the primary mailbox

    Crypto brothers front-ran the front-runners

    Hacker News
    www.bloomberg.com
    2024-05-16 18:32:21
    Comments...
    Original Article

    Why did this happen?

    Please make sure your browser supports JavaScript and cookies and that you are not blocking them from loading. For more information you can review our Terms of Service and Cookie Policy.

    Need Help?

    For inquiries related to this message please contact our support team and provide the reference ID below.

    Block reference ID:

    Microsoft shares temp fix for Outlook encrypted email reply issues

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-16 18:28:40
    ​Microsoft has shared a temporary fix for a known issue preventing Microsoft 365 customers from replying to encrypted emails using the Outlook Desktop client. [...]...
    Original Article

    Outlook

    ​Microsoft has shared a temporary fix for a known issue preventing Microsoft 365 customers from replying to encrypted emails using the Outlook Desktop client.

    This confirms customer reports regarding these issues when using the classic Outlook clients shared on Microsoft's community website in recent months.

    According to online reports, reinstalling Outlook or creating a new profile for the impacted email account fails to address the issue.

    As Redmond explained in a Thursday support document, the issue only affects Microsoft 365 customers on Current Channel Version 2402 (Build 17328.20142) and higher, released on February 28.

    It also impacts only those who must respond to emails encrypted using Office 365 Message Encryption (OMEv2), now known as Microsoft Purview Message Encryption.

    Affected customers will receive error messages stating, "Microsoft Outlook was not able to create a message with restricted permission" when trying to reply to messages using Microsoft encryption.

    ​Official workarounds available

    As a temporary fix, Microsoft says you can still reply to encrypted emails using the new Outlook or Outlook Web Access (OWA).

    If you can only use the Outlook Desktop app to reply to encrypted emails you receive, you can revert to the last working build.

    To do that, you will have to type Command Prompt in the Windows search box, right-click Command Prompt, and click Run as administrator.

    Next, you have to paste the following commands in the Command Prompt window and hit Enter after each:

    cd %programfiles%\Common Files\Microsoft Shared\ClickToRun
    officec2rclient.exe /update user updatetoversion=16.0.17231.20236

    Last month, Microsoft also rolled back a fix for an Outlook issue caused by the December Outlook Desktop security updates triggering incorrect security alerts when opening ICS calendar files.

    Recently, the company also resolved another known issue causing Outlook desktop clients to stop synchronizing with email servers via Exchange ActiveSync and a bug causing connection problems for Outlook.com users on both desktop and mobile email clients.

    day 652-664 git-remote-annex

    JoeyDev
    git-annex.branchable.com
    2024-05-16 18:23:42
    The Distribits conference was a wonderful chance to meet with many scientific users of git-annex and learn about amazing things they are doing with it. After giving my talk, titled "git annex is complete, right?", it turned out (spoilers) to not be complete. Indeed, the very next talk gave me a big...
    Original Article

    The Distribits conference was a wonderful chance to meet with many scientific users of git-annex and learn about amazing things they are doing with it.

    After giving my talk, titled "git annex is complete, right?", it turned out (spoilers) to not be complete. Indeed, the very next talk gave me a big idea that I have been working on for the past several weeks and have merged into master today. Michael Hanke described his git-remote-datalad-annex which lets git push, pull, and even clone from a git-annex special remote.

    I immediately saw that this would be better implemented in git-annex, which would let it use its internals rather than some of the hacky workarounds Michael needed. Also, I saw that git bundles were a much better data format to use, which would allow cheap incremental git pushes.

    At the Distribits hackathon, I got together with Michael and Timothy Sanders, and we thought through the data format to store on special remotes. We ended up with a quite simple data design, which can be used without git-annex if necessary. (See git-remote-annex.)

    Getting git bundles to work right, especially incremental bundles, and dealing with all the quirks of git's gitremote-helper interface turned out to be more challanging than I thought. I ended up spending a week implementing a prototype in shell script to work through all the details. Then I had to reimplement it all in Haskell, ending up with over 1000 lines of code.

    The result is the git-remote-annex, which will ship in the next git-annex release. It should work with most types of special remotes, including exporttree=yes ones (but not yet importtree=yes). But I've only tested it on the directory special remote so far. It's really neat to be able to git clone a repository from so many places, as well as incrementally push changes.

    There is a git-remote-annex todo page, of which a lot of the remainder is various race conditions when two people are pushing different things to the same special remote at the same time. At least some of those will be dealt with, for now I recommend only using git-remote-annex when you know you're the only one pushing to a special remote.

    This work was sponsored by Mark Reidenbach, Jake Vosloo, Lawrence Brogan, Graham Spencer, unqueued, and Erik Bjäreholt on Patreon

    Marc Andreessen: Guide to Personal Productivity (2007)

    Hacker News
    pmarchive.com
    2024-05-16 18:14:14
    Comments...
    Original Article

    Productivity porn (or, for those really in the know, “productivity pr0n") consists of techniques, tactics, and tricks for maximizing personal productivity—or, as they say, “getting things done”.

    The techniques that follow work together as an integrated set for me, but they probably won’t for you. Maybe you’ll get one or two ideas—probably out of the ideas I stole from other people. If so, I have succeeded.

  • Let’s start with a bang: don’t keep a schedule.

    He’s crazy, you say!

    I’m totally serious. If you pull it off—and in many structured jobs, you simply can’t—this simple tip alone can make a huge difference in productivity.

    By not keeping a schedule, I mean: refuse to commit to meetings, appointments, or activities at any set time in any future day.

    As a result, you can always work on whatever is most important or most interesting, at any time.

    Want to spend all day writing a research report? Do it!

    Want to spend all day coding? Do it!

    Want to spend all day at the cafe down the street reading a book on personal productivity? Do it!

    When someone emails or calls to say, “Let’s meet on Tuesday at 3”, the appropriate response is: “I’m not keeping a schedule for 2007, so I can’t commit to that, but give me a call on Tuesday at 2:45 and if I’m available, I’ll meet with you.”

    Or, if it’s important, say, “You know what, let’s meet right now.”

    Clearly this only works if you can get away with it. If you have a structured job, a structured job environment, or you’re a CEO, it will be hard to pull off.

    But if you can do it, it’s really liberating, and will lead to far higher productivity than almost any other tactic you can try.

    This idea comes from a wonderful book called A Perfect Mess, which explains how not keeping a schedule has been key to Arnold Schwarzenegger’s success as a movie star, politician, and businessman over the last 20 years.

    Want to meet with Arnold? Sure, drop on by. He’ll see you if he can. But you might want to call first. Sorry, he doesn’t schedule appointments in advance.

    As a result, for 20 years he has been free to work on whatever is most important in his life at any time.

    Those of you in California may recall how, once Arnold decided to run for Governor, he went into a blaze of action and activity that resulted in a landslide victory. The book attributes this in part to the fact that his schedule was completely clear and he could spend all day, every day on his new political career, without having to worry about distractions or commitments.

    If you have at any point in your life lived a relatively structured existence—probably due to some kind of job with regular office hours, meetings, and the like—you will know that there is nothing more liberating than looking at your calendar and seeing nothing but free time for weeks ahead to work on the most important things in whatever order you want.

    This also gives you the best odds of maximizing flow, which is a whole ’nother topic but highly related.

    I’ve been trying this tactic as an experiment in 2007, as those of you who have emailed me to suggest we get together or that I go to a conference or to a meeting will attest. And I am so much happier, I can’t even tell you. I get so much more time to focus on the things that really matter—in my case, my two companies, my nonprofit boards, and my lovely wife.

    The other great thing about this tactic is that it doesn’t have to be all or nothing—there are quite a few things that still sneak onto my calendar that I really can’t get out of. But one is still able to draw the line between “must do” and “sounds interesting but I’m not keeping a schedule”.

  • Keep three and only three lists: a Todo List, a Watch List, and a Later List.

    The more into lists you are, the more important this is.

    Into the Todo List goes all the stuff you “must” do—commitments, obligations, things that have to be done. A single list, possibly subcategorized by timeframe (today, this week, next week, next month).

    Into the Watch List goes all the stuff going on in your life that you have to follow up on, wait for someone else to get back to you on, remind yourself of in the future, or otherwise remember.

    Into the Later List goes everything else—everything you might want to do or will do when you have time or wish you could do.

    If it doesn’t go on one of those three lists, it goes away.

  • Each night before you go to bed, prepare a 3x5 index card with a short list of 3 to 5 things that you will do the next day.

    And then, the next day, do those things.

    I sit down at my desk before I go to sleep, pull up my Todo List (which I keep in Microsoft Word’s outline mode, due to long habit), and pick out the 3 to 5 things I am going to get done tomorrow. I write those things on a fresh 3x5 card, lay the card out with my card keys, and go to bed. Then, the next day, I try like hell to get just those things done. If I do, it was a successful day.

    People who have tried lots of productivity porn techniques will tell you that this is one of the most successful techniques they have ever tried.

    Once you get into the habit, you start to realize how many days you used to have when you wouldn’t get 3 to 5 important/significant/meaningful things done during a day.

  • Then, throughout the rest of the day, use the back of the 3x5 card as your Anti-Todo List.

    This isn’t a real list. And the name is tongue firmly in cheek.

    What you do is this: every time you do something—anything—useful during the day, write it down in your Anti-Todo List on the card.

    Each time you do something, you get to write it down and you get that little rush of endorphins that the mouse gets every time he presses the button in his cage and gets a food pellet.

    And then at the end of the day, before you prepare tomorrow’s 3x5 card, take a look at today’s card and its Anti-Todo list and marvel at all the things you actually got done that day.

    Then tear it up and throw it away.

    Another day well spent, and productive.

    I love this technique—being able to put more notches on my accomplishment belt, so to speak, by writing down things on my Anti-Todo list as I accomplish them throughout the day makes me feel marvelously productive and efficient. Far more so than if I just did those things and didn’t write them down.

    Plus, you know those days when you’re running around all day and doing stuff and talking to people and making calls and responding to emails and filling out paperwork and you get home and you’re completely exhausted and you say to yourself, “What the hell did I actually get done today?”

    Your Anti-Todo list has the answer.

    By the way, in order to do this, you have to carry a pen with you everywhere you go. I recommend the Fisher Space Pen. It’s short and bullet-shaped so it won’t poke you in the thigh when it’s in your pocket, it’s wonderfully retro, it helped save the Apollo 11 mission, and it writes upside down. What’s not to like?

  • Structured Procrastination.

    This is a great one.

    This one is lifted straight from the genius mind of John Perry, a philosophy professor at Stanford.

    Read his original description, by all means. You even get to see a photo of him practicing jumping rope with seaweed on a beach while work awaits. Outstanding.

    The gist of Structured Procrastination is that you should never fight the tendency to procrastinate—instead, you should use it to your advantage in order to get other things done.

    Generally in the course of a day, there is something you have to do that you are not doing because you are procrastinating.

    While you’re procrastinating, just do lots of other stuff instead.

    As John says, “The list of tasks one has in mind will be ordered by importance. Tasks that seem most urgent and important are on top. But there are also worthwhile tasks to perform lower down on the list. Doing these tasks becomes a way of not doing the things higher up on the list. With this sort of appropriate task structure, the procrastinator becomes a useful citizen. Indeed, the procrastinator can even acquire, as I have, a reputation for getting a lot done.”

    Reading John’s essay was one of the single most profound moments of my entire life.

    For example, I hate making phone calls. Hate it. Love sending emails, enjoy seeing people face to face (sometimes), but I hate making phone calls.

    I can get so much done while I am avoiding making a phone call that I need to make, I can barely believe it.

    In fact, that’s what’s happening right now.

  • The other key two-word tactic: Strategic Incompetence.

    The best way to to make sure that you are never asked to do something again is to royally screw it up the first time you are asked to do it.

    Or, better yet, just say you know you will royally screw it up—maintain a strong voice and a clear gaze, and you’ll probably get off the hook.

    Of course, this assumes that there are other things that are more important at which you are competent.

    Which, hopefully, there are.

    Organizing the company picnic, sending faxes or Fedexes, negotiating with insurance brokers, writing in plain English... the list of things at which one can be strategically incompetent is nearly endless.

  • Do email exactly twice a day—say, once first thing in the morning, and once at the end of the workday.

    Allocated half an hour or whatever it takes, but otherwise, keep your email client shut and your email notifications turned off.

    Anyone who needs to reach you so urgently that it can’t wait until later in the day or tomorrow morning can call you, or send a runner, or send up smoke signals, or something else.

    Or, more likely, find someone else who can do whatever it is that needs doing.

    (If you communicate with your spouse or key family members via email during the day, then just set up a separate email account just for them and leave that open all day, but keep your primary email closed. And never give out the family email address to anyone noncritical—including your boss.)

    Only doing email twice a day will make you far more productive for the rest of the day.

    The problem with email is that getting an email triggers that same endorphin hit I mentioned above—the one that a mouse gets when he bonks on the button in the cage and gets a food pellet.

    Responding to an email triggers that same hit.

    The pleasure chemical hits your neocortex and you go “ahhh" inside and feel like you’ve done something.

    So you sit and work with your mail client open and you interrupt your work every time an email comes in and you answer it and you send another email and you feel great in the moment.

    But what you’re really doing is fracturing your time, interrupting your flow, and killing your ability to focus on anything long enough to get real high-quality work done.

    This one is far easier to say than do. And it won’t be feasible during projects where lots of updates during the day really are important—raising money, for example, or closing a big deal.

    Me, I’m just trying to get down to checking email only a half dozen times per day.

  • When you do process email, do it like this:

    First, always finish each of your two daily email sessions with a completely empty inbox.

    I don’t know about you, but when I know I have emails in my inbox that haven’t been dealt with, I find it hard to concentrate on other things.

    The urge to go back to my email is nearly overpowering.

    (I am apparently seriously addicted to endorphins.)

    Second, when doing email, either answer or file every single message until you get to that empty inbox state of grace.

    Not keeping a schedule helps here, a lot, if you can pull it off—you can reply to a lot of messages with “I’m sorry, I’m not keeping a schedule in 2007, I can’t commit to that.”

    Third, emails relating to topics that are current working projects or pressing issues go into temporary subfolders of a folder called Action.

    You should only have Action subfolders for the things that really matter, right now.

    Those subfolders then get used, and the messages in them processed, when you are working on their respective projects in the normal course of your day.

    Fourth, aside from those temporary Action subfolders, only keep three standing email folders: Pending, Review, and Vault.

    Emails that you know you’re going to have to deal with again—such as emails in which someone is committing something to you and you want to be reminded to follow up on it if the person doesn’t deliver—go in Pending.

    Emails with things you want to read in depth when you have more time, go into Review.

    Everything else goes into Vault.

    Every once in a while, sweep through your Action subfolders and dump any of them that you can into Vault.

    (And do the same thing for messages in your Pending folder—most of the things in there you will never look at again. Actually, same is true for Review.)

    That’s it.

    You can get away with this because modern email clients are so good at search (well, most of them—and you can always move to GMail) that it’s not worth the effort to try to file emails into lots of different folders.

    Obviously you may need some additional permanent folders for important things like contracts, or emails from your doctor, or the like, but these are exceptions and don’t change your standard operating procedure.

  • Don’t answer the phone.

    Let it go to voicemail, and then every few hours, screen your voicemails and batch the return calls.

    Say, twice a day.

    Cell phones and family plans are so cheap these days that I think the best thing to do is have two cell phones with different numbers—one for key family members, your closest friends, and your boss and a few coworkers, and the other for everyone else.

    Answer the first one when it rings, but never answer the second one.

  • Hide in an IPod.

    One of the best and easiest ways to avoid distractions in the workplace is to be wearing those cute little IPod earbud headphones (or any other headphones of your choice).

    People, for some reason, feel much worse interrupting you if you are wearing headphones than if you’re not.

    It’s great—a lot of the time, people will walk up to you, start to say something, notice the headphones, apologize (using exaggerated mouth motions), and walk away.

    This is great—half the time they didn’t actually need to talk to you, and the other half of the time they can send an email that you can process at the end of the day during the second of your two daily email sweeps.

    Here’s the best part: you don’t actually have to be listening to anything.

    Hell, you don’t even have to have the headphones plugged into anything.

  • I’m not going to talk a lot about getting up early or going to bed late or anything else related to the course of a typical day, because everyone’s different.

    Personally I go back and forth between being a night owl (99% of the time) and a morning person (1%—I’m going to try to push it to 2%).

    But the thing that matters almost more than anything in determining whether I’ll have a happy, satisfying day is this: no matter what time you get up, start the day with a real, sit-down breakfast.

    This serves two purposes.

    First, it fuels you up. Study after study have shown that breakfast is, yes, the most important meal of the day. It’s critical to properly fuel the body for the day’s activities and it’s also critical to staying lean or losing weight. (People who don’t have breakfast tend to eat more, and worse, at lunch.)

    Second, it gives you a chance to calmly, peacefully collect your thoughts and prepare mentally and emotionally for the day ahead.

    This works whether you do it with kids and/or a partner, or you’re solo.

    Personally I think it’s worth whatever effort is involved to go to bed early enough to wake up early enough to have a good solid 45 minutes or an hour for breakfast each morning, if you can pull it off.

  • Only agree to new commitments when both your head and your heart say yes.

    This one is from the great Robert Evans.

    (Hold out for the audiobook—trust me.)

    It’s really easy to get asked to do something—a new project, a nonprofit activity, a social event—and to have your head say yes and your heart say no, and then your mouth says yes.

    The next thing you know, you’re piled up with all kinds of things on your schedule that sounded like a good idea at the time but you really don’t want to do.

    And distract you from the things that really matter.

    And make you angry, and bitter, and sullen, and hostile.

    (Oh, wait, I’m projecting.)

    In my experience, it takes time to tell the difference between your head saying yes and your heart saying yes.

    I think the key is whether you’re really excited about it.

    If you get that little adrenaline spike (in a good way) when you think about it, then your heart is saying yes.

    The corollary, of course, is that when your head says no and your heart says yes, your mouth should generally say yes as well :-).

    But not when your head says yes and your heart says no.

  • Do something you love.

    As you’ve probably concluded by now, most of the tactics described in this post involve keeping oneself as free as possible to pursue one’s core interests, and dreams.

    If you’re not doing something you love with the majority of your time, and you have any personal freedom and flexibility whatsoever, it’s time for a change.

    And this doesn’t mean something that you love doing in theory—but rather, the core thing you love doing in practice.

  • And that’s it.

    Please feel free to nominate additions to the list! Next time my mobile wiki-based GTD Outlook synchronized hipster PDA reminds me, I’ll check ’em out.

    Turns out Robert Benchley wrote about structured procrastination back in 1949. Wonderful essay—highly recommended.

    The sharpest reaction has been to my theory of not keeping a schedule. I’ll stick to my theory but make (or re-make) a couple of clarifying points.

    First, it is certainly true that many people have jobs and responsibilities where they can’t do that. Or maybe can only do it partially. And many people enjoy living a highly structured life and obviously this approach is not for them.

    But if your reaction is, “boy, I wish I could do that”, then it may well be worth rethinking your approach to your career.

    I can tell you from personal experience that being stuck in a role where you have a lot of structure but feel like you never get anything done is not the optimal way to advance in one’s profession, or maximize one’s job satisfaction.

    Second, I do not recommend pursuing this approach in one’s personal life :-).

    On another topic, the tactic of each night, write down the 3 to 5 things you need to do the next day has struck some people as too simplistic.

    That may be the case for some people, but I can’t tell you how many times I’ve arrived home at night and am at a loss as to what I actually got done that day, despite the fact that I worked all day.

    And I also can’t tell you how often I’ve had a huge, highly-structured todo list in front of me with 100 things on it and I stare at it and am paralyzed into inaction (or, more likely, structured procrastination).

    So a day when I get 3 to 5 concrete, actionable things done in addition to all the other stuff one has to do to get through the day—well, that’s a good day.

    A few people have said, why not just use GTD (David Allen’s “Getting Things Done” approach).

    While I find GTD to be highly inspiring, in practice I think it’s awfully complex. At least if your job is based on project work (as opposed to having a highly structured role like CEO or head of sales).

    For me, an organization system that requires significant time to deal with in and of itself is not optimal. Much better, for me at least, is to focus on stripping away nonessentials and freeing up as much time as possible to deal with whatever is most important.

    Finally, I discovered after writing this post that Paul Graham talks a bit about the role of time and focus in personal productivity in his essay on “The Power of the Marginal”.

    The Tragic Downfall of the Internet's Art Gallery

    Hacker News
    slate.com
    2024-05-16 18:12:22
    Comments...
    Original Article
    Users

    The Tragic Downfall of the Internet’s Art Gallery

    Once a vibrant platform for artists, DeviantArt is now buckling under the weight of bots and greed—and spurning the creative community that made it great.

    A human hand holds a piece of art, while an A.I./robot hand tries to grab on to it.

    Photo illustration by Slate. Images by Vladimir Sukhachev/Getty Images Plus and Vladyslav Severyn/Getty Images Plus.

    On March 27, a large group of artists and creators from across the web noticed the frightening extent to which a once-beloved, highly influential community platform of theirs had, like so many others, fallen prey to the artificial intelligence juggernauts plundering the internet.

    As VFX animator Romain Revert (Minions, The Lorax) pointed out on X, the bots had come for his old home base of DeviantArt. Its social accounts were promoting “top sellers” on the platform, with usernames like “Isaris-AI” and “Mikonotai,” who reportedly made tens of thousands of dollars through bulk sales of autogenerated, dead-eyed 3D avatars. The sales weren’t exactly legit—an online artist known as WyerframeZ looked at those users’ followers and found pages of profiles with repeated names, overlapping biographies and account-creation dates, and zero creations of their own, making it apparent that various bots were involved in these “purchases.”

    It’s not unlikely, as WyerframeZ surmised, that someone constructed a low-effort bot network that could hold up a self-perpetuating money-embezzlement scheme: Generate a bunch of free images and accounts, have them buy and boost one another in perpetuity, inflate metrics so that the “art” gets boosted by DeviantArt and reaches real humans, then watch the money pile up from DeviantArt revenue-sharing programs. Rinse, repeat.

    After Revert declared this bot-on-bot fest to be “the downfall of DeviantArt,” myriad other artists and longtime users of the platform chimed in to share in the outrage that these artificial accounts were monopolizing DeviantArt’s promotional and revenue apparatuses. Several mentioned that they’d abandoned their DeviantArt accounts—all appearing to prove his dramatic point.

    Worse still, DeviantArt showed little desire to engage with these concerns: Film concept artist Reid Southen (The Woman King, Jupiter Ascending) pointed out that the site’s social media managers had hidden dozens and dozens of critical replies to the tweet that boosted Mikonotai. Right after this blowup, DeviantArt’s Twitter account posted artwork from Nozomi Matsuoka, who was forced to clarify that she’d already wiped her DeviantArt library in protest of its A.I. integrations. The account took down the post soon after.

    This isn’t the first (or most recent) time the 24-year-old social network has invited such rancor over its A.I. experiments. Much of the ire comes from current and former members, who’d made it an essential resource for illustrators, photographers, cartoonists, and other visual masterminds hoping to show their works, network with peers, and break into creative industries. The first real round of A.I. furor hit DeviantArt in late 2022. As generative-A.I. tools like DALL-E 3 and Midjourney breached the mainstream, DeviantArt partnered with the startup Stability A.I. to roll out an internal image-generation tool called DreamUp, which had the ability to scrape “every single piece of art on the platform” for training purposes, per Artnet News.

    Outcry from users caused a quick walk back from the company, which noted that “deviations”—creations shared to DeviantArt—would now be “automatically labeled as NOT authorized for use in A.I. datasets.” This did not satisfy the platform’s “Deviants,” who noted that DreamUp was still based off the underlying architecture of Stability A.I.’s popular Stable Diffusion tool—which had already scraped tens of thousands of DeviantArt entries to train its model without creators’ permission, as writer Andy Baio reported and as DeviantArt itself later admitted.

    In January 2023, three prominent illustrators (Sarah Andersen, Kelly McKernan, and Karla Ortiz) filed a copyright-infringement and unfair-competition class-action lawsuit in federal court against DeviantArt, Stability, and Midjourney, whose own app trained on the same database that powers Stable Diffusion. Notably, they alleged here that more than 3 million DeviantArt images had been scraped in the training sets used by all three companies.

    The suit hit a legal barrier last October, when the judge advanced only Andersen’s infringement claim against Stability while dismissing the rest of the charges—albeit allowing the plaintiffs to refine their case and try again if they chose. And refine it they did, by bringing on seven other artists as fellow plaintiffs. This extended the suit to include popular A.I.-creation firm Runway, which helped to craft Stable Diffusion.

    They also amended their complaint against DeviantArt to specify that its rollout of DreamUp constituted direct copyright infringement, a breach of its terms-of-service agreements with DeviantArt users, and a “theft” of revenue from the artists whose works were expropriated as training data. This updated lawsuit, which added pages of visual evidence demonstrating A.I. output that looked nearly identical to users’ artwork, now had additional support from famed artists like Adam Ellis, Gregory Manchess, and Jingna Zhang.

    In Zhang’s case, this is neither her only courtroom appearance nor her sole advocacy effort on behalf of artists in the age of mass reproduction. On Friday, she prevailed in a yearslong plagiarism suit against Luxembourgian artist Jeff Dieschburg, who used a 2017 magazine photograph shot by Zhang as a “model” for a 2022 painting he showcased at the Strassen Contemporary Art Biennale—and for which he won a cash prize. Zhang celebrated this verdict, which found that Dieschburg had violated copyright law by using the photo as a source for his art without adding due credit, as a “win” for “artists and photographers everywhere … especially in [the] time of AI where our rights seem to be quickly eroding.”

    Zhang told me in an interview that this same copyright principle was what she wanted to bring to the fore in joining the stateside A.I. suit, although this battle is no less personal—and not just because hundreds of her works have been scraped by these companies. “I’ve had an account on DeviantArt for 22 years,” she said. “I actually dropped out of school because I grew a following on DeviantArt. My first job for Mercedes-Benz happened when I was 20 years old because they found my work online.”

    She’s far from the only DeviantArt success story. Southen, who joined DeviantArt in the mid-2000s, told me he’d established friendships there that have lasted to this day.

    “It was a super important place that had a lot to do with my development as an artist and where I’m at today,” Southen said. He added that the folks he connected with on the site “have helped get me work, and I’ve helped get them work.”

    R.J. Palmer, a concept artist who worked on Detective Pikachu, claims to have gotten that gig thanks to the “Realistic Pokemon” illustrations he’d shared on DeviantArt back in 2012, which subsequently went viral. “I’ve been on the site for almost 20 years,” Palmer told me. “I met my long-term partner on DeviantArt in 2009. We live together now.”

    Although Palmer and Southen are not directly involved with the litigation against DeviantArt, they’ve found themselves drawn into the battle for artist rights and protection as generative A.I. swallows up more of their industry. In many cases, the tech eats into creative opportunities once readily available to them and their peers. That goes for everything from big-budget movies to even the opportunity for publicity and revenue offered by online platforms like DeviantArt and even Etsy.

    “Some people I know that use Etsy have basically seen their income dry up entirely over the past 18 months,” Southen said. “Which is really disturbing to see, because what’s happening is they get buried, and then 50 A.I. people all making $300 a month are effectively making it so someone else can’t pay their bills.”

    Why would a site like DeviantArt allow for this—especially when it had once so closely mentored its human users and curated promotional opportunities for them? It seems to have been a long time coming. When it started in 2000, DeviantArt was an early and popular prototype for what we now know as social media, predating the rise of Facebook. It was a casual mixer for artists of all stripes that turned into a serious enterprise as more users across the world logged on to the web throughout the 2000s.

    A Canadian illustrator and educator who’s had a DeviantArt account for 17 years (and preferred to stay anonymous) told me that DeviantArt, in contrast with early art-focused message boards where community members offered substantive feedback, “was more of a place for young up-and-coming amateur artists to post their work and get an ego boost with people commenting, ‘I love it.’ ” Since it also provided a centralized portfolio gallery, it was soon “used as a recruiting tool for art directors and people looking for artists for board games.”

    “DeviantArt was just big enough, and early enough, that it made careers for a lot of people,” Zhang explained.

    By the time streamlined social platforms began to emerge in earnest, the site had trouble catching up. For one, it never branded itself as a place to go professional, and it never intended to be. That role was played by now-dead sites like CGHub, a platform Zhang helped to build, and successors like ArtStation, whose users have also revolted against its A.I. policies. DeviantArt took a different tack by allowing free rein to more friendly interactions and unorthodox drawings. (As Southen bluntly characterized this dynamic: “It became flooded with a lot of really low-effort hentai and porn stuff.”)

    Plus, highly capitalized and mobile app–optimized platforms like Tumblr and Instagram offered more organized feeds with smoother user experiences. “Because Tumblr specifically allowed multiple images per post, it was much easier to showcase comics and image sets,” Palmer said. “Another problem is DeviantArt didn’t have an app for a long time. When that finally launched in 2014, it was just terrible.”

    Not only did DeviantArt lose users and revenue opportunities to the bigger social platforms, but it lost the kingmaking clout it had gained from its early web presence. So it missed out on potentially sizable revenue streams. “It become another one of those places that served more ads and made you pay for a ‘premium’ service, which I did for several years,” the Canadian artist said. The site-building company Wix acquired DeviantArt in 2017 and “relaunched” it two years later with a new design called Eclipse, even though Deviants made clear they’d much preferred the earlier iteration.

    As artists delved more deeply into professional and traditional realms, their DeviantArt accounts remained on the backburner, albeit with a long-reaching effect. “Even these days, when I’m writing about generative A.I. or something about my Luxembourg lawsuit goes viral, people will be like, ‘I recognize your avatar. I used to follow you on DeviantArt 15 years ago when I was a child,’ ” Zhang said. “It’s the only reason I keep the same avatar, so that it helps people to find me.”

    Palmer, who was in so deep with DeviantArt that he’d become friendly with its staff, was awakened to its A.I. efforts in a Twitter Space that DeviantArt executives set up in late 2022, when DreamUp was introduced.

    “Lots of artists were pissed off about it the morning it launched,” he said. “On the Space, the leadership came off looking like bullies—like out-of-touch tech people that just want to make money off this thing. They wanted the artists to be like, ‘This is OK for you to do.’ That burned DeviantArt for a lot of people.” DeviantArt’s social media managers later deleted the tweet on which they’d hosted the Space.

    It wasn’t the first time DeviantArt had incorporated a new tech “innovation” and gotten burned. Look no further than the NFT flood of the early 2020s, which DeviantArt attempted to monetize by offering an exclusive, subscription-based “protection tool” to notify artists when their works got ripped off into salable nonfungible tokens. While DeviantArt could take a cut of proceeds from price-inflated digital apes, it could make even more with small transactional fees from A.I. “works” uploaded quickly and in bulk.

    “Making $25,000 or $12,000 as a DeviantArt user, like those A.I. accounts did, that’s not typical—that’s on the high end for a lot of stuff,” said Southen. “If you have to have almost 10,000 images up and sold to make $25,000, that’s a sheer volume game. It’s not a quality game, and it’s not an interest game.” And these days, it’s a game that’s ever easier to automatically engineer.

    Now artists who made their way into the industry via platforms like DeviantArt are working to figure out how to preserve such avenues for another generation of artists.

    To take it from the publishing industry, A.I. is already decimating once-common job prospects. An April report from the Society of Authors found that 26 percent of the illustrators surveyed “have already lost work due to generative A.I.” and about 37 percent of illustrators “say the income from their work has decreased in value because of generative A.I.”

    There’s little relief to be found in other sectors like gaming, where companies like Activision are already hiring young artists to “polish” generative-A.I. output. Or even in cinema, per the Canadian artist: “I’ve heard stories about companies going all in on A.I. imagery for matte paintings for movies—those sorts of things that used to be done by a digital artist—and then discovering that A.I. can’t take feedback.”

    Jingna Zhang is hoping that—by suing her old home of DeviantArt and in suing Google over its Gemini image generators in a proposed class-action suit she filed with other artists last month—she can center these knotty discussions of artist ownership and copyright. It’s anyone’s guess as to how the DeviantArt suit will go, especially as other litigation continues against these A.I. firms from journalism outfits, actors, and audio narrators. In one promising sign for these plaintiffs, though, the district judge overseeing the case indicated earlier this month that he will likely allow the amended copyright-infringement complaints to proceed to discovery. (He may also dismiss the breach-of-contract charge against DeviantArt, whose attorney continues to argue that the site’s actions constitute “classic fair use.”) Here, Zhang may have help from other advocates like Southen, who’s published results from experiments with Midjourney that have spit out copyright imagery from big-name intellectual property titans like Marvel and DC.

    In the meantime, Zhang has also been running Cara, a volunteer-controlled digital portfolio and social app that explicitly ensures that the work shared there is human-made. Incidentally, one of its users is Angelo Sotira, who co-founded DeviantArt back in 2000. On his most recent post, he wrote that he’s “so sad to see the abandonment of real artists by other platforms in favor of AI generated stuff” and that “it’s so nice to check into Cara and see the soulful communication happening between real artists.”

    This piece has been updated to clarify Jingna Zhang’s early role in the creation of CGHub.

    MediSecure e-script firm hit by ‘large-scale’ ransomware data breach

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-16 18:08:22
    Electronic prescription provider MediSecure in Australia has shut down its website and phone lines following a ransomware attack believed to originate from a third-party vendor. [...]...
    Original Article

    MediSecure e-script firm hit by ‘large-scale’ ransomware data breach

    Electronic prescription provider MediSecure in Australia has shut down its website and phone lines following a ransomware attack believed to originate from a third-party vendor.

    The incident has impacted personal and health information of individuals but the extent remains unclear at this time.

    Operating since 2009, MediSecure provides digital tools to healthcare professionals to manage and dispense medications to patients.

    The company has issued millions of eScripts via its private and the state-backed eRx systems. Until November 2009, it was one of the two two paperless script networks in Australia.

    Today, the company announced that it has been indirectly impacted by a cybersecurity incident on one of its service providers, that has resulted in a data breach.

    “MediSecure has identified a cyber security incident impacting the personal and health information of individuals. We have taken immediate steps to mitigate any potential impact on our systems,” reads the public statement.

    An investigation has started and "early indicators suggest the incident originated from one of our third-party vendors,” the company says.

    The organization has informed key regulators in Australia, including the Office of the Australian Information Commissioner, and is working with the National Cyber Security Coordinator (NCSC) to mitigate the impact of the cyberattack.

    In a short announcement, the Australian NCSC said that "a commercial health information organisation" reported being "the victim of a large-scale ransomware data breach incident."

    “Yesterday afternoon I was advised by a commercial health information organisation that it was the victim of a large-scale ransomware data breach incident. I am working with agencies across the Australian Government, states and territories to coordinate a whole-of-government response to this incident.” – NCSC

    Although MediSecure did not mention a ransomware attack, The Australian Financial Review and ABC [1, 2] report that the company behind the NCSC's announcement was MediSecure.

    The NCSC noted that the investigations is in too early a stage to be able to share any useful details about the impact this cybersecurity incident has on the Australian population.

    The worst healthcare-related data breach incident in Australia’s recent history is that of Medibank that was breached by the REvil ransomware gang in October 2022.

    That breach compromised the information of nearly 9.7 million Medibank and included personally identifiable details, contact, and healthcare data.

    I Don't Want to Spend My One Precious Life Dealing with Google's AI Search

    Hacker News
    aftermath.site
    2024-05-16 18:02:40
    Comments...
    Original Article

    Google’s AI search has arrived, uninvited, to my browser, and I cannot make it leave. It isn’t just that it serves me crap whenever I enter a question into my search bar, but that I have to wait for all the crap I don't want in the first place.

    Let me tell you a story from my day: I was paying invoices, and I wanted to doublecheck that the number of episodes of our podcast, Aftermath Hours, squared with what our producers had billed for. I typed “Aftermath hours spotify” into my browser window, which–depending when I’ve last cleared my history–either autofills the URL for the podcast on Spotify or takes me to Google search results, where our Spotify page is the top result. But now, when I get Google, I have to wait through a nearly three-second pause before AI information about the podcast appears at the top of the page, followed by a link to Spotify and other results. While I appreciate that, in this instance, the AI-generated information about the podcast is correct, this information is not what I’m looking for, and I have to wait three seconds for it to show up just so I can ignore it.

    These three seconds are wrecking me. I’m not one of those lifehacking types who wants to optimize every bit of their day, but that three second wait is just enough friction that I notice it every time. It’s a small annoyance in the moment, but over the course of a day’s queries–any writer or editor can tell you that the number of weird searches you do adds up–that friction starts to build into a drag. I feel like I’m losing chunks of my one and only life waiting for bullshit I didn’t ask for and don’t want to load onto my screen so I can scroll past it. That's something I already deal with when visiting the ad-laden websites Google search brings up; I don’t need a preview! It makes the already unpleasant experience of Google search even worse than it already is.

    Before some stray AI evangelist leaps into the comments to promise the tech will get better, I want to be clear that even if it were instantaneous, I still wouldn’t want it. I didn’t ask for results from the plagiarism machine! My Aftermath colleagues aren’t getting it, so I assume it’s just rolling out to more people this week on the back of Google’s I/O conference. 

    I should, apparently, be able to get around all this by selecting “web” results from the “more” dropdown, but I’m not seeing that option yet–and I assume I’d still have to wait for the AI results to load first. All the instructions for how to disable AI search presume I opted into it, which I very much did not. Plus, Googling “how do I turn AI search off” still gives me AI results; while its answers square with what actual websites tell me, it’s a real 2001: A Space Odyssey vibe. 

    In lieu of being able to turn it off, I’ve been trying to race the AI results, clicking “search” and then scrolling as fast as I can down the page before the AI text appears. While this adds some excitement to my day, it also adds more stress and time crunch to a life that’s already full of it. I don’t want this! I don’t need this. Life is too short.

    Stay in touch

    Sign up for our free newsletter

    Reflex (YC W23) Is Hiring Software Engineers

    Hacker News
    www.ycombinator.com
    2024-05-16 18:00:11
    Comments...
    Original Article

    Web apps in pure Python. Deploy with a single command.

    Software Engineer

    $120K - $200K / 0.25% - 0.75%

    Location

    San Francisco, CA, US

    Connect directly with founders of the best YC-funded startups.

    Apply to role ›

    Alek Petuskey

    About the role

    The Role:

    We’re looking for a fantastic SF/Bay Area-based senior software engineer comfortable working on a very early product in a quickly changing codebase and role. Our office is in San Francisco and we work in person M-F.

    This role will involve working on some of our open-source projects and customer-facing applications. You should be comfortable with a high level of ownership over product decisions and the tech stack.

    Responsibilities:

    • Help optimize and improve our open-source project. Design and implement new features and ensure that Reflex is well-tested and maintained.
    • Collaborate with design, product management, and fellow engineers to build and plan new features
    • Take an active role in the Reflex community by seeking feedback, integrating contributions, and fostering positive and collaborative relationships.

    What We Look for:

    • Very comfortable writing Python.
    • Strong intuition in system design.
    • Passion for open source software and contributing to open source communities.
    • (Nice to have) Strong knowledge of frontend web technologies such as React, JavaScript, HTML, and CSS.

    About the interview

    • The entire process is fully remote; all communication will happen via email and video chat.
    • Once you've submitted your application, the team will review your submission and may reach out for a technical phone screen
    • After the screen, there will be 2-3 technical interviews, each around 45 minutes.
    • The last step is a call with both founders.
    • Once the interviews are over, the team will meet to discuss several roles and candidates and may be asked one or two follow-up questions over email or a quick call or go directly to make an offer.

    About Reflex

    Reflex is an open-source framework to build web apps in pure Python and deploy them with a single command. This can be anything from a small data science/internal app to a large multi-page web app.

    We launched in December and have seen rapid adoption of our open-source framework, with over 14K GitHub Stars and 8500 users on the waitlist for our hosting service. In parallel with improving our open-source framework, we are now working on a hosting service so users can quickly deploy and scale their apps. We have raised 5M in seed funding in August led by Lux Capital with some fantastic founders as angel investors.

    Introduction:https://reflex.dev/docs/getting-started/introduction/ Github: https://github.com/reflex-dev/reflex

    Funding Blog Post: https://reflex.dev/blog/2023-08-02-seed-annoucement/

    Reflex

    Reflex

    Founded:2023

    Team Size:7

    Location:San Francisco

    Founders

    Alek Petuskey

    Nikhil Rao

    [$] The first half of the 6.10 merge window

    Linux Weekly News
    lwn.net
    2024-05-16 18:00:01
    The merge window for the 6.10 kernel release opened on May 12; between then and the time of this writing, 6,819 non-merge commits were pulled into the mainline kernel for that release. Your editor has taken some time out from LSFMM+BPF in an attempt to keep up with the commit flood. Read on f...
    Original Article

    The page you have tried to view (The first half of the 6.10 merge window) is currently available to LWN subscribers only.

    Reader subscriptions are a necessary way to fund the continued existence of LWN and the quality of its content.

    If you are already an LWN.net subscriber, please log in with the form below to read this content.

    Please consider subscribing to LWN. An LWN subscription provides numerous benefits, including access to restricted content and the warm feeling of knowing that you are helping to keep LWN alive.

    (Alternatively, this item will become freely available on May 30, 2024)

    America's dramatic shift from gas power plants to batteries

    Hacker News
    theprogressplaybook.com
    2024-05-16 17:51:37
    Comments...
    Original Article

    Big batteries are eating the lunch of gas-fired power plants in the US, new data shows.

    Gas has long been the technology of choice for balancing America’s power grids and facilitating the shift from coal. In 2023, gas facilities accounted for 43.1% of total utility-scale generation in the country, per the Energy Information Administration (EIA). That’s up from 27.7% just a decade before.

    But recent statistics from the EIA show that developers and power plant owners now overwhelmingly favour batteries as a source of dispatchable power. And the shift has been brisk.

    In 2020, gas plants accounted for 21% of all new electrical capacity brought onto the grid. In 2024, however, the fossil fuel’s share of new additions is expected to slump to 4%, with just 2.5GW of new capacity set to come online — the lowest level in 25 years.

    On the other hand, the share of new battery storage capacity has surged from 1% in 2020 to an anticipated 23% this year, with 14.3GW set to come online.

    Chart: Council of Economic Advisers

    And there are indications that gas’ share of new projects will continue to decline.

    Data collated by Berkeley Lab shows that of the 2.6 terawatts of energy projects seeking grid connections in the US, gas accounts for just 2.6% of potential additions. Standalone batteries, and projects with battery components, comprise nearly two-thirds of the total pipeline.

    Meanwhile, some existing gas-fired power plants are being muscled out, too, as batteries that can take advantage of arbitrage opportunities gain the upper hand on the economic front.

    An 800MW Californian gas plant, commissioned in 2008, was recently demolished to make way for a 680MW, four-hour battery storage system, which will charge up on excess solar power during the day and feed back into the grid when demand and prices are high.

    In the Golden State, batteries already frequently provide more instantaneous power than gas during evening peak periods.

    During the evening of 16 April 2024, big batteries provided 6.2GW of instantaneous power at one point — more than gas. Graphic: California’s independent system operator.

    That’s helping to reduce system costs.

    California’s system operator said recently its ancillary service costs in the third quarter of 2023 were down 45% from a year before partly thanks to the “increased participation of battery storage resources.”

    “This stunning growth in battery deployment means that moving forward, utilities will be able to bring online even more renewable energy — such as solar or wind — without relying as much on natural gas,” the Council of Economic Advisers, an agency that advises the US president, said in a new analysis.

    It referenced EIA data showing that through 2024, wind, solar and batteries will account for 94% of all new electrical capacity in the US. Nuclear will comprise another 2% of total additions.

    Yes, but: There remains a long way to go to decarbonise the US power system.

    In 2024, gas will likely hold a 42% share of the electricity mix, followed by renewables at 24%, nuclear at 19%, and coal at 15%, the EIA says.

    The US government aims to get to 80% renewable-based electricity by 2030, and a 100% carbon-free power system by 2035.

    “While there is still plenty of existing fossil fuel capacity across the US, this increase in new capacity from battery storage is an important milestone toward a fully clean power grid,” the Council of Economic Advisers says.

    The council credits the Inflation Reduction Act for galvanising the shift to solar, wind and batteries.

    Among other things, the legislation provides generous investment tax credits for utility-scale battery storage systems.

    Since it came into law, domestic manufacturing investments in battery production — for both grid scale and EV batteries — have increased from $2.3 billion to $9.9 billion, according to the Clean Investment Monitor.

    “These policies will supercharge battery deployment in the coming years, particularly as two ongoing trends continue to increase the demand for batteries,” the Council of Economic Advisers says.

    “First, increasing electrification of the economy, from electric vehicles to heat pumps, is increasing electricity demand for the first time in over a decade.

    “Second, even without increases in overall electricity demand, there are moments in places such as in California and Texas where excess supply of zero-carbon, zero-marginal cost renewable electricity must be turned away from the grid. This curtailment of renewable energy is expected to grow. Batteries can absorb excess clean power, simultaneously meeting greater electricity demand and enabling accelerated power sector decarbonisation.”

    Love Letter To the Student Encampments for Palestine

    OrganizingUp
    convergencemag.com
    2024-05-16 17:46:50
    Dear courageous students for a…...
    Original Article
    by
    and
    Article published:
    Grayscale cutout of small tents on the ground with a banner reading, "Gaza Solidarity Encamptment" across them. Background is orange with a confetti of black and white outline hearts.

    The participants in the student encampments “have rejuvenated us after months of militant protest, taking bold action for our transgenerational, collective vision of liberated peoples and lands across the world.”

    Dear courageous students for a free Palestine,
    In Spring 1985, when UC Berkeley students pitched their tents on the steps of Sproul Plaza to demand the University of California divest from apartheid South Africa, they felt the same struggles and grappled with the same contradictions that you do today. To be real, shit gets dark when you’re in the trenches. We know you are overwhelmed and underslept. We know that connections with others can feel tenuous when we exist in a surveillance state and political battlefield. But here’s the truth: The world is shifting thanks to you. Please keep going. We got you.

    As young people in this time on this Earth, you have the power and the spirit to move millions of people and win material victories. For generations, student movements have dared to face off against the Herculean power of colonial institutions and state-sponsored military force, changing the course of history. Right now you are at the frontlines of our intergenerational battle for a free Palestine—for collective liberation—yet the rest of us must also meet the moment to fortify your movement. 

    In the Bay Area and in many places across Turtle Island, movement elders and experienced organizers have faced these same threats before. Students, we honor your leadership and stand ready to support you in all the ways you need, from political education to healing resources to hot meals. And across imaginary borders, even when encampments are dismantled, remember that mycelial networks stretch between every student movement—from UC Berkeley to San Francisco State University (SFSU), from UCLA to Columbia, from the Sorbonne to the University of Sydney—to replenish resources, knowledge, and spirit.

    The Third World Liberation Front (TWLF) strikes of 1968, initiated by a coalition of Black, Latinx, Chicanx, Filipinx, Native American, Chinese, and Asian American students at San Francisco State College and UC Berkeley, were among the longest student strikes in US history—and are the reason the schools have ethnic studies today. Lasting a total of five months, the San Francisco State strike was sustained because the students’ families and community members showed up day in and day out, feeding the people, providing mental health support, keeping each other safe, sharing tactics, exchanging culture, and more.

    More than 140 student encampments across Turtle Island have not only righteously demanded divestment from Israeli apartheid and freedom from political repression; they have also given communities an opportunity to practice the experiment of collective governance, rooted in true democracy, that we need in order to embody the liberatory futures we’re building. Collective governance is not the air we breathe normally, but we do have the skills to do it; in fact, we’re always doing it. In the moments when we bring our friends soup when they’re sick, or divide up our chores, or help each other problem solve when things don’t go as planned—we’re practicing collective governance. And we need to resource ourselves by reclaiming our own labor to do it at scale.

    Not only do we have the lived experience of collective governance, but we also have genetic memory of it. Our ancestors practiced it long before our lands and peoples were colonized. While colonization and racial capitalism have continually tried to force us to abandon ourselves, each other, and our relationships with the lands and waters—we are still here fighting for our people and our lands after all this time. Justimagine the ancestral knowledge and intergenerational healing we’ll activate as we remember the practice of collective governance through caring for one another.

    As we watch the genocide in Palestine and invasion of Rafah being livestreamed and show up week after week to mass mobilizations and direct actions, it can feel as though we are losing our minds and our spirits. Our relationships and our bodies are dysregulated and stressed to the max. But remember that we do have each other. We draw inspiration from the Muslim and Jewish and other allied students who are protecting one another and creating deep community across cultural fronts. They remind us that our target is not Jewish, Muslim, Arab, or Palestinian identity; it is the US-backed apartheid system created by Israel and the political ideology and colonial project of Zionism.

    We will continue to struggle through difference, and we can do so in principled and disciplined ways. Living into the culture shift that we’re trying to move is what will actually get us to liberation. Right now, you, the students, are primed to make this shift. It will be a lifelong commitment, and a worthy one.

    Back to 1985 and the struggle against apartheid in South Africa: After holding camp for six weeks, UC students won, forcing the UC system to divest $3 billion from South Africa-related stock holdings. By 1990, anti-apartheid leader Nelson Mandela was freed from prison and the formal process to end apartheid began. Boycotts and divestments played a key role in advancing this victory.

    Courageous students, you have rejuvenated us after months of militant protest, taking bold action for our transgenerational, collective vision of liberated peoples and lands across the world. Thank you for all the ways you are showing up. Please keep going. We got you. Palestine will be free in our lifetime.

    Love,
    Movement Generation

    This letter is presented by Movement Generation co-founders Carla María Pérez and Mateo Nube on behalf of the MG collective.

    Mateo Nube

    OrganizingUp
    convergencemag.com
    2024-05-16 17:38:36
    Mateo Nube is a co-founder,…...
    Original Article

    Convergence is a magazine for radical insights. We produce articles, videos, and podcasts to sharpen our collective practice, lift up stories about organizing, and engage in strategic debate — all with the goal of winning multi-racial democracy and a radically democratic economy.

    Carla María Pérez

    OrganizingUp
    convergencemag.com
    2024-05-16 17:34:44
    Carla María Pérez is a co-founder,…...
    Original Article

    Convergence is a magazine for radical insights. We produce articles, videos, and podcasts to sharpen our collective practice, lift up stories about organizing, and engage in strategic debate — all with the goal of winning multi-racial democracy and a radically democratic economy.

    Using Llamafiles for Embeddings in Local RAG Applications

    Hacker News
    future.mozilla.org
    2024-05-16 17:20:03
    Comments...
    Original Article

    A good text embedding model is the lynchpin of retrieval-augmented generation (RAG). Given the computational cost of indexing large datasets in a vector store, we think llamafile is a great option for scaleable RAG on local hardware, especially given llamafile's ongoing performance optimizations.

    To make local RAG easier, we found some of the best embedding models with respect to performance on RAG-relevant tasks and released them as llamafiles. In this post, we'll talk about these models and why we chose them. We'll also show how to use one of these llamafiles to build a local RAG app.

    Note: This post only covers English-language models. Some of them might be multi-lingual but we did not take into account performance on non-English tasks when finding models to recommend.

    Model License Memory Usage (GP, fp32) Embedding Size
    Best overall Salesforce/SFR-Embedding-Mistral CC-by-NC 26.49 4,096
    Best overall, commercial-friendly license intfloat/e5-mistral-7b-instruct MIT 26.49 4,096
    Best small mixedbread-ai/mxbai-embed-large-v1 Apache 2 1.25 1,024

    Best overall: Salesforce/SFR-Embedding-Mistral (llamafile link). Why does it work so well? They carried out additional, multi-task finetuning on top of intfloat/e5-mistral-7b-instruct using the training datasets of several tasks in the Massive Text Embedding Benchmark (MTEB). For more details, see their blog post.

    Best overall, commercial-friendly license: intfloat/e5-mistral-7b-instruct (llamafile link). Why does it work so well? Synthetic data generation. The authors finetune mistral-7b-instruct on various synthetic text embedding datasets generated by another LLM. For more information, see their paper.

    Best small: mixedbread-ai/mxbai-embed-large-v1 (llamafile link). Why does it work so well? Data building and curation. The authors scraped and curated 700 million text pairs and trained a BERT model using contrastive training. Then, they finetuned the model on an additional 30 million text triplets using AngIE loss. For more information, see their blog post.

    Which embedding model should I use?

    The embedding model you should pick for your app depends on a variety of factors:

    Model size and memory constraints: The larger models require more memory and are slower, so if you have lots of memory available, go with SFR-Embedding-Mistral or e5-mistral-7b-instruct. Otherwise, go with the smaller mxbai-embed-large-v1. In addition, if you have limited indexing time or you have a very large collection of documents to index, a smaller model will get the job done much faster.

    Document length: You should also consider the type of data you'd like to "store" in your embeddings. The larger models have a longer max sequence length, so they can stuff a longer document into an embedding. Smaller models tend to be more suited to short texts like a sentence or maybe a paragraph. (However, if you're memory-bound and want to use a smaller model to index longer documents, you can just snippetize the docs into smaller pieces.) In this post, we did not specifically look at model performance by text length, so if you're looking for a model for long documents, you may have to go through your own evaluation process.

    Generation model size: Also note that you may have to use a separate model or llamafile for the 'generation' part of RAG. mxbai-embed-large-v1 does not generate text at all (in fact, you'll get an error if you attempt this) and, since the larger models were fine-tuned specifically for embedding tasks, their generation capabilities might be somewhat worse than a model tuned for text generation. You may need to account for this when choosing a model. You'll need enough memory available for both the embedding model and the text generation model, assuming you'll be running them on the same machine.

    We'll also mention that the authors of the MTEB benchmark--a widely-used embeddings benchmark suite described in more detail below--wrote a great companion guide to using their leaderboard for model selection. Their post provides a lot more detail about the model selection process than we do here and is an excellent guide to choosing an embedding model for your specific task/data. We highly recommend reading that so you can decide whether the models we recommend are actually right for your use case.

    How do I use these llamafiles in my RAG app?

    Llamafile is now integrated with two popular RAG app development frameworks:

    We recommend getting familiar with one of these two frameworks via their respective quickstart guides, then following the llamafile-specific documentation at one of the links above.

    In addition to the higher-level libraries above, we've provided a very minimal example of a local RAG app using llamafile here.

    How did we choose these models? The short version...

    As our starting point, we looked at the Massive Text Embedding Benchmark (MTEB) leaderboard, which evaluates models across a diverse battery of tasks that use text embeddings in various ways. The benchmark includes 7 task categories: classification, pair classification, clustering, reranking, retrieval, semantic textual similarity (STS), and summarization. Each task category is associated with a collection of datasets, e.g. the retrieval task includes datasets like MS MARCO and QuoraRetrieval. Models are evaluated on each dataset, then model scores are aggregated by task category. The final leaderboard ranking is determined by the average model score across all task categories.

    However, you might notice that the models we recommend above are different from the top-ranked models according to this leaderboard. This is because we made two modifications during our selection process.

    First, we filtered the results to include only "RAG-relevant" MTEB task categories that test embeddings in a scenario similar to how they might be used in a RAG application, where you need to retrieve text snippets related to a query from a vector store. We kept results related to clustering, reranking, retrieval, and semantic textual similarity (STS) and ignored results related to classification, pair classification, and summarization.

    Second, we used a different metric to determine the overall ranking of models in the leaderboard. While the MTEB leaderboard (and many others) rank according to average model score across tasks, we instead determine the final ranking using mean task rank, or MTR. Essentially, instead of averaging across raw model score on each task, we rank each model on each MTEB dataset, then take the average across those ranks to get the model's MTR.

    Why? In brief: Each task category uses its own metric, so model scores on different datasets don't necessarily have the same "units". STS scores tend to fall around 80 whereas retrieval task scores are much lower, in the mid-50s. Since scores on different task types/datasets are not necessarily commensurate, it doesn't make a lot of sense to average across them. So, instead of averaging across raw model scores, we average across model rank. This essentially maps all the scores into the same shared "unit". We didn't come up with this ourselves: This follows the advice for multiple comparisons across multiple datasets detailed in Statistical Comparisons of Classifiers over Multiple Data Sets (Demšar, 2006). For a longer explanation of this process, see the Appendix.

    After these two changes, our top-10 leaderboard looks like:

    Rank Model RAG MTR% RAG Average (40 datasets) Clustering Average (11 datasets) Reranking Average (4 datasets) Retrieval Average (15 datasets) STS Average (10 datasets)
    1 SFR-Embedding-Mistral 5.72 63.66 51.67 60.64 59.00 85.05
    2 e5-mistral-7b-instruct 9.92 62.33 50.26 60.20 56.89 84.63
    3 voyage-large-2-instruct 10.23 63.68 53.35 60.09 58.28 84.58
    4 GritLM-7B 11.91 62.33 50.61 60.49 57.41 83.35
    5 mxbai-embed-large-v1 14.08 60.51 46.71 60.11 54.39 85.00
    6 GritLM-8x7B 14.49 61.24 50.14 59.80 55.09 83.26
    7 UAE-Large-V1 14.74 60.47 46.73 59.88 54.66 84.54
    8 voyage-lite-02-instruct 14.87 62.91 52.42 58.24 56.60 85.79
    9 google-gecko.text-embedding-preview-0409 15.12 61.10 47.48 58.90 55.70 85.07
    10 GIST-large-Embedding-v0 15.71 59.99 46.55 60.05 53.44 84.59

    You can see our full, revised leaderboard here.

    To make our final recommendations, we 1) eliminated the closed-source models (only the voyage and google-gecko models made it into the top 10) and 2) restricted our list to models whose architecture is compatible with the gguf file format (see also: here and here), which llamafile requires.

    Conclusion

    We hope this post was helpful for getting started with llamafiles and embeddings.

    For reference, here are some of the links referenced in this post:

    If you have questions or feedback, reach out to us on Discord.

    References

    @article{demvsar2006statistical,
      title={Statistical comparisons of classifiers over multiple data sets},
      author={Dem{\v{s}}ar, Janez},
      journal={The Journal of Machine learning research},
      volume={7},
      pages={1--30},
      year={2006},
      publisher={JMLR. org}
    }
    @article{muennighoff2022mteb,
        doi = {10.48550/ARXIV.2210.07316},
        url = {https://arxiv.org/abs/2210.07316},
        author = {Muennighoff, Niklas and Tazi, Nouamane and Magne, Lo{\"\i}c and Reimers, Nils},
        title = {MTEB: Massive Text Embedding Benchmark},
        publisher = {arXiv},
        journal={arXiv preprint arXiv:2210.07316},  
        year = {2022}
    }
    

    Appendix

    How did we choose these models? The long version...

    Now, you might say: "Why did you write such a long post about this? What's the problem? Just use SFR-Embedding-Mistral, it's right there at the top!" In the end, you'd be right, but for the wrong reasons.

    As the MTEB authors note, "Does [the leaderboard] make it easy to choose the right model for your application? You wish!" What they meant was, while this leaderboard is a great way to see embedding quality in general, it doesn't necessarily make it obvious which model is best for your specific application.

    One problem is simply the complexity of the leaderboard, which is actually a good problem! The MTEB benchmark includes hundreds of datasets grouped into 7 broad task categories: classification, clustering, pair classification, reranking, retrieval, semantic textual similarity (STS), and summarization. Some of these task categories--e.g. retrieval, STS--test embeddings in a scenario similar to how they might be used in a RAG application, where you need to retrieve text snippets related to a query from a vector store. Others, like classification, do not. So, looking at overall performance on MTEB tells us a lot about embedding quality in general but the best overall model is not necessarily the best model for RAG applications.

    Here's the top-10 leaderboard showing rank by mean performance across tasks side-by-side with rank by mean performance across RAG-related tasks only:

    Model rank by avg rank by rag avg avg rag avg
    voyage-large-2-instruct 1 1 68.28 63.68
    SFR-Embedding-Mistral 2 2 67.56 63.66
    gte-Qwen1.5-7B-instruct 3 3 67.34 63.06
    voyage-lite-02-instruct 4 4 67.13 62.91
    GritLM-7B 5 5 66.76 62.33
    e5-mistral-7b-instruct 6 6 66.63 62.33
    GritLM-8x7B 8 7 65.66 61.24
    gte-large-en-v1.5 9 8 65.39 61.11
    google-gecko.text-embedding-preview-0409 7 9 66.31 61.10
    LLM2Vec-Meta-Llama-3-supervised 10 10 65.01 60.87

    There isn't much difference until we get to ranks 7, 8, and 9.

    However, there is a second problem with the MTEB leaderboard: regardless of which task subset you use, models are ranked according to their average performance across those tasks. The model with the highest average score across tasks wins. This is a very common way of ranking multiple models across multiple datasets, but just because it's a common method doesn't mean it's a good method.

    Here is average model performance for each task type in the RAG subset:

    Model rag avg clustering avg reranking avg retrieval avg STS avg
    voyage-large-2-instruct 63.68 53.35 60.09 58.28 84.58
    SFR-Embedding-Mistral 63.66 51.67 60.64 59.00 85.05
    gte-Qwen1.5-7B-instruct 63.06 55.83 60.13 56.24 82.42
    voyage-lite-02-instruct 62.91 52.42 58.24 56.60 85.79
    GritLM-7B 62.33 50.61 60.49 57.41 83.35
    e5-mistral-7b-instruct 62.33 50.26 60.21 56.89 84.63
    GritLM-8x7B 61.24 50.14 59.80 55.09 83.26
    gte-large-en-v1.5 61.11 47.96 58.50 57.91 81.43
    google-gecko.text-embedding-preview-0409 61.10 47.48 58.90 55.70 85.07
    LLM2Vec-Meta-Llama-3-supervised 60.87 46.45 59.68 56.63 83.58

    As you can see, there is a lot of variation in the magnitude of scores across the different tasks. STS scores tend to be in the low 80s whereas clustering scores tend to be the high 40s/low 50s. Does it really make sense to average across these numbers?

    Note that each task has its own metric. STS uses the Spearman correlation coefficient whereas retrieval uses NDCG@10 (the MTEB paper lists them all). While all of these task metrics are technically bounded by the range [0, 1], the actual scores models get for these metrics aren't going to be spread across that interval the same way.

    Here are the descriptive statistics for the distribution of model scores on the STS and retrieval tasks:

    STS   Retrieval
    count 155   133
    mean 79.26   44.93
    std 5.86   10.97
    min 39.10   7.94
    25% 78.08   41.17
    50% 80.84   48.48
    75% 82.58   51.99
    max 85.79   59.00

    In other words, a good average score on the STS is ~83 and a good average score on the Retrieval task is ~52.

    Now let's say we have two models, Model A and Model B, that get the following scores on these two tasks:

    STS
    Score
    Retrieval
    Score
    Average  Rank
    Model A  82.58 (75%)  41.17 (25%)  61.88  2
    Model B  78.08 (25%)  51.99 (75%)  65.04  1

    Model A is good at STS but bad at retrieval; Model B is bad at STS but good at retrieval. Importantly, they are each equally good at one task and equally bad at the other. However, when we rank according to average score, Model B wins. In effect, this ranking method prioritizes the retrieval task over the STS task. This seems pretty arbitrary, since presumably we care about performance on all tasks equally.

    So, what's the alternative? In Statistical comparisons of classifiers over multiple data sets., Janez Demšar recommends using the non-parametric Friedman test to ascertain whether there is a statistically-significant difference among a set of classifier scores on a set of datasets. The first step of this test is ranking each model on each dataset, then finding the average rank of each model across the tasks. We refer to this metric as mean task rank, or MTR.

    To illustrate how to compute MTR, we'll go back to our toy example above. Model A is ranked 1st on STS and 2nd on retrieval. Model B is ranked 2nd on STS and 1st on retrieval. To compute MTR for Model A, we take the average (1+2)/2 = 1.5, and likewise for Model B. Then, we rank the entire table with respect to MTR.

    STS
    Score
     STS
    Rank
     Retrieval
    Score
     Retrieval
    Rank
     MTR   Rank by MTR
    Model A  82.58   1  41.17   2 1.5   1.5
    Model B  78.08   2  51.99   1 1.5   1.5

    Now, Model A and Model B tie, which (at least to me) seems like a more accurate outcome than the version where Model B won.

    • llamafile
    • LLM
    • RAG

    We've All Felt It

    Hacker News
    www.raycast.com
    2024-05-16 17:18:32
    Comments...
    Original Article

    You look up at the clock, realizing hours have flown by because you’ve lost yourself in work. When the day ends, you feel happy, knowing you spent your time deliberately. This is Flow: the perfect state of productivity. But most of us reach this state far too seldom.

    While it’s easy to blame social media, the apps we use for work can be just as distracting. Switching between apps and contexts adds up when we’re at our computers for eight hours a day. Simple actions turn into long series of clicks, causing us to forget our intentions. Since these tools are for work, turning them off isn’t an option.

    But what if you could check your notifications without an app pushing them onto you? Update your Slack status, without getting sidetracked by #random? View your top todos, without getting overwhelmed by all your do-it-laters? Or look up an answer, without loosing yourself in the internet?

    Say hello to Raycast,your shortcutto everything.

    It allows you to get anything done from anywhere on your Mac, from adding to-do’s to asking AI. A new way of experiencing your computer, where distractions aren’t just easier to resist but are completely out of sight.

    Once you start thinking outside the app, almost anything is possible. From getting your windows in place, to jotting down notes during calls. Or taking actions in Slack, Spotify, GitHub, and all your favorites apps — without even opening them. It’s a fresh way of thinking that takes some getting used to. But once you get it, you can never go back. It’s not even about saving time... It’s about never wasting it.

    Raycast is inspired by early command line interfaces, where you could take any action without the distractions. In this way, it’s a timeless computing vision, reimagined for the modern age.

    The choice is yours: continue clicking through life or take the short way.

    Photobox – Free Open Source Google Photos Clone

    Hacker News
    www.photobox.dev
    2024-05-16 17:07:15
    Comments...
    Original Article

    Photo library and interactive editor built with Next.js

    Get StartedView on GitHub

    Or check out the demo.

    Photobox media library

    Create a new Photobox

    npx create-next-app@latest -e https://github.com/cloudinary-community/photobox photobox

    Or deploy your new library!

    Deploy to Vercel

    Give New Life to Your Memories

    Use Photobox Creations to create Collages, Animations, and more built on top of Cloudinary transformations to give a new experience to your images.

    Collage with Thailand, Arizona, and Rio de Janiero

    Collage with Thailand, Arizona, and Rio de Janiero

    Your Photos, Your Library

    Gain control over how your images are stored using Cloudinary's as the host for all of your images.

    Create Your Photobox

    Get StartedView on GitHub

    Mummy Brown

    Hacker News
    en.wikipedia.org
    2024-05-16 17:05:48
    Comments...
    Original Article

    From Wikipedia, the free encyclopedia

    Mummy brown

    A tube of mummy brown in a coffin

    About these coordinates     Color coordinates
    Source[Unsourced]

    Mummy brown, also known as Egyptian brown or Caput Mortuum,[1]: 254 [2] is a rich brown bituminous pigment with good transparency, sitting between burnt umber and raw umber in tint.[3] The pigment was made from the flesh of mummies mixed with white pitch and myrrh.[4][5] Mummy brown was extremely popular from the mid-eighteenth to the nineteenth centuries. However, fresh supplies of mummies diminished, and artists were less satisfied with the pigment's permanency and finish.[2] By 1915, demand had significantly declined.[6] Suppliers ceased to offer it by the middle of the twentieth century.[7]: 82 

    Mummy brown was one of the favourite colours of the Pre-Raphaelites.[6] It was used by many artists, including Eugene Delacroix, William Beechey, Edward Burne-Jones, Lawrence Alma-Tadema, and Martin Drolling.[2]

    History[edit]

    Before "mummy brown" was used as a pigment, Egyptian mummies were known for their medicinal qualities. People used materials derived from mummies to treat a wide range of medical complaints, from toothaches to dysentery.[2]

    In the 16th and 17th centuries, people began producing pigment from mummies. The pigment was made from the flesh of Egyptian mummies or Guanche mummies of Canary Islands (both human and feline),[8][9] mixed with white pitch and myrrh.[4][5] The earliest record of the use of mummy brown dates back to 1712 when an artist supply shop called "À la momie" in Paris sold paints, varnish, and powdered mummy.[2] In 1797, a Compendium of Colours published in London proclaimed that the finest brown used as a glaze by Benjamin West, the president of the Royal Academy, "is the flesh of mummy, the most fleshy are the best parts."[7]

    The pigment was popular from the mid-eighteenth to the nineteenth centuries. However, the demand for mummy brown sometimes exceeded the available supply of true Egyptian mummies, leading to occasional substitution of contemporary corpses of enslaved people or criminals.[1]: 254  By 1849, it was described as being "quite in vogue."[2]

    Towards the end of the nineteenth century, mummy brown began to fall out of popularity. Fresh supplies of mummies diminished, and artists were less satisfied with the pigment's permanence and finish.[1]: 255 [10] The Pre-Raphaelite artist Edward Burne-Jones was reported to have ceremonially buried his tube of mummy brown in his garden when he discovered its true origins.[1]: 255 [2]

    By 1915, demand for mummy brown had slowed so much that one London colourman claimed he could satisfy his customers' requests for twenty years from a single Egyptian mummy.[6] By the start of the 20th century, mummy brown had largely ceased production in its traditional form due to a continued decline in the supply of available mummies as well as a significant drop in demand.[1]: 255 [6]

    Today, mummy brown cannot be bought from any paint shop. In 1964, Time magazine reported that the sole distributor of the pigment, London colourmaker C. Roberson, had run out of mummies a few years prior.[7]: 82  A tube of mummy brown pigment purchased from Roberson in early 1900s is on display at the Forbes Pigment Collection of the Harvard Art Museum.[11]

    Brown plate
    Mummy brown is shown on the catalog with other browns for comparison

    Visual characteristics[edit]

    Ancient mummy brown is a rich brown pigment with a warm vibrancy. The colour is intermediate in tint between burnt umber and raw umber.[3] It has good transparency. It could be used in oil paint and watercolour for glazing, shadows, flesh tones, and shading.[2]

    The modern equivalent sold as "mummy brown" is composed of a mixture of kaolin, quartz, goethite, and hematite, with the hematite and goethite (generally 60% of the content) determining the colour. The more hematite, the redder the pigment, while the others are inert substances that can vary the opacity or tinting strength.[12] The colour of mummy brown can vary from yellow to red to dark violet, the latter usually called "mummy violet".[12]

    Permanence[edit]

    Mummy brown exhibits poor permanence. It fades easily and cracks when used alone.[13] However, when mixed with oil paints, it dries and the tendency to crack is diminished.[2] It was also extremely variable in its composition and quality, and since it contained ammonia and particles of fat, it was likely to affect other colors it was used with.[14]

    Notable occurrences[edit]

    Interior of a Kitchen
    Martin Drolling's Interior of a Kitchen is believed to have been painted with an extensive use of mummy brown[3]

    Many artists, including Eugene Delacroix, William Beechey, Edward Burne-Jones, Lawrence Alma-Tadema, and Martin Drolling, are thought to have used mummy brown in their palettes.[2] However, few works have been tested for its presence because the process is destructive.[3]

    Some popular paintings included in previous articles and research papers are thought to have been painted with mummy brown based on their visual characteristics. Examples include the Last Sleep of Arthur in Avalon by Edward Burne-Jones, Interior of a Kitchen by Martin Drolling, and Liberty Leading the People by Eugene Delacroix.[3]

    Liberty Leading the People
    Eugene Delacroix' Liberty Leading the People is claimed to have been painted with mummy brown because Delacroix was "known to have used pigment made from ground mummy."[3]
    Last Sleep of Arthur in Avalon
    Edward Burne-Jones' Last Sleep of Arthur in Avalon was probably drawn using mummy brown[3]

    See also[edit]

    Notes[edit]

    1. ^ a b c d e St. Clair, Kassia (2016). The Secret Lives of Colour. London: John Murray. pp. 253–255. ISBN 978-1473630819. OCLC 936144129.
    2. ^ a b c d e f g h i j McCouat, Philip, "The life and death of Mummy Brown" Archived 2013-10-14 at the Wayback Machine, Journal of Art in Society
    3. ^ a b c d e f g "The corpse on the canvas: the story of 'mummy brown' paint | Art UK". artuk.org. Retrieved 2023-04-13.
    4. ^ a b Tom, Scott (18 March 2019). "The Library of Rare Colors". Archived from the original on 8 May 2019. Retrieved 8 May 2019 – via YouTube.
    5. ^ a b Adeline, Jules; Hugo G. Beigel (1966). The Adeline Art Dictionary. F. Ungar Pub. Co.
    6. ^ a b c d "The Passing of Mummy Brown". Time. 1964-10-02. Archived from the original on 2008-11-23.
    7. ^ a b c Finlay, Victoria (2014). The Brilliant History of Color in Art. Los Angeles, CA: J. Paul Getty Museum. pp. 81–82. ISBN 978-1606064290.
    8. ^ Vallvé, David Sentinella (2010). El enigma de las momias: Claves históricas del arte de la momificación en las antiguas civilizaciones (in Spanish) (Ediciones Nowtilus S.L. ed.). Ediciones Nowtilus. ISBN 978-8497633468. Archived from the original on 2020-10-09. Retrieved 2019-12-28.
    9. ^ Godfraind-De Becker, Anne. Utilisations des momies de l'antiquité à l'aube du XXe siècle. Revue des questions scientifiques, 2010, vol. 181, no. 3, pp. 305–340. https://www.unamur.be/sciences/philosoc/revueqs/textes-en-ligne/RQS_181_3momies.pdf Archived 2019-05-05 at the Wayback Machine
    10. ^ Church, A. H. (1901). The Chemistry of Paints and Painting. London: Seeley and Co.
    11. ^ R. Leopoldina Torres. "A Pigment from the Depths | Index Magazine | Harvard Art Museums". harvardartmuseums.org. Retrieved 2023-04-14.
    12. ^ a b "Mummy Brown". naturalpigments.com. Archived from the original on 2004-08-16. Retrieved 2008-02-08.
    13. ^ Eveleth, Rose. "Ground Up Mummies Were Once an Ingredient in Paint". Smithsonian Magazine. Retrieved 2023-04-13.
    14. ^ Field, George (2008). Field's Chromatography. BiblioBazaar, LLC. pp. 254–255. ISBN 978-1434669612.

    References[edit]

    Look up mummy brown in Wiktionary, the free dictionary.

    Build WebGPU Apps Today with PlayCanvas

    Hacker News
    blog.playcanvas.com
    2024-05-16 17:04:47
    Comments...
    Original Article

    It's here! 🥳 Today, we're excited to announce that WebGPU support has officially arrived in the PlayCanvas Editor.

    Editor with WebGPU Scene

    WebGPU on the Rise

    Since its inception back in 2010, PlayCanvas has been layered on top of WebGL. In 2017, we were proud to launch support for WebGL 2.0 in partnership with our friends at Mozilla. April 2023 marked the beginning of a new era for web graphics when Google enabled WebGPU by default in Chrome 113. Since then, WebGPU adoption has exploded and today, Web3D Survey reports that 62.19% of end users can now run WebGPU. With Firefox and Safari due to launch their WebGPU support in the not-too-distant future, expect this number to rise dramatically in 2024.

    Why WebGPU Matters

    If you enable WebGPU for your PlayCanvas project, you may not notice much difference to begin with. In fact, we have put a great deal of effort into ensuring your WebGL projects look identical under WebGPU. But over time, there is are a great deal of opportunities to achieve performance improvements due to WebGPU's reduced driver overhead.

    Another key feature unique to WebGPU is support for Compute Shaders which allow for general computation on the GPU. Support for Compute Shaders landed in Engine v1.70.0. Here you can see Computer Shaders in action simulating 1 million particles on the GPU:

    Click here to run it for yourself in a WebGPU-enabled browser (i.e. Chrome or Edge).

    In short, WebGPU represents the future for PlayCanvas and you can expect some incredible advances in performance and functionality over the coming months.

    Getting Started with WebGPU

    WebGPU support in PlayCanvas is still considered 'Beta'. There are still some unimplemented features (for example, the run-time lightmapper is still not supported). Therefore, you have to currently 'opt in' to WebGPU support. To do this, open your Project's Settings in the Inspector and expand the RENDERING section. Then update Graphics Devices to include WebGPU (beta).

    Editor with WebGPU Scene

    Once we are satisfied WebGPU support has matured enough, it will become the default.

    Your Feedback is Important

    Since WebGPU support is new, we rely on the community for feedback. What works and what doesn't? Please submit an issue if you discover any problems or kick off a new thread on the forum if you want to discuss WebGPU support in more detail. We want to hear what your opinions! 👂

    Neovim 0.10 released

    Linux Weekly News
    lwn.net
    2024-05-16 17:03:22
    Version 0.10 of the Vim-based text editor Neovim is now available. This release includes a new default color scheme, enhanced support for rendering multibyte characters, support for hyperlinks, system clipboard synchronization, and more. Many features have been deprecated in 0.10 and will be removed...
    Original Article

    Version 0.10 of the Vim-based text editor Neovim is now available. This release includes a new default color scheme, enhanced support for rendering multibyte characters, support for hyperlinks, system clipboard synchronization, and more. Many features have been deprecated in 0.10 and will be removed in future release. Neovim core contributor Gregory Anders has written a summary of some of the highlights and thoughts on upcoming releases:

    We follow a "fun driven development" paradigm: for the most part, contributors and maintainers work on things that are personally interesting to them. Because of this, it can be difficult to predict what will happen in future releases. If there is a feature you want to see implemented, the best way to do it is to take a crack at it yourself: many of the features mentioned in this very blog post were contributed by users that are not part of the "core" maintenance team!


    (Log in to post comments)

    Russian hackers use new Lunar malware to breach a European govt's agencies

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-16 16:57:15
    Security researchers discovered two previously unseen backdoors dubbed LunarWeb and LunarMail that were used to compromise a European government's diplomatic institutions abroad. [...]...
    Original Article

    Russian hackers use new Lunar malware to breach a European govt's agencies

    Security researchers discovered two previously unseen backdoors dubbed LunarWeb and LunarMail that were used to compromise a European government's diplomatic institutions abroad.

    The pieces of malware have been used to breach the Ministry of Foreign Affairs of a European country with diplomatic missions in the Middle East and have been active since at least 2020.

    Researchers at cybersecurity company ESET believe that the backdoors may be connected to the Russian state-sponsored hacker group Turla, although attribution has medium confidence at this point.

    Lunar attack chain

    In its report, ESET says that the attack starts with spear-phishing emails that carry Word files with malicious macro code to install the LunarMail backdoor onto the target system.

    The VBA macro also establishes persistence on the infected host by creating an Outlook add-in, ensuring it is activated whenever the email client is launched.

    Malicious Outlook add-in
    Malicious Outlook add-in
    Source: ESET

    ESET analysts have also seen evidence pointing to the potential abuse of a misconfigured open-source network monitoring tool Zabbix to drop the LunarWeb payload.

    Specifically, a component mimicking a Zabbix agent log is deployed on a server, and when accessed with a specific password via an HTTP request, it decrypts and executes the loader and backdoor components.

    LunarWeb persists on the breached device using several techniques that include creating Group Policy extensions, replacing system DLLs, and deploying as part of legitimate software.

    Both payloads are decrypted by a malware loader that the researchers called ‘LunarLoader’ from an encrypted blob using the RC4 and AES-256 ciphers. The loader uses the DNS domain name for decryption and ensures that it runs only within the targeted environment.

    Once the Lunar backdoors are running on the host, the attackers may send commands directly via the command and control (C2) server and use stolen credentials and compromised domain controllers for lateral movement on the network.

    The two infection chains seen in the campaign
    The two infection chains seen in the campaign
    Source: ESET

    LunarWeb and LunarMail

    The two Lunar backdoors are designed for prolonged and covert surveillance, data theft, and maintaining control over compromised systems, such as high-value targets like government and diplomatic institutions.

    LunarWeb is deployed on servers, mimicking legitimate traffic by spoofing HTTP headers from Windows and ESET product updates.

    It receives commands for execution which are hidden in .JPG and .GIF image files using the steganopraphy technique.

    The commands LunarWeb supports include executing shell and PowerShell commands, collecting system information, running Lua code, zipping files, and exfiltrating data in AES-256 encrypted form.

    ESET researchers say that they observed an attack where the threat actor dropped LunarWeb at three diplomatic institutions of the targeted European Ministry of Foreign Affairs just minutes apart.

    The attacker may have been able to move this quickly because they had previously gained access to the domain controller of the ministry and leveraged it to move to machines from other institutions on the network.

    LunarMail is deployed on user workstations with Microsoft Outlook installed.

    It uses an email-based communication system (Outlook MAPI) for data exchange with specific Outlook profiles linked to the C2 to evade detection in environments where HTTPS traffic may be more closely monitored.

    Commands sent from the C2 are embedded in email attachments, typically hidden in .PNG images, which the backdoor parses to extract the hidden instructions.

    LunarMail can create processes, take screenshots, write files, and run Lua code. Lua script execution allows it to indirectly run shell and PowerShell commands if needed.

    LunarMail operation
    LunarMail operational diagram
    Source: ESET

    Based on similarities in observed tactics, techniques, and procedures (TTPs) between the Lunar toolset and and past activities, ESET attributes the backdoors to the Russian hacking group Turla with medium confidence.

    However, the researchers noticed "varying degrees of sophistication in the compromises," which suggests that the tools were developed and operated by multiple individuals.

    Despite the intrusions being of a more recent date, ESET found artifacts indicating that the backdoors have been used in operations and evaded detection since at least 2020.

    The cybersecurity company is providing a list of indicators of compromise (IoCs) for files, file paths, network, and registry keys observed in compromised environments. A complete list is available here.

    Meta revokes job offer to sextortion expert after he publicly criticizes Instagram

    Guardian
    www.theguardian.com
    2024-05-16 16:53:28
    Exclusive: Paul Raffile held webinar where he said app failed to protect children, and his offer was rescinded hours later Meta revoked a job offer to a prominent cyber-intelligence analyst immediately after he criticized Instagram for failing to protect children online. Paul Raffile had been offere...
    Original Article

    Meta revoked a job offer to a prominent cyber-intelligence analyst immediately after he criticized Instagram for failing to protect children online.

    Paul Raffile had been offered a job as a human exploitation investigator focusing on issues such as sextortion and human trafficking. He had participated in a 24 April webinar on safeguarding against financial sextortion schemes, during which he criticized Instagram for allowing children to fall prey to scammers and offered possible solutions.

    “The only reason I can think of for the offer being rescinded is me trying to shine a light on this big issue of these crimes happening on Instagram, and Instagram doing little to prevent it so far,” said Raffile.

    Raffile was a co-organizer of the webinar, which featured the parents of four children who had died after being scammed on Instagram. Among the 350 attendees were staffers from Meta, the National Center of Missing and Exploited Children (NCMEC), law enforcement agencies, the United Nations Office on Drugs and Crime, Visa, Google and Snap.

    White man with glasses wearing blue button-down
    Paul Raffile. Photograph: Courtesy

    Raffile told the Guardian he made some quick introductory remarks at the webinar, which took less than a minute to deliver.

    With a contract already signed, Raffile was due to start his new $175,000-a-year role the following Monday, but he received the call rescinding the offer within hours of the webinar concluding. Meta’s hiring manager did not share the reason for his firing, stating the directive came from “many pay-levels above us”, Raffile said.

    Meta said in a statement: “It’s not accurate to imply the offer was rescinded because of the NCRI report, the webinar or the candidate’s expertise in this space.” The company did not provide a reason for rescinding Raffile’s offer.

    Raffile said: “It shows that Meta is not willing to take this issue seriously. I’ve brought up legitimate concerns and recommendations, and they’re potentially unwilling to be aggressive enough to tackle this issue.”

    Financial sextortion schemes have soared in the past two years, with more than 26,700 cases of underage victims reported to NCMEC in 2023 alone. According to the FBI, sextortion is the fastest-growing cybercrime in the US.

    The victims are mainly teenage boys, who scammers approach by pretending to be attractive girls. After coercing victims into sending sexually explicit images of themselves, a scammer threatens to distribute the photos to their friends and family unless they pay a ransom.

    A significant portion of these cases are the result of cybercriminals in Nigeria targeting teens abroad. Scammers refer to themselves as “Yahoo Boys”, and most commonly operate on Instagram and Snapchat. The crime can be deadly. Minors are often overwhelmed by scammers’ threats, and financial sextortion led to at least 20 teenage suicides between October 2021 and March 2023, the FBI has said.

    Meta said in a statement it had strict rules against non-consensual sharing of intimate imagery.

    Raffile questioned the reasons Meta and other social media companies have not managed to take effective action against financial sextortion.

    “I had squared off against Yahoo Boys at previous employers, which were financial institutions and tech companies,” he said.

    He previously held positions at the consulting firms Booz Allen Hamilton and Teneo.

    He said: “We were able to eradicate them from our platforms in four to six months. Yet, the social media platforms have had two years to deal with this.”

    A Meta spokesperson said its expert teams were aware that sextortion actors are disproportionately based in several countries, including in west Africa.

    Raffile said Instagram’s design features help facilitate these cybercrimes, including plans to encrypt direct messages, which offers greater privacy but can handicap investigations. Another major issue is the inability of users to keep their followers and following lists private, which means a blackmailer can access the friends and family of their victims, he said.

    “They message the victim and say: ‘Hey, I have your nudes, and I’ve screenshotted all your friends and family, your followers.’ Meta isn’t taking teen privacy seriously enough,” Raffile said.

    Raffile criticized Meta’s April announcement that it would blur images detected as containing nudity as a default setting for under-18s. But teens can still opt to view them.

    “It sounds illegal to allow minors to transmit these images on their platform,” he said. “Why not just block them?”

    Meta said in a statement: “This feature aims to strike the balance between protecting people from seeing nude images and educating them about the risks of sharing them, while not preventing or interrupting people’s important conversations.”

    ChatGPT-4o vs. Math

    Hacker News
    www.sabrina.dev
    2024-05-16 16:30:49
    Comments...
    Original Article

    In this series, I test drive OpenAI’s multimodal ChatGPT-4o.

    For part 1, click here.

    I want to know:

    • can GPT-4o solve this problem by analyzing just the prompt?

    • can GPT-4o solve this problem by combining prompt and image?

    • can GPT-4o solve this problem with the help of prompt engineering?

    Math Problem

    Here’s the image of the math problem:

    Problem Statement

    There is a roll of tape. The tape is 100 meters long when unrolled. When rolled up, the outer diameter is 10 cm, and the inner diameter is 5 cm. How thick is the tape?

    Neil Fraser

    Solution

    Reduce the problem to 2 dimensions.

    Here’s an ASCII Unrolled Tape:

    ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬

    Unrolled Tape Area = T * L

    L = length

    T = thickness

    Here’s an ASCII Rolled Tape:

                          ,,ggddY""""Ybbgg,,
                     ,agd""'              `""bg,
                  ,gdP"                       "Ybg,
                ,dP"                             "Yb,
              ,dP"         _,,ddP"""Ybb,,_         "Yb,
             ,8"         ,dP"'         `"Yb,         "8,
            ,8'        ,d"                 "b,        `8,
           ,8'        d"                     "b        `8,
           d'        d'                       `b        `b
           8         8                         8         8
           8         8                         8         8
           8         8                         8         8
           8         Y,                       ,P         8
           Y,         Ya                     aP         ,P
           `8,         "Ya                 aP"         ,8'
            `8,          "Yb,_         _,dP"          ,8'
             `8a           `""YbbgggddP""'           a8'
              `Yba                                 adP'
                "Yba                             adY"
                  `"Yba,                     ,adP"'
                     `"Y8ba,             ,ad8P"'
                          ``""YYbaaadPP""''

    Rolled Tape Area = \pi (R^2 - r^2)

    R = outer radius

    r = inner radius

    The areas are the same!

    So we can easily solve for thickness T = 0.00589 cm

    Overview of Experiments

    Here are my varied experiments:

    1. Prompt only, no image

    2. Zero-shot Chain-of-Thought

    3. Dimensions inside the image, missing data

    4. Prompt and image

    5. Zero-shot Chain-of-Thought and image

    Despite the same input, there is no guarantee I’ll get the same outputs.

    I designed the experiments to evaluate the impact of:

    • one modality (text only)

    • multi modality (text + image)

    • prompt engineering (Chain of Thought)

    Which approach leads to superior outcomes?

    Take a guess now and see if you’re right 🙂 

    1. Prompt Only, No Image

    First, I test one modality with no prompt engineering:

    I give GPT-4o the text prompt, without the image.

    There is a roll of tape. The tape is 100 meters long when unrolled. When rolled up, the outer diameter is 10 cm, and the inner diameter is 5 cm. How thick is the tape?

    1st run — choke

    GPT-4o gives up after teasing me:

    “Given the complexity, let’s solve this equation numerically”.

    2nd run — correct

    Yay!

    GPT-4o gets the right answer on the 2nd try, without the image, without any prompt engineering.

    3rd run — incorrect

    Unfortunately, the 3rd try was wrong.

    The probabilistic nature of LLMs rears its head…

    2. Zero-Shot Chain-of-Thought


    Second, I test one modality, assisted by prompt engineering:

    I give GPT-4o the text prompt, without the image.

    Then I add a simple prompt engineering technique:

    Take a deep breath and work on this problem step-by-step.

    Sabrina Ramonov @ sabrina.dev

    Seems too simple, right? 😅 

    This prompt engineering technique is called Chain-of-Thought.

    It’s proven to improve ChatGPT’s performance on logic and reasoning tasks by requiring it to explain intermediate steps leading to an answer.

    Full prompt:

    There is a roll of tape. The tape is 100 meters long when unrolled. When rolled up, the outer diameter is 10 cm, and the inner diameter is 5 cm. How thick is the tape?
    
    Take a deep breath and work on this problem step-by-step.

    1st run - correct

    2nd run - correct

    3rd run - correct

    Quite a surprise, this absurdly simple prompt engineering technique resulted in 3/3 correct answers!

    3. Dimensions Inside Image, Missing Data

    Third, I test multi modality (image) and a minimal text prompt.

    I remove dimension data from the text prompt, so GPT-4o must analyze the image correctly to extract the tape roll’s dimensions (radius and diameter).

    However, the length of tape unrolled is neither in the image nor text prompt.

    I expect GPT-4o’s output to be something like, “without knowing the length we can't determine it”.

    Image uploaded to ChatGPT-4o

    There is a roll of tape with dimensions specified in the picture. How thick is the tape?

    1st run - incorrect

    2nd run - incorrect

    3rd run - incorrect

    Sabrina Ramonov @ sabrina.dev

    Interestingly, ChatGPT-4o successfully analyzes the image to determine the outer diameter 10cm and inner diameter 5cm.

    But misinterprets the problem statement:

    GPT-4o interprets “how thick is the tape” as referring to the cross-section of the tape roll, rather than the thickness of a piece of tape.

    Recall the original prompt which has:

    1. dimension data

    2. length of tape unrolled

    3. the concept of rolled vs unrolled tape

    There is a roll of tape. The tape is 100 meters long when unrolled. When rolled up, the outer diameter is 10 cm, and the inner diameter is 5 cm. How thick is the tape?

    Neil Fraser

    Missing this important context, GPT-4o should’ve said it can’t solve the problem. But it went ahead and tried anyway with a different interpretation, indeed a pretty reasonable interpretation given the data at hand.

    4. Prompt and Image

    Fourth, I test multi modality (image) and a text prompt that includes the length of tape unrolled.

    There is a roll of tape with dimensions specified in the picture. The tape is 100 meters long when unrolled. How thick is the tape?

    Image uploaded to ChatGPT-4o

    1 — choke

    Well, this is amusing…

    GPT-4o notices its estimate seems unusually large and tries to course correct!

    But then it gives up... dying with a grammatically incorrect last sentence:

    I will re-calculation next response

    ChatGPT-4o’s last words…

    Sabrina Ramonov @ sabrina.dev

    2 — incorrect

    The 2nd run is better, still wrong, but at least GPT-4o didn’t choke.

    Sabrina Ramonov @ sabrina.dev

    3 — correct

    Yay! GPT-4o finally got it right.

    1/3 correct doesn’t seem super reliable. I thought multi-modality would improve accuracy, but so far, it seems to create confusion.

    Sabrina Ramonov @ sabrina.dev

    5. Zero-Shot Chain-of-Thought and Image

    Fifth, I test multi modality (image), a text prompt that includes the length of tape unrolled, assisted by Chain-of-Thought prompt engineering.

    Image uploaded to ChatGPT-4o

    There is a roll of tape with dimensions specified in the picture. The tape is 100 meters long when unrolled. How thick is the tape?
    
    Take a deep breath and work on this problem step-by-step.

    1 — incorrect

    2 — incorrect

    3 — incorrect

    Wow, didn’t expect that!

    Recall test #2 — text prompt with prompt engineering resulted in 3/3 correct.

    In this multimodal test, I’ve added the image as supporting context, yet all 3 answers are wrong. I mistakenly assumed more context would help.

    But notice GPT-4o incorrectly interprets 5cm as radius, instead of diameter:

    Sabrina Ramonov @ sabrina.dev

    Key takeaway:

    The emphasis here is consistency.

    Previously with Chain-of-Thought, I got the same answer 3 times in a row.

    But because GPT-4o’s image understanding mistakenly thought 5cm was radius, not diameter, it was consistently wrong by a factor of 4.

    It seems GPT-4o’s image understanding struggles with these finer details.

    Conclusion

    Reiterating my goal at the start, I wanted to know:

    • can GPT-4o solve this problem by analyzing just the prompt?

    • can GPT-4o solve this problem by combining prompt and image?

    • can GPT-4o solve this problem with the help of prompt engineering?

    I tested single vs multi modality, as well as the prompt engineering technique called Chain-of-Thought.

    One Modality

    1. Prompt only, no image

    2. Zero-shot Chain of Thought

    Multi Modality

    1. Dimensions inside image, missing data

    2. Prompt and image

    3. Zero-shot Chain-of-Thought and image

    The Winner?

    One modality

    Text-only prompt with zero-shot Chain-of-Thought prompt engineering 🥳 

    Be honest, was that your first guess?

    This concludes part 2 of this series Test Driving ChatGPT-4o!

    For part 1, click here.

    Tornado Cash developer sentenced to more than five years imprisonment in the Netherlands

    Web3 Is Going Great
    web3isgoinggreat.com
    2024-05-16 16:24:24
    Alexey Pertsev, one of the developers of the Tornado Cash mixing service, was found guilty of money laundering and sentenced to 64 months imprisonment in the Netherlands. Prosecutors claimed that Pertsev knew the service was being used to launder money, but "chose not to intervene". They ar...
    Original Article

    Alexey Pertsev, one of the developers of the Tornado Cash mixing service, was found guilty of money laundering and sentenced to 64 months imprisonment in the Netherlands. Prosecutors claimed that Pertsev knew the service was being used to launder money, but "chose not to intervene". They argued that, although the developers could not necessarily prevent bad actors from laundering money through the service directly, they could have done more to prevent people from using the web interface to wash funds from known criminal wallets.

    The case is a concerning one, as sanctioning software developers for how the code they write is used — particularly when it comes to software intended to protect privacy — has frightening implications. Although there is some precedent in the United States that "code is speech", and merely writing and publishing code is protected by the First Amendment, that obviously does not apply to the Netherlands. A collaborator to Pertsev, Roman Storm, is set to be tried on charges of money laundering and sanctions violations in the United States in September, and that case is likely to grapple with this exact issue.

    Egypt's pyramids may have been built on a long-lost branch of the Nile

    Hacker News
    www.nature.com
    2024-05-16 16:20:45
    Comments...
    Original Article

    Introduction

    The landscape of the northern Nile Valley in Egypt, between Lisht in the south and the Giza Plateau in the north, was subject to a number of environmental and hydrological changes during the past few millennia1,2. In the Early Holocene (~12,000 years before present), the Sahara of North Africa transformed from a hyper-arid desert to a savannah-like environment, with large river systems and lake basins3,4 due to an increase in global sea level at the end of the Last Glacial Maximum (LGM). The wet conditions of the Sahara provided a suitable habitat for people and wildlife, unlike in the Nile Valley, which was virtually inhospitable to humans because of the constantly higher river levels and swampy environment5. At this time, Nile River discharge was high, which is evident from the extensive deposition of organic-rich fluvial sediment in the Eastern Mediterranean basin6. Based on the interpretation of archeological material and pollen records, this period, known as the African Humid Period (AHP) (ca. 14,500–5000 years ago), was the most significant and persistent wet period from the early to mid-Holocene in the eastern Sahara region7, with an annual rainfall rate of 300–920 mm yr−18. During this time the Nile would have had several secondary channels branching across the floodplain, similar to those described by early historians (e.g., Herodotus).

    During the mid-Holocene (~10,000–6000 years ago), freshwater marshes were common within the Nile floodplain causing habitation to be more nucleated along the desert margins of the Nile Valley9. The desert margins provided a haven from the high Nile water. With the ending of the AHP and the beginning of the Late Holocene (~5500 years ago to present), rainfall greatly declined, and the region’s humid phase gradually came to an end with punctuated short wet episodes10. Due to increased aridity in the Sahara, more people moved out of the desert towards the Nile Valley and settled along the edge of the Nile floodplain. With the reduced precipitation, sedimentation increased in and around the Nile River channels causing the proximal floodplain to rise in height and adjacent marshland to decrease in the area11,12 estimated the Nile flood levels to have ranged from 1 to 4 m above the baseline (~5000 BP). Inhabitants moved downhill to the Nile Valley and settled in the elevated areas on the floodplain, including the raised natural levees of the river and jeziras (islands). This was the beginning of the Old Kingdom Period (ca. 2686 BCE) and the time when early pyramid complexes, including the Step Pyramid of Djoser, were constructed at the margins of the floodplain. During this time the Nile discharge was still considerably higher than its present level. The high flow of the river, particularly during the short-wet intervals, enabled the Nile to maintain multiple branches, which meandered through its floodplain. Although the landscape of the Nile floodplain has greatly transformed due to river regulation associated with the construction of the Aswan High Dam in the 1960s, this region still retains some clear hydro-geomorphological traces of the abandoned river channels.

    Since the beginning of the Pharaonic era, the Nile River has played a fundamental role in the rapid growth and expansion of the Egyptian civilization. Serving as their lifeline in a largely arid landscape, the Nile provided sustenance and functioned as the main water corridor that allowed for the transportation of goods and building materials. For this reason, most of the key cities and monuments were in close proximity to the banks of the Nile and its peripheral branches. Over time, however, the main course of the Nile River laterally migrated, and its peripheral branches silted up, leaving behind many ancient Egyptian sites distant from the present-day river course9,13,14,15. Yet, it is still unclear as to where exactly the ancient Nile courses were situated16, and whether different reaches of the Nile had single or multiple branches that were simultaneously active in the past. Given the lack of consensus amongst scholars regarding this subject, it is imperative to develop a comprehensive understanding of the Nile during the time of the ancient Egyptian civilization. Such a poor understanding of Nile River morphodynamics, particularly in the region that hosts the largest pyramid fields of Egypt, from Lisht to Giza, limits our understanding of how changes in the landscape influenced human activities and settlement patterns in this region, and significantly restricts our ability to understand the daily lives and stories of the ancient Egyptians.

    Currently, much of the original surface of the ancient Nile floodplain is masked by either anthropogenic activity or broad silt and sand sheets. For this reason, singular approaches such as on-ground searches for the remains of hidden former Nile branches are both increasingly difficult and inauspicious. A number of studies have already been carried out in Egypt to locate segments of the ancient Nile course. For instance9, proposed that the axis of the Nile River ran far west of its modern course past ancient cities such as el-Ashmunein (Hermopolis)13. mapped the ancient hydrological landscape in the Luxor area and estimated both an eastward and westward Nile migration rate of 2–3 km per 1000 years. In the Nile Delta region17, detected several segments of buried Nile distributaries and elevated mounds using geoelectrical resistivity surveys. Similarly, a study by Bunbury and Lutley14 identified a segment of an ancient Nile channel, about 5000 years old, near the ancient town of Memphis (men-nefer). More recently15, used cores taken around Memphis to reveal a section of a lateral ancient Nile branch that was dated to the Neolithic and Predynastic times (ca. 7000–5000 BCE). On the bank of this branch, Memphis, the first capital of unified Egypt, was founded in early Pharaonic times. Over the Dynastic period, this lateral branch then significantly migrated eastwards15. A study by Toonen et al.18, using borehole data and electrical resistivity tomography, further revealed a segment of an ancient Nile branch, dating to the New Kingdom Period, situated near the desert edge west of Luxor. This river branch would have connected important localities and thus played a significant role in the cultural landscape of this area. More recent research conducted further north by Sheisha et al.2, near the Giza Plateau, indicated the presence of a former river and marsh-like environment in the floodplain east of the three great Pyramids of Giza.

    Even though the largest concentration of pyramids in Egypt are located along a narrow desert strip from south Lisht to Giza, no explanation has been offered as to why these pyramid fields were condensed in this particular area. Monumental structures, such as pyramids and temples, would logically be built near major waterways to facilitate the transportation of their construction materials and workers. Yet, no waterway has been found near the largest pyramid field in Egypt, with the Nile River lying several kilometers away. Even though many efforts to reconstruct the ancient Nile waterways have been conducted, they have largely been confined to small sites, which has led to the mapping of only fragmented sections of the ancient Nile channel systems.

    In this work, we present remote sensing, geomorphological, soil coring and geophysical evidence to support the existence of a long-lost ancient river branch, the Ahramat Branch, and provide the first map of the paleohydrological setting in the Lisht-Giza area. The finding of the Ahramat Branch is not only crucial to our understanding of why the pyramids were built in these specific geographical areas, but also for understanding how the pyramids were accessed and constructed by the ancient population. It has been speculated by many scholars that the ancient Egyptians used the Nile River for help transporting construction materials to pyramid building sites, but until now, this ancient Nile branch was not fully uncovered or mapped. This work can help us better understand the former hydrological setting of this region, which would in turn help us learn more about the environmental parameters that may have influenced the decision to build these pyramids in their current locations during the time of Pharaonic Egypt.

    Results

    Position and morphology of the Ahramat Branch

    Synthetic Aperture Radar (SAR) imagery and radar high-resolution elevation data for the Nile floodplain and its desert margins, between south Lisht and the Giza Plateau area, provide evidence for the existence of segments of a major ancient river branch bordering 31 pyramids dating from the Old Kingdom to Second Intermediate Period (2686−1649 BCE) and spanning between Dynasties 3–13 (Fig. 1a). This extinct branch is referred to hereafter as the Ahramat Branch, meaning the “Pyramids Branch” in Arabic. Although masked by the cultivated fields of the Nile floodplain, subtle topographic expressions of this former branch, now invisible in optical satellite data, can be traced on the ground surface by TanDEM-X (TDX) radar data and the Topographic Position Index (TPI). Data analysis indicates that this lateral distributary channel lies between 2.5 and 10.25 km west from the modern Nile River. The branch appears to have a surface channel depth between 2 and 8 m, a channel length of about 64 km and a channel width of 200–700 m, which is similar to the width of the contemporary neighboring Nile course. The size and longitudinal continuity of the Ahramat Branch and its proximity to all the pyramids in the study area implies a functional waterway of great significance.

    Fig. 1: The water course of the ancient Ahramat Branch.
    figure 1

    a Shows the Ahramat Branch borders a large number of pyramids dating from the Old Kingdom to the 2nd Intermediate Period and spanning between Dynasties 3 and 13. b Shows Bahr el-Libeini canal and remnant of abandoned channel visible in the 1911 historical map (Egyptian Survey Department scale 1:50,000). c Bahr el-Libeini canal and the abandoned channel are overlain on satellite basemap. Bahr el-Libeini is possibly the last remnant of the Ahramat Branch before it migrated eastward. d A visible segment of the Ahramat Branch in TDX is now partially occupied by the modern Bahr el-Libeini canal. e A major segment of the Ahramat Branch, approximately 20 km long and 0.5 km wide, can be traced in the floodplain along the Western Desert Plateau south of the town of Jirza. Location of e is marked in white a box in a. (ESRI World Image Basemap, source: Esri, Maxar, Earthstar Geographics).

    Full size image

    A trace of a 3 km river segment of the Ahramat Branch, with a width of about 260 m, is observable in the floodplain west of the Abu Sir pyramids field (Fig. 1b–d). Another major segment of the Ahramat Branch, approximately 20 km long and 0.5 km wide can be traced in the floodplain along the Western Desert Plateau south of the town of Jirza (Fig. 1e). The visible segments of the Ahramat Branch in TDX are now partially occupied by the modern Bahr el-Libeini canal. Such partial overlap between the courses of this canal, traced in the1911 historical maps (Egyptian Survey Department scale 1:50,000), and the Ahramat Branch is clear in areas where the Nile floodplain is narrower (Fig. 1b–d), while in areas where the floodplain gets wider, the two water courses are about 2 km apart. In light of that, Bahr el-Libeini canal is possibly the last remnant of the Ahramat Branch before it migrated eastward, silted up, and vanished. In the course of the eastward migration over the Nile floodplain, the meandering Ahramat Branch would have left behind traces of abandoned channels (narrow oxbow lakes) which formed as a result of the river erosion through the neck of its meanders. A number of these abandoned channels can be traced in the 1911 historical maps near the foothill of the Western Desert plateau proving the eastward shifting of the branch at this locality (Fig. 1b–d). The Dahshur Lake, southwest of the city of Dahshur, is most likely the last existing trace of the course of the Ahramat Branch.

    Subsurface structure and sedimentology of the Ahramat Branch

    Geophysical surveys using Ground Penetrating Radar (GPR) and Electromagnetic Tomography (EMT) along a 1.2 km long profile revealed a hidden river channel lying 1–1.5 m below the cultivated Nile floodplain (Fig. 2). The position and shape of this river channel is in an excellent match with those derived from radar satellite imagery for the Ahramat Branch. The EMT profile shows a distinct unconformity in the middle, which in this case indicates sediments that have a different texture than the overlying recent floodplain silt deposits and the sandy sediments that are adjacent to this former branch (Fig. 2). GPR overlapping the EMT profile from 600–1100 m on the transect confirms this. Here, we see evidence of an abandoned riverbed approximately 400 m wide and at least 25 m deep (width:depth ratio ~16) at this location. This branch has a symmetrical channel shape and has been infilled with sandy Neonile sediment different to other surrounding Neonile deposits and the underlying Eocene bedrock. The geophysical profile interpretation for the Ahramat Branch at this locality was validated using two sediment cores of depths 20 m (Core A) and 13 m (Core B) (Fig. 3). In Core A between the center and left bank of the former branch we found brown sandy mud at the floodplain surface and down to ~2.7 m with some limestone and chert fragments, a reddish sandy mud layer with gravel and handmade material inclusions at ~2.8 m, a gray sandy mud layer from ~3–5.8 m, another reddish sandy mud layer with gravel and freshwater mussel shells at ~6 m, black sandy mud from ~6–8 m, and sandy silt grading into clean, well-sorted medium sand dominated the profile from ~8 to >13 m. In Core B on the right bank of the former branch we found recently deposited brown sandy mud at the floodplain surface and down to ~1.5 m, alternating brown and gray layers of silty and sandy mud down to ~4 m (some reddish layers with gravel and handmade material inclusions), a black sandy mud layer from ~4–4.9 m, and another reddish sandy mud layer with gravel and freshwater mussel shells at ~5 m, before clean, well-sorted medium sand dominated the profile from 5 to >20 m. Shallow groundwater was encountered in both cores concurrently with the sand layers, indicating that the buried sedimentary structure of the abandoned Ahramat Branch acts as a conduit for subsurface water flow beneath the distal floodplain of the modern Nile River.

    Fig. 2: Geophysical survey showing evidence of the abandoned river course of the Ahramat Branch.
    figure 2

    a Locations of geophysical profile and soil drilling (ESRI World Image Basemap, source: Esri, Maxar, Earthstar Geographics). Photos taken from the field while using the b Electromagnetic Tomography (EMT) and c Ground Penetrating Radar (GPR). d Showing the apparent conductivity profile, e showing EMT profile, and f showing GPR profiles with overlain sketch of the channel boundary on the GPR graph. g Simplified interpretation of the buried channel with the location of the two-soil coring of A and B.

    Full size image

    Fig. 3: Deep sediment cores from the southern segment of the Ahramat Branch.
    figure 3

    It shows two-soil cores, A and core B, with soil profile descriptions, graphic core logs, sediment grain size charts, and example photographs.

    Full size image

    Alignment of old and middle kingdom pyramids to the Ahramat Branch

    The royal pyramids in ancient Egypt are not isolated monuments, but rather joined with several other structures to form complexes. Besides the pyramid itself, the pyramid complex includes the mortuary temple next to the pyramid, a valley temple farther away from the pyramid on the edge of a waterbody, and a long sloping causeway that connects the two temples. A causeway is a ceremonial raised walkway, which provides access to the pyramid site and was part of the religious aspects of the pyramid itself19. In the study area, it was found that many of the causeways of the pyramids run perpendicular to the course of the Ahramat Branch and terminate directly on its riverbank.

    In Egyptian pyramid complexes, the valley temples at the end of causeways acted as river harbors. These harbors served as an entry point for the river borne visitors and ceremonial roads to the pyramid. Countless valley temples in Egypt have not yet been found and, therefore, might still be buried beneath the agricultural fields and desert sands along the riverbank of the Ahramat Branch. Five of these valley temples, however, partially survived and still exist in the study area. These temples include the valley temples of the Bent Pyramid, the Pyramid of Khafre, and the Pyramid of Menkaure from Dynasty 4; the valley temple of the Pyramid of Sahure from Dynasty 5, and the valley temple of the Pyramid of Pepi II from Dynasty 6. All the aforementioned temples are dated to the Old Kingdom. These five surviving temples were found to be positioned adjacent to the riverbank of the Ahramat Branch, which strongly implies that this river branch was contemporaneously functioning during the Old Kingdom, at the time of pyramid construction.

    Analysis of the ground elevation of the 31 pyramids and their proximity to the floodplain, within the study area, helped explain the position and relative water level of the Ahramat Branch during the time between the Old Kingdom and Second Intermediate Period (ca. 2649–1540 BCE). Based on Fig. (4), the Ahramat Branch had a high-water level during the first part of the Old Kingdom, especially during Dynasty 4. This is evident from the high ground elevation and long distance from the floodplain of the pyramids dated to that period. For instance, the remote position of the Bent and Red Pyramids in the desert, very far from the Nile floodplain, is a testament to the branch’s high-water level. On the contrary, during the Old Kingdom, our data demonstrated that the Ahramat Branch would have reached its lowest level during Dynasty 5. This is evident from the low altitudes and close proximity to the floodplain of most Dynasty 5 pyramids. The orientation of the Sahure Pyramid’s causeway (Dynasty 5) and the location of its valley temple in the low-lying floodplain provide compelling evidence for the relatively low water level proposition of the Ahramat Branch during this stage. The water level of the Ahramat Branch would have been slightly raised by the end of Dynasty 5 (the last 15–30 years), during the reign of King Unas and continued to rise during Dynasty 6. The position of Pepi II and Merenre Pyramids (Dynasty 6) deep in the desert, west of the Djedkare Isesi Pyramid (Dynasty 5), supports this notion.

    Fig. 4: The ground elevation of 31 pyramids and their proximity to the Nile floodplain.
    figure 4

    It explains the position and relative water level of the Ahramat Branch during the time between the Old Kingdom and Second Intermediate Period. a Shows positive correlation between the ground elevation of the pyramids and their proximity to the floodplain. b Shows positive correlation between the average ground elevation of the pyramids and their average proximity to the floodplain in each Dynasty. c Illustrates the water level interpretation by Hassan (1986) in Faiyum Lake in correlation to the average pyramids ground elevation and average distances to the floodplain in each Dynasty. d The data indicates that the Ahramat Branch had a high-water level during the first period of the Old Kingdom, especially during Dynasty 4. The water level reduced afterwards but was raised slightly in Dynasty 6. The position of the Middle Kingdom’s pyramids, which was at lower altitudes and in close proximity to the floodplain as compared to those of the Old Kingdom might be explained by the slight eastward migration of the Ahramat Branch.

    Full size image

    In addition, our analysis in Fig. (4), shows that the Qakare Ibi Pyramid of Dynasty 8 was constructed very close to the floodplain on very low elevation, which implies that the Nile water levels were very low at this time of the First Intermediate Period (2181–2055 BCE). This finding is in agreement with previous work conducted by Kitchen20 which implies that the sudden collapse of the Old Kingdom in Egypt (after 4160 BCE) was largely caused by catastrophic failure of the annual flood of the Nile River for a period of 30–40 years. Data from soil cores near Memphis indicated that the Old Kingdom settlement is covered by about 3 m of sand11. Accordingly, the Ahramat Branch was initially positioned further west during the Old Kingdom and then shifted east during the Middle Kingdom due to the drought-induced sand encroachments of the First Intermediate Period, “a period of decentralization and weak pharaonic rule” in ancient Egypt, spanning about 125 years (2181–2055 BCE) post Old Kingdom era. Soil cores from the drilling program at Memphis show dominant dry conditions during the First Intermediate Period with massive eolian sand sheets extended over a distance of at least 0.5 km from the edge of the western desert escarpment21. The Ahramat Branch continued to move east during the Second Intermediate Period until it had gradually lost most of its water supply by the New Kingdom.

    The western tributaries of the Ahramat Branch

    Sentinal-1 radar data unveiled several wide channels (inlets) in the Western Desert Plateau connected to the Ahramat Branch. These inlets are currently covered by a layer of sand, thus partially invisible in multispectral satellite imagery. In Sentinal-1 radar imagery, the valley floors of these inlets appear darker than the surrounding surfaces, indicating subsurface fluvial deposits. These smooth deposits appear dark owing to the specular reflection of the radar signals away from the receiving antenna (Fig. 5a, b)22. Considering that Sentinel-1’s C-Band has a penetration capability of approximately 50 cm in dry sand surface23, this would suggest that the riverbed of these channels is covered by at least half a meter of desert sand. Unlike these former inlets, the course of the Ahramat Branch is invisible in SAR data due in large part to the presence of dense farmlands in the floodplain, which limits radar penetration and the detection of underlying fluvial deposition. Moreover, the radar topographic data from TDX revealed the areal extent of these inlets. Their river courses were extracted from TDX data using the Topographic Position Index (TPI), an algorithm which is used to compute the topographic slope positions and to automate landform classifications (Fig. 5c, d). Negative TPI values show the former riverbeds of the inlets, while positive TPI signify the riverbanks bordering them.

    Fig. 5: Using Radar and the Topographic Position Index for mapping major channels (inlets) connected to the Ahramat Branch.
    figure 5

    a Conceptual sketch of the dependence of surface roughness on the sensor wavelength λ (modified after48). b Expected backscatter characteristics in sandy desert areas with buried dry riverbeds. c Dry channels/inlets masked by desert sand in the Dahshur area. d The channels’ courses were extracted using TPI. Negative TPI values highlight the courses of the channels while positive TPI signify their banks.

    Full size image

    Analysis indicated that several of the pyramid’s causeways, from Dynasties 4 and 6, lead to the inlet’s riverbanks (Fig. 6). Among these pyramids, are the Bent Pyramid, the first pyramid built by King Snefru in Dynasty 4 and among the oldest, largest, and best preserved ancient Egyptian pyramids that predates the Giza Pyramids. This pyramid is situated at the royal necropolis of Dahshur. The position of the Bent Pyramid, deep in the desert, far from the modern Nile floodplain, remained unexplained by researchers. This pyramid has a long causeway (~700 m) that is paved in the desert with limestone blocks and is attached to a large valley temple. Although all the pyramids’ valley temples in Egypt are connected to a water body and served as the landing point of all the river-borne visitors, the valley temple of the Bent Pyramid is oddly located deep in the desert, very distant from any waterways and more than 1 km away from the western edge of the modern Nile floodplain. Radar data revealed that this temple overlooked the bank of one of these extinct channels (called Wadi al-Taflah in historical maps). This extinct channel (referred to hereafter as the Dahshur Inlet due to its geographical location) is more than 200 m wide on average (Fig. 6). In light of this finding, the Dahshur Inlet, and the Ahramat Branch, are thus strongly argued to have been active during Dynasty 4 and must have played an important role in transporting building materials to the Bent Pyramid site. The Dahshur Inlet could have also served the adjacent Red Pyramid, the second pyramid built by the same king (King Snefru) in the Dahshur area. Yet, no traces of a causeway nor of a valley temple has been found thus far for the Red Pyramid. Interestingly, pyramids in this site dated to the Middle Kingdom, including the Amenemhat III pyramid, also known as the Black Pyramid, White Pyramid, and Pyramid of Senusret III, are all located at least 1 km far to the east of the Dynasty 4 pyramids (Bent and Red) near the floodplain (Fig. 6), which once again supports the notion of the eastward shift of the Ahramat Branch after the Old Kingdom.

    Fig. 6: The Sakkara and Dahshur inlets are connected to the Ahramat Branch.
    figure 6

    a The two inlets are presently covered by sand, thus invisible in optical satellite imagery. b Radar data, and c TDX topographic data reveal the riverbed of the Sakkara Inlet due to radar signals penetration capability in dry sand. b and c show the causeways of Pepi II and Merenre Pyramids, from Dynasty 6, leading to the Saqqara Inlet. The Valley Temple of Pepi II Pyramid overlooks the inlet riverbank, which indicates that the inlet, and thus Ahramat Branch, were active during Dynasty 6. d Radar data, and e TDX topographic data, reveal the riverbed of the Dahshur Inlet with the Bent Pyramid’s causeway of Dynasty 4 leading to the Inlet. The Valley Temple of the Bent Pyramid overlooks the riverbank of the Dahshur Inlet, which indicates that the inlet and the Ahramat Branch were active during Dynasty 4 of the Old Kingdom.

    Full size image

    Radar satellite data revealed yet another sandy buried channel (tributary), about 6 km north of the Dahshur Inlet, to the west of the ancient city of Memphis. This former fluvial channel (referred to hereafter as the Saqqara Inlet due to its geographical location) connects to the Ahramat Branch with a broad river course of more than 600 m wide. Data shows that the causeways of the two pyramids of Pepi II and Merenre, situated at the royal necropolis of Saqqara and dated to Dynasty 6, lead directly to the banks of the Saqqara Inlet (see Fig. 6). The 400 m long causeway of Pepi II pyramid runs northeast over the southern Saqqara plateau and connects to the riverbank of the Saqqara Inlet from the south. The causeway terminates with a valley temple that lies on the inlet’s riverbank. The 250 long causeway of the Pyramid of Merenre runs southeast over the northern Saqqara plateau and connects to the riverbank of the Saqqara Inlet from the north. Since both pyramids dated to Dynasty 6, it can be argued that the water level of the Ahramat Branch was higher during this period, which would have flooded at least the entrance of its western inlets. This indicates that the downstream segment of the Saqqara Inlet was active during Dynasty 6 and played a vital role in transporting construction materials and workers to the two pyramids sites. The fact that none of the Dynasty 5 pyramids in this area (e.g., the Djedkare Isesi Pyramid) were positioned on the Saqqara Inlet suggests that the water level in the Ahramat Branch was not high enough to enter and submerge its inlets during this period.

    In addition, our data analysis clearly shows that the causeways of the Khafre, Menkaure, and Khentkaus pyramids, in the Giza Plateau, lead to a smaller but equally important river bay associated with the Ahramat Branch. This lagoon-like river arm is referred to here as the Giza Inlet (Fig. 7). The Khufu Pyramid, the largest pyramid in Egypt, seems to be connected directly to the river course of the Ahramat Branch (Fig. 7). This finding proves once again that the Ahramat Branch and its western inlets were hydrologically active during Dynasty 4 of the Old Kingdom. Our ancient river inlet hypothesis is also in accordance with earlier research, conducted on the Giza Plateau, which indicates the presence of a river and marsh-like environment in the floodplain east of the Giza pyramids2.

    Fig. 7: TDX data shows, in 3D, a clear topographic expression of a segment of the former Ahramat Branch in the Nile floodplain in close proximity to the Giza Plateau.
    figure 7

    The causeways of the four Pyramids lead to an inlet, which we named the Giza Inlet, that connects from the west with the Ahramat Branch. These causeways connect the pyramids with valley temples which acted as river harbors in antiquity. These river segments are invisible in optical satellite imagery since they are masked by the cultivated lands of the Nile floodplain. The photo shows the valley temple of Khafre Pyramid (Photo source: Author Eman Ghoneim).

    Full size image

    Discussion

    During the Old Kingdom Period, our analysis suggests that the Ahramat Branch had a high-water level during the first part, especially during Dynasty 4 whereas this water level was significantly decreased during Dynasty 5. This finding is in agreement with previous studies which indicate a high Nile discharge during Dynasty 4 (e.g., ref. 24). Sediment isotopic analysis of the Nile Delta indicated that Nile flows decrease more rapidly by the end of Dynasty 425, in addition26 reported that during Dynasties 5 and 6 the Nile flows were the lowest of the entire Dynastic period. This long-lost Ahramat Branch (possibly a former Yazoo tributary to the Nile) was large enough to carry a large volume of the Nile discharge in the past. The ancient channel segment uncovered by1,15 west of the city of Memphis through borehole logs is most likely a small section of the large Ahramat Branch detected in this study. In the Middle Kingdom, although previous studies implied that the Nile witnessed abundant flood with occasional failures (e.g., ref. 27), our analysis shows that all the pyramids from the Middle Kingdom were built far east of their Old Kingdom counterparts, on lower altitudes and in close proximity to the floodplain as compared to those of the Old Kingdom. This paradox might be explained by the fact that the Ahramat Branch migrated eastward, slightly away from the Western Desert escarpment, prior to the construction of the Middle Kingdom pyramids, resulting in the pyramids being built eastward so that they could be near the waterway.

    The eastward migration and abandonment of the Ahramat Branch could be attributed to gradual tilting of the Nile delta and floodplain in lower Egypt towards the northeast due to tectonic activity28. A topographic tilt such as this would have accelerated river movement eastward due to the river being located in the west at a relatively higher elevation of the floodplain. While near-channel floodplain deposition would naturally lead to alluvial ridge development around the active Ahramat Branch, and therefore to lower-lying tracts of adjacent floodplain to the east, regional tilting may explain the wholesale lateral migration of the river in that direction. The eastward migration and abandonment of the branch could also be ascribed to sand incursion due to the branch’s proximity to the Western Desert Plateau, where windblown sand is abundant. This would have increased sand deposition along the riverbanks and caused the river to silt up, particularly during periods of low flow. The region experienced drought during the First Intermediate Period, prior to the Middle Kingdom. In the area of Abu Rawash north29 and Dahshur site11, settlements from the Early Dynastic and Old Kingdom were found to be covered by more than 3 m of desert sands. During this time, windblown sand engulfed the Old Kingdom settlements and desert sands extended eastward downhill over a distance of at least 0.5 km21. The abandonment of sites at Abusir (5th Dynasty), where the early pottery-rich deposits are covered by wind-blown sand and then mud without sherds, can be used as evidence that the Ahramat Branch migrated eastward after the Old Kingdom. The increased sand deposition activity, during the end of the Old Kingdom, and throughout the First Intermediate Period, was most likely linked to the period of drought and desertification of the Sahara30. In addition, the reduced river discharge caused by decreased rainfall and increased aridity in the region would have gradually reduced the river course’s capacity, leading to silting and abandonment of the Ahramat Branch as the river migrated to the east.

    The Dahshur, Saqqara, and Giza inlets, which were connected to the Ahramat Branch from the west, were remnants of past active drainage systems dated to the late Tertiary or the Pleistocene when rainwater was plentiful31. It is proposed that the downstream reaches of these former channels (wadis) were submerged during times of high-water levels of the Ahramat Branch, forming long narrow water arms (inlets) that gave a wedge-like shape to the western flank of the Ahramat Branch. During the Old Kingdom, the waters of these inlets would have flowed westward from the Ahramat Branch rather than from their headwaters. As the drought intensified during the First Intermediate Period, the water level of the Ahramat Branch was lowered and withdrew from its western inlets, causing them to silt up and eventually dry out. The Dahshur, Saqqara, and Giza inlets would have provided a bay environment where the water would have been calm enough for vessels and boats to dock far from the busy, open water of the Ahramat Branch.

    Sediments from the Ahramat Branch riverbed, which were collected from the two deep soil cores (cores A and B), show an abrupt shift from well-sorted medium sands at depth to overlying finer materials with layers including gravel, shell, and handmade materials. This indicates a step-change from a relatively consistent higher-energy depositional regime to a generally lower-energy depositional regime with periodic flash floods at these sites. So, the Ahramat Branch in this region carried and deposited well-sorted medium sand during its last active phase, and over time became inactive, infilling with sand and mud until an abrupt change led the (by then) shallow depression fill with finer distal floodplain sediment (possibly in a wetland) that was utilized by people and experienced periodic flash flooding. Validation of the paleo-channel position and sediment type using these cores shows that the Ahramat Branch has similar morphological features and an upward-fining depositional sequence as that reported near Giza, where two cores were previously used to reconstruct late Holocene Nile floodplain paleo-environments2. Further deep soil coring could determine how consistent the geomorphological features are along the length of the Ahramat branch, and to help explain anomalies in areas where the branch has less surface expression and where remote sensing and geophysical techniques have limitations. Considering more core logs can give a better understanding of the floodplain and the buried paleo-channels.

    The position of the Ahramat Branch along the western edge of the Nile floodplain suggests it to be the downstream extension of Bahr Yusef. In fact, Bahr Yusef’s course may have initially flowed north following the natural surface gradient of the floodplain before being forced to turn west to flow into the Fayum Depression. This assumption could be supported by the sharp westward bend of Bahr Yusef’s course at the entrance to the Fayum Depression, which could be a man-made attempt to change the waterflow direction of this branch. According to Römer32, during the Middle Kingdom, the Gadallah Dam located at the entrance of the Fayum, and a possible continuation running eastwards, blocked the flow of Bahr Yusef towards the north. However, a sluice, probably located near the village of el-Lahun, was created in order to better control the flow of water into the Fayum. When the sluice was locked, the water from Bahr Yusef was directed to the west and into the depression, and when the sluice was open, the water would flow towards the north via the course of the Ahramat Branch. Today, the abandoned Ahramat Branch north of Fayum appears to support subsurface water flow in the buried coarse sand bed layers, however these shallow groundwater levels are likely to be quite variable due to proximity of the bed layers to canals and other waterways that artificially maintain shallow groundwater. Groundwater levels in the region are known to be variable33, but data on shallow groundwater could be used to further validate the delineated paleo-channel of the Ahramat Branch.

    Conclusion

    The present work enabled the detection of segments of a major former Nile branch running at the foothills of the Western Desert Plateau, where the vast majority of the Ancient Egyptian pyramids lie. The enormity of this branch and its proximity to the pyramid complexes, in addition to the fact that the pyramids’ causeways terminate at its riverbank, all imply that this branch was active and operational during the construction phase of these pyramids. This waterway would have connected important locations in ancient Egypt, including cities and towns, and therefore, played an important role in the cultural landscape of the region. The eastward migration and abandonment of the Ahramat Branch could be attributed to gradual movement of the river to the lower-lying adjacent floodplain or tilting of the Nile floodplain toward the northeast as a result of tectonic activity, as well as windblown sand incursion due to the branch’s proximity to the Western Desert Plateau. The increased sand deposition was most likely related to periods of desertification of the Great Sahara in North Africa. In addition, the branch eastward movement and diminishing could be explained by the reduction of the river discharge and channel capacity caused by the decreased precipitation and increased aridity in the region, particularly during the end of the Old Kingdom.

    The integration of radar satellite data with geophysical surveying and soil coring, which we utilized in this study, is a highly adaptable approach in locating similar former buried river systems in arid regions worldwide. Mapping the hidden course of the Ahramat Branch, allowed us to piece together a more complete picture of ancient Egypt’s former landscape and a possible water transportation route in Lower Egypt, in the area between Lisht and the Giza Plateau.

    Revealing this extinct Nile branch can provide a more refined idea of where ancient settlements were possibly located in relation to it and prevent them from being lost to rapid urbanization. This could improve the protection measures of Egyptian cultural heritage. It is the hope that our findings can improve conservation measures and raise awareness of these sites for modern development planning. By understanding the landscape of the Nile floodplain and its environmental history, archeologists will be better equipped to prioritize locations for fieldwork investigation and, consequently, raise awareness of these sites for conservation purposes and modern development planning. Our finding has filled a much-needed knowledge gap related to the dominant waterscape in ancient Egypt, which could help inform and educate a wide array of global audiences about how earlier inhabitants were living and in what ways shifts in their landscape drove human activity in such an iconic region.

    Materials and methods

    The work comprised of two main elements: satellite remote sensing and historical maps and geophysical survey and sediment coring, complemented by archeological resources. Using this suite of investigative techniques provided insights into the nature and relationship of the former Ahramat Branch with the geographical location of the pyramid complexes in Egypt.

    Satellite remote sensing and historical maps

    Unlike optical sensors that image the land surface, radar sensors image the subsurface due to their unique ability to penetrate the ground and produce images of hidden paleo-rivers and structures. In this context, radar waves strip away the surface sand layer and expose previously unidentified buried channels. The penetration capability of radar waves in the hyper-arid regions of North Africa is well documented4,34,35,36,37. The penetration depth varies according to the radar wavelength used at the time of imaging. Radar signal penetration becomes possible without significant attenuation if the surface cover material is extremely dry (<1% moisture content), fine grained (<1/5 of the imaging wavelength) and physically homogeneous23. When penetrating desert sand, radar signals have the ability to detect subsurface soil roughness, texture, compactness, and dielectric properties38. We used the European Space Agency (ESA) Sentinel-1 data, a radar satellite constellation consisting of a C-Band synthetic aperture radar (SAR) sensor, operating at 5.405 GHz. The Sentinel-1 SAR image used here was acquired in a descending orbit with an interferometric wide swath mode (IW) at ground resolutions of 5 m × 20 m, and dual polarizations of VV + VH. Since Sentinal-1 is operated in the C-Band, it has an estimated penetration depth of 50 cm in very dry, sandy, loose soils39. We used ENVI v. 5.7 SARscape software for processing radar imagery. The used SAR processing sequences have generated geo-coded, orthorectified, terrain-corrected, noise free, radiometrically calibrated, and normalized Sentinel-1 images with a pixel size of 12.5 m. In SAR imagery subsurface fluvial deposits appear dark owing to specular reflection of the radar signals away from the receiving antenna, whereas buried coarse and compacted material, such as archeological remains appear bright due to diffuse reflection of radar signals40.

    Other previous studies have shown that combining radar topographic imagery (e.g., Shuttle Radar Topography Mission-SRTM) with SAR images improves the extraction and delineation of mega paleo-drainage systems and lake basins concealed under present-day topographic signatures3,4,22,41. Topographic data represents a primary tool in investigating surface landforms and geomorphological change both spatially and temporally. This data is vital in mapping past river systems due to its ability to show subtle variations in landform morphology37. In low lying areas, such as the Nile floodplain, detailed elevation data can detect abandoned channels, fossilized natural levees, river meander scars and former islands, which are all crucial elements for reconstructing the ancient Nile hydrological network. In fact, the modern topography in many parts of the study area is still a good analog of the past landscape. In the present study, TanDEM-X (TDX) topographic data, from the German Aerospace Centre (DLR), has been utilized in ArcGIS Pro v. 3.1 software due to its fine spatial resolution of 0.4 arc-second (12 m). TDX is based on high frequency X-Band Synthetic Aperture Radar (SAR) (9.65 GHz) and has a relative vertical accuracy of 2 m for areas with a slope of ≤20%42. This data was found to be superior to other topographic DEMs (e.g., Shuttle Radar Topography Mission and ASTER Global Digital Elevation Map) in displaying fine topographic features even in the cultivated Nile floodplain, thus making it particularly well suited for this study. Similar archeological investigations using TDX elevation data in the flat terrains of the Seyhan River in Turkey and the Nile Delta43,44 allowed for the detection of levees and other geomorphologic features in unprecedented spatial resolution. We used the Topographic Position Index (TPI) module of45 with the TDX data by applying varying neighboring radiuses (20–100 m) to compute the difference between a cell elevation value and the average elevation of the neighborhood around that cell. TPI values of zero are either flat surfaces with minimal slope, or surfaces with a constant gradient. The TPI can be computed using the following expression46.

    $${TPI} < {scaleFactor} > ={{{{\mathrm{int}}}}}(\left({DEM}-{focalmean}\left({annulus},{Irad},{Orad}\right)\right)+0.5)$$

    (1)

    Where the scaleFactor is the outer radius in map units and Irad and Orad are the inner and outer radius of annulus in cells. Negative TPI values highlight abandoned riverbeds and meander scars, while positive TPI signify the riverbanks and natural levees bordering them.

    The course of the Ahramat Branch was mapped from multiple data sources and used different approaches. For instance, some segments of the river course were derived automatically using the TPI approach, particularly in the cultivated floodplain, whereas others were mapped using radar roughness signatures specially in sandy desert areas. Moreover, a number of abandoned channel segments were digitized on screen from rectified historical maps (Egyptian Survey Department scale 1:50,000 collected on years 1910–1911) near the foothill of the Western Desert Plateau. These channel segments together with the former river course segments delineated from radar and topographic data were aggregated to generate the former Ahramat Branch. In addition to this and to ensure that none of the channel segments of the Ahramat Branch were left unmapped during the automated process, a systematic grid-based survey (through expert’s visual observation) was performed on the satellite data. Here, Landsat 8 and Sentinal-2 multispectral images, Sentinal-1 radar images and TDX topographic data were used as base layers, which were thoroughly examined, grid-square by grid-square (2*2 km per a square) at a full resolution, in order to identify small-scale fluvial landforms, anomalous agricultural field patterns and irregular ditches, and determine their spatial distributions. Here, ancient fluvial channels were identified using two key aspects: First, the sinuous geometry of natural and manmade features and, second the color tone variations in the satellite imagery. For example, clusters of contiguous pixels with darker tones and sinuous shapes may signify areas of a higher moisture content in optical imagery, and hence the possible existence of a buried riverbed. Stretching and edge detection were applied to enhance contrasts in satellite images brightness to enable the visualization of traces of buried river segments that would otherwise go unobserved. Lastly, all the pyramids and causeways in the study site, along with ancient harbors and valley temples, as indicators of preexisting river channels, were digitized from satellite data and available archeological resources and overlaid onto the delineated Ahramat Branch for geospatial analysis.

    Geophysical survey and sediment coring

    Geophysical measurements using Ground Penetrating Radar (GPR) and Electromagnetic Tomography (EMT) were utilized to map subsurface fluvial features and validate the satellite remote sensing findings. GPR is effective in detecting changes of dielectric constant properties of sediment layers, and its signal responses can be directly related to changes in relative porosity, material composition, and moisture content. Therefore, GPR can help in identifying transitional boundaries in subsurface layers. EMT, on the other hand, shows the variations and thickness of large-scale sedimentary deposits and is more useful in clay-rich soil than GPR. In summer 2022, a geophysical profile was measured using GPR and EMT units with a total length of approximately 1.2 km. The GPR survey was conducted with a central frequency antenna of 35 MHz and a trigger interval of 5 cm. The EMT survey was performed using the multi-frequency terrain conductivity (EM–34–3) measuring system with a spacing of 10–11 meters between stations. To validate the remote sensing and geophysical data, two sediment cores with depths of 20 m (Core A) and 13 m (Core B) were collected using a deep soil driller. These cores were collected from along the geophysical profile in the floodplain. Sieving and organic analysis were performed on the sediment samples at Tanta University sediment lab to extract information about grain size for soil texture and total organic carbon. In soil texture analysis medium to coarse sediment, such as sands, are typical for river channel sediments, loamy sand and sandy loam deposits can be interpreted as levees and crevasse splays, whereas fine texture deposits, such as silt loam, silty clay loam, and clay deposits, are representative of the more distal parts of the river floodplain47.

    Data availability

    References

    1. Bunbury, J., Tavares, A., Pennington, B. & Gonçalves, P. Development of the Memphite Floodplain: Landscape and Settlement Symbiosis in the Egyptian Capital Zone. In The Nile: Natural and Cultural Landscape in Egypt (eds. Willems, H. & Dahms, J.-M.) 71–96 (Transcript Verlag, 2017). https://doi.org/10.1515/9783839436158-003.

    2. Sheisha, H. et al. Nile waterscapes facilitated the construction of the Giza pyramids during the 3rd millennium BCE. Proc. Natl. Acad. Sci. 119, e2202530119 (2022).

      Article  CAS  Google Scholar 

    3. Ghoneim, E. & El-Baz, F. K. DEM‐optical‐radar data integration for palaeohydrological mapping in the northern Darfur, Sudan: implication for groundwater exploration. Int. J. Remote Sens. 28, 5001–5018 (2007).

      Article  Google Scholar 

    4. Ghoneim, E., Benedetti, M. M. & El-Baz, F. K. An integrated remote sensing and GIS analysis of the Kufrah Paleoriver, Eastern Sahara. Geomorphology 139, 242–257 (2012).

      Article  Google Scholar 

    5. Zaki, A. S. et al. Did increased flooding during the African Humid Period force migration of modern humans from the Nile Valley? Quat. Sci. Rev. 272, 107200 (2021).

      Article  Google Scholar 

    6. Rohling, E. J., Marino, G. & Grant, K. M. Mediterranean climate and oceanography, and the periodic development of anoxic events (sapropels). Earth Sci. Rev. 143, 62–97 (2015).

      Article  CAS  Google Scholar 

    7. DeMenocal, P. et al. Abrupt onset and termination of the African Humid Period: rapid climate responses to gradual insolation forcing. Quat. Sci. Rev. 19, 347–361 (2000).

      Article  Google Scholar 

    8. Ritchie, J. C. & Haynes, C. V. Holocene vegetation zonation in the eastern Sahara. Nature 330, 645–647 (1987).

      Article  Google Scholar 

    9. Butzer, K. W. Early Hydraulic Civilization in Egypt: A Study in Cultural Ecology (The University of Chicago press, Chicago [Ill.] London, 1976).

    10. Kröpelin, S. et al. Climate-Driven Ecosystem Succession in the Sahara: The Past 6000 Years. Science 320, 765–768 (2008).

      Article  Google Scholar 

    11. Bunbury, J. & Jeffreys, D. Real and Literary Landscapes in Ancient Egypt. Camb. Archaeol. J. 21, 65–76 (2011).

      Article  Google Scholar 

    12. Sterling, S. Mortality Profiles as Indicators of Slowed Reproductive Rates: Evidence from Ancient Egypt. J. Anthropol. Archaeol. 18, 319–343 (1999).

      Article  Google Scholar 

    13. Hillier, J. K., Bunbury, J. M. & Graham, A. Monuments on a migrating Nile. J. Archaeol. Sci. 34, 1011–1015 (2007).

      Article  Google Scholar 

    14. Bunbury, J. & Lutley, K. The Nile on the move. https://api.semanticscholar.org/CorpusID:131474399 (2008).

    15. Hassan, F. A., Hamdan, M. A., Flower, R. J., Shallaly, N. A. & Ebrahem, E. Holocene alluvial history and archaeological significance of the Nile floodplain in the Saqqara-Memphis region, Egypt. Quat. Sci. Rev. 176, 51–70 (2017).

      Article  Google Scholar 

    16. Bietak, M., Czerny, E. & Forstner-Müller, I. Cities and urbanism in ancient Egypt. Papers from a workshop in November 2006 at the Austrian Academy of Sciences (Austrian Academy of Sciences, 2010).

    17. El-Qady, G., Shaaban, H., El-Said, A. A., Ghazala, H. & El-Shahat, A. Tracing of the defunct Canopic Nile branch using geoelectrical resistivity data around Itay El-Baroud area, Nile Delta, Egypt. J. Geophys. Eng. 8, 83–91 (2011).

      Article  Google Scholar 

    18. Toonen, W. H. J. et al. Holocene fluvial history of the Nile’s west bank at ancient Thebes, Luxor, Egypt, and its relation with cultural dynamics and basin-wide hydroclimatic variability. Geoarchaeology 33, 273–290 (2018).

      Article  Google Scholar 

    19. Lehner, M. The Complete Pyramids (Thames and Hudson, New York, 1997).

    20. Kitchen, K. A. The chronology of ancient Egypt. World Archaeol. 23, 201–208 (1991).

      Article  Google Scholar 

    21. Giddy, L. & Jeffreys, D. Memphis, 1991. J. Egypt. Archaeol. 78, 1–11 (1992).

      Article  Google Scholar 

    22. Ghoneim, E., Robinson, C. & El‐Baz, F. Radar topography data reveal drainage relics in the eastern Sahara. Int. J. Remote Sens. 28, 1759–1772 (2007).

      Article  Google Scholar 

    23. Roth, L. & Elachi, C. Coherent electromagnetic losses by scattering from volume inhomogeneities. IEEE Trans. Antennas Propag. 23, 674–675 (1975).

      Article  Google Scholar 

    24. Hassan, F. A. Holocene lakes and prehistoric settlements of the Western Faiyum, Egypt. J. Archaeol. Sci. 13, 483–501 (1986).

      Article  Google Scholar 

    25. Woodward, J. C., Macklin, M. G., Krom, M. D. & Williams, M. A. J. The Nile: Evolution, Quaternary River Environments and Material Fluxes. In Large Rivers (ed. Gupta, A.) 261–292 (John Wiley & Sons, Ltd, Chichester, UK, 2007). https://doi.org/10.1002/9780470723722.ch13.

    26. Krom, M. D., Stanley, J. D., Cliff, R. A. & Woodward, J. C. Nile River sediment fluctuations over the past 7000 yr and their key role in sapropel development. Geology 30, 71–74 (2002).

      Article  CAS  Google Scholar 

    27. Stanley, J.-D., Krom, M. D., Cliff, R. A. & Woodward, J. C. Short contribution: Nile flow failure at the end of the Old Kingdom, Egypt: Strontium isotopic and petrologic evidence. Geoarchaeology 18, 395–402 (2003).

      Article  Google Scholar 

    28. Stanley, D. J. & Warne, A. G. Nile Delta: Recent Geological Evolution and Human Impact. Science 260, 628–634 (1993).

      Article  CAS  Google Scholar 

    29. Jones, M. A new old Kingdom settlement near Ausim: report of the archaeological discoveries made in the Barakat drain improvements project, https://api.semanticscholar.org/CorpusID:194486461 (1995).

    30. Bunbury, J. M. The development of the River Nile and the Egyptian Civilization: A Water Historical Perspective with Focus on the First Intermediate Period. In A History of Water: Rivers and Society — From the Birth of Agriculture to Modern Times, Vol. 2 (eds. Tvedt, T. & Coopey, R) 50–69 (I.B. Tauris, 2010).

    31. Bubenzer, O. & Riemer, H. Holocene climatic change and human settlement between the central Sahara and the Nile Valley: Archaeological and geomorphological results. Geoarchaeology 22, 607–620 (2007).

      Article  Google Scholar 

    32. Römer, C. The Nile in the Fayum: Strategies of Dominating and Using the Water Resources of the River in the Oasis in the Middle Kingdom and the Graeco-Roman Period. In The Nile: Natural and Cultural Landscape in Egypt (eds. Willems, H. & Dahms, J.-M.) 171–192 (transcript Verlag, 2017). https://doi.org/10.1515/9783839436158-006.

    33. Mansour, K. et al. Investigation of Groundwater Occurrences Along the Nile Valley Between South Cairo and Beni Suef, Egypt, Using Geophysical and Geodetic Techniques. Pure Appl. Geophys. 180, 3071–3088 (2023).

      Article  Google Scholar 

    34. McCauley, J. F. et al. Subsurface Valleys and Geoarcheology of the Eastern Sahara Revealed by Shuttle Radar. Science 218, 1004–1020 (1982).

      Article  CAS  Google Scholar 

    35. El-Baz, F. & Robinson, C. A. Paleo-channels revealed by SIR-C data in the Western Desert of Egypt: Implications to sand dune accumulations. In Proceedings of the 12th International Conference on Applied Geologic Remote Sensing, Vol. 1, I–469 (Environmental Research Institute of Michigan, Ann Arbor, 1997).

    36. Robinson, C. A., El-Baz, F., Al-Saud, T. S. M. & Jeon, S. B. Use of radar data to delineate palaeodrainage leading to the Kufra Oasis in the eastern Sahara. J. Afr. Earth Sci. 44, 229–240 (2006).

      Article  Google Scholar 

    37. Ghoneim, E. Rimaal: A Sand Buried Structure of Possible Impact Origin in the Sahara: Optical and Radar Remote Sensing Investigation. Remote Sens. 10, 880 (2018).

      Article  Google Scholar 

    38. Ghoneim, E. M. Ibn-Batutah: A possible simple impact structure in southeastern Libya, a remote sensing study. Geomorphology 103, 341–350 (2009).

      Article  Google Scholar 

    39. Schaber, G. G., Kirk, R. L. & Strom, R. Data base of impact craters on Venus based on analysis of Magellan radar images and altimetry data. U.S. Geological Survey, Open-File Report, https://doi.org/10.3133/ofr98104, https://pubs.usgs.gov/of/1998/0104/report.pdf (1998).

    40. Ghoneim, E. & El-Baz, F. K. Satellite Image Data Integration for Groundwater Exploration in Egypt, https://api.semanticscholar.org/CorpusID:216495993 (2020).

    41. Skonieczny, C. et al. African humid periods triggered the reactivation of a large river system in Western Sahara. Nat. Commun. 6, 8751 (2015).

      Article  CAS  Google Scholar 

    42. Wessel, B. et al. Accuracy assessment of the global TanDEM-X Digital Elevation Model with GPS data. ISPRS J. Photogramm. Remote Sens. 139, 171–182 (2018).

      Article  Google Scholar 

    43. Erasmi, S., Rosenbauer, R., Buchbach, R., Busche, T. & Rutishauser, S. Evaluating the Quality and Accuracy of TanDEM-X Digital Elevation Models at Archaeological Sites in the Cilician Plain, Turkey. Remote Sens. 6, 9475–9493 (2014).

      Article  Google Scholar 

    44. Ginau, A., Schiestl, R. & Wunderlich, J. Integrative geoarchaeological research on settlement patterns in the dynamic landscape of the northwestern Nile delta. Quat. Int. 511, 51–67 (2019).

      Article  Google Scholar 

    45. JENNESS, J. Topographic position index (tpi_jen.avx_extension for Arcview 3.x, v.1.3a, Jenness Enterprises [EB/OL], http://www.jennessent.com/arcview/tpi.htm (2006).

    46. Weiss, A. D. Topographic position and landforms analysis, https://api.semanticscholar.org/CorpusID:131349144 (2001).

    47. Verstraeten, G., Mohamed, I., Notebaert, B. & Willems, H. The Dynamic Nature of the Transition from the Nile Floodplain to the Desert in Central Egypt since the Mid-Holocene. In The Nile: Natural and Cultural Landscape in Egypt (eds. Willems, H. & Dahms, J.-M.) 239–254 (transcript Verlag, 2017). https://doi.org/10.1515/9783839436158-009.

    48. Meyer, F. Spaceborne Synthetic Aperture Radar: Principles, data access, and basic processing techniques. In Synthetic Aperture Radar the SAR Handbook: Comprehensive Methodologies for Forest Monitoring and Biomass Estimation. 21–64 (2019). https://doi.org/10.25966/nr2c-s697, https://gis1.servirglobal.net/TrainingMaterials/SAR/SARHB_FullRes.pdf.

    Download references

    Acknowledgements

    This work was funded by NSF grant # 2114295 awarded to E.G., S.O. and T.R. and partially supported by Research Momentum Fund, UNCW, to E.G. TanDEM-X data was awarded to E.G. and R.E by the German Aerospace Centre (DLR) (contract # DEM_OTHER2886). Permissions for collecting soil coring and sampling were obtained from the Faculty of Science, Tanta University, Egypt by coauthors Dr. Amr Fhail and Dr. Mohamed Fathy. Bradley Graves at Macquarie University assisted with preparation of the sedimentological figures. Hamada Salama at NRIAG assisted with the GPR field data collection.

    Author information

    Authors and Affiliations

    1. Department of Earth and Ocean Sciences, University of North Carolina Wilmington, Wilmington, NC, 28403-5944, USA

      Eman Ghoneim

    2. School of Natural Sciences, Macquarie University, Macquarie, NSW, 2109, Australia

      Timothy J. Ralph

    3. Department of History, The University of Memphis, Memphis, TN, 38152-3450, USA

      Suzanne Onstine

    4. Near Eastern Languages and Civilizations, University of Chicago, Chicago, IL, 60637, USA

      Raghda El-Behaedi

    5. National Research Institute of Astronomy and Geophysics (NRIAG), Helwan, Cairo, 11421, Egypt

      Gad El-Qady, Mahfooz Hafez, Magdy Atya, Mohamed Ebrahim & Ashraf Khozym

    6. Geology Department, Faculty of Science, Tanta University, Tanta, 31527, Egypt

      Amr S. Fahil & Mohamed S. Fathy

    Authors

    1. Eman Ghoneim

      You can also search for this author in PubMed Google Scholar

    2. Timothy J. Ralph

      You can also search for this author in PubMed Google Scholar

    3. Suzanne Onstine

      You can also search for this author in PubMed Google Scholar

    4. Raghda El-Behaedi

      You can also search for this author in PubMed Google Scholar

    5. Gad El-Qady

      You can also search for this author in PubMed Google Scholar

    6. Amr S. Fahil

      You can also search for this author in PubMed Google Scholar

    7. Mahfooz Hafez

      You can also search for this author in PubMed Google Scholar

    8. Magdy Atya

      You can also search for this author in PubMed Google Scholar

    9. Mohamed Ebrahim

      You can also search for this author in PubMed Google Scholar

    10. Ashraf Khozym

      You can also search for this author in PubMed Google Scholar

    11. Mohamed S. Fathy

      You can also search for this author in PubMed Google Scholar

    Contributions

    Eman Ghoneim conceived the ideas, lead the research project, and conducted the data processing and interpretations. The manuscript was written and prepared by Eman Ghoneim. Timothy J. Ralph co-supervised the project, contributed to the geomorphological and sedimentological interpretations, edited the manuscript and the figures. Suzanne Onstine co-supervised the project, contributed to the archeological and historical interpretations, and edited the manuscript. Raghda El-Behaedi contributed to the remote sensing data processing and methodology and edited the manuscript. Gad El-Qady supervised the geophysical survey. Mahfooz Hafez, Magdy Atya, Mohamed Ebrahim, Ashraf Khozym designed, collected, and interpreted the GPR and EMT data. Amr S. Fahil and Mohamed S. Fathy supervised the soil coring, sediment analysis, drafted sedimentological figures and contributed to the interpretations. All authors reviewed the manuscript and participated in the fieldwork.

    Corresponding author

    Correspondence to Eman Ghoneim.

    Ethics declarations

    Competing interests

    The authors declare no competing interests.

    Peer review

    Peer review information

    Communications Earth & Environment thanks Ritambhara Upadhyay and Judith Bunbury for their contribution to the peer review of this work. Primary Handling Editors: Patricia Spellman and Joe Aslin. A peer review file is available.

    Additional information

    Publisher’s note Springer Nature remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.

    Supplementary information

    About this article

    Check for updates. Verify currency and authenticity via CrossMark

    Cite this article

    Ghoneim, E., Ralph, T.J., Onstine, S. et al. The Egyptian pyramid chain was built along the now abandoned Ahramat Nile Branch. Commun Earth Environ 5, 233 (2024). https://doi.org/10.1038/s43247-024-01379-7

    Download citation

    • Received:

    • Accepted:

    • Published:

    • DOI: https://doi.org/10.1038/s43247-024-01379-7

    Egypt's pyramids may have been built on a long-lost branch of the Nile

    Hacker News
    www.nature.com
    2024-05-16 16:20:45
    Comments...
    Original Article
    • NEWS

    Geological survey reveals the remains of a major waterway that ancient Egyptian builders could have used to transport materials.

    1. Freda Kreier
    The Red Pyramid at the Dahshur necropolis.

    The Red Pyramid, the largest of the pyramids at the Dahshur necropolis, was built more than 4,500 years ago.Credit: Eman Ghoneim

    Stretching beneath the ground near the Giza pyramid complex in Egypt lie the remains of an ancient branch of the Nile River that might once have helped ancient Egyptians to build their monuments.

    The highest concentration of pyramids in Egypt can be found in a stretch of desert between Giza and the village of Lisht. These sites are now several dozens of kilometres away from the Nile River. But Egyptologists have long suspected that the Nile might once have been closer to that stretch than it is today.

    Satellite images and geological data now confirm that a tributary of the Nile — which researchers have named the Ahramat Branch — used to run near many of the major sites in the region several thousand years ago. The discovery, reported on 16 May in Communications Earth and Environment1, could help to explain why ancient Egyptians chose this area to build the pyramids (See ‘Ancient river’).

    Ancient river: Location of an ancient branch of the Nile River that may have flowed past many of Egypt's pyramids.

    Source: Ref. 1 Image source: NASA Visible Earth

    “The pyramids seem like pretty monumental work,” says Judith Bunbury, a geoarchaeologist at the University of Cambridge, UK. “But it’s less arduous if you can bring big stones up by boat rather than carrying them over land.”

    Wandering waterways

    For thousands of years, the Nile and its flood-plain have provided food, agriculture and water to Egypt’s inhabitants. The majority of the country’s population still lives in the Nile basin.

    But the river is prone to migrating, and in the past, populations have had to relocate to keep up. Over the last few hundred years, the Nile has moved several kilometres to the east, possibly owing to shifting plate tectonics.

    There is evidence that some of Egypt’s important archaeological sites do not have the same relationship to the river as they would have had at the time they that were built. There are remains of harbours and other such clues at sites between Giza and Lisht. But scientists have found it difficult to chart the scope or locations of these lost waterways.

    While looking for traces of ancient water, a team led by Eman Ghoneim, a geomorphologist at the University of North Carolina at Wilmington, spotted what looked like a dried-up river channel several kilometres west of the Nile. The channel ran for around 60 kilometres through agricultural areas and had a similar depth and width to the modern Nile.

    Members of the research team organises a table covered in collected soil samples.

    The research team prepares to analyse soil samples collected from an area in the Nile Valley close to the pyramids.Credit: Eman Ghoneim

    To investigate whether the channel could be part of an ancient riverbed, the researchers collected core samples of sediment from the channel. Beneath the wet mud of the fields, they found an layer of gravel and sand consistent with that of a riverbed. Combining this sample data with satellite imagery allowed the team to map the branch’s location. They found that it would have flowed past more than 30 Old- and Middle-Kingdom pyramids dating from between 2686 to 1649 bc — thus the decision to called it the ‘Ahramat’ branch, using the Arabic word for pyramid.

    The Ahramat “connected all these different pyramid fields”, says Suzanne Onstine, an egyptologist at the University of Memphis in Tennessee. “Their valley temples and causeways all oriented exactly to where the water would have been.”

    Riverside sites

    Researchers have long debated the significance of the pyramids’ locations. The waterway running right past them could have been an important factor, because it would have provided a convenient way for builders to transport materials to the sites.

    This theory aligns with documents from the era which state that building materials were brought in by boat, says Bunbury.

    Eventually, the movement of the Nile and sand blowing in from the Sahara Desert would have caused the Ahramat Branch to dry up and become unnavigable. Today, only a few stray lakes and channels remain where the major branch once ran.

    But knowing the ancient river’s location provides a blueprint that archaeologists can use to try and uncover more ancient Egyptian settlements, says Onstine. And the finding that Egyptians were probably using boats rather than land transportation to move materials to build the pyramids hints that they were “a lot more pragmatic than perhaps we realized before”, says Bunbury.

    References

    Intel's Thunderbolt Share lets two PCs control each other over a USB cable

    Hacker News
    www.theverge.com
    2024-05-16 16:19:53
    Comments...
    Original Article

    Why can’t you just plug a USB cable between two PCs, drag your mouse cursor between their screens, and drop files between them, as if they were a single machine? Well, you can and have for years — but Intel may be about to turbocharge that idea with Thunderbolt Share.

    It’s a proprietary app that Intel will be licensing to laptop, desktop, and accessory manufacturers to bundle with new hardware. Install it on two Thunderbolt 4 or 5 computers, connect them with a Thunderbolt cable, and you should be able to share your mouse, keyboard, screens, storage, and other USB peripherals; drag and drop files at Thunderbolt speeds; and sync data between them. It won’t let you share an internet connection, though.

    Image: Intel

    Intel says you can also mirror one PC’s screen to another at 1080p resolution and 60 frames per second at low latency and with zero compression — and the PCs can connect through a Thunderbolt dock or monitor if that’s more convenient than a direct link.

    It doesn’t strictly require a Thunderbolt-certified computer, mind you, or even necessarily an Intel processor. “USB 4 and Thunderbolt 3 connections may work, we just really don’t guarantee it, we won’t be providing support for it,” says Intel Thunderbolt chief Jason Ziller.

    Image: Intel

    But it does require the app, which Intel will charge OEMs an extra license fee to provide exclusively with new hardware. Having to buy a subset of Thunderbolt computer or Thunderbolt accessory kind of limits the environments in which this might come in handy! Intel says you do get a second license with any Thunderbolt Share PC you buy or two with any accessory, though.

    The app is an upsell because PC manufacturers are interested, says Ziller, and Intel wants to test and certify it thoroughly with them “to make sure it’s a great experience.”

    It’s also just for Windows right now: “We’re exploring other OS opportunities but at this point in time it would not work connected to a Mac.”

    Image: Intel

    Acer, Lenovo, MSI, and Razer are the first PC partners, along with accessory vendors Belkin, Kensington, Plugable, and Promise Technology. Some of those companies previously sold “Easy Transfer” cables designed to migrate from one computer to the next; Plugable already sells a Thunderbolt cable packaged with a Bravura Easy Computer Sync app that offers drag and drop and remote computer control, too. I wonder how Thunderbolt Share will compare.

    Nevada parents wrongfully accused of child abuse file lawsuit against hospital

    Hacker News
    mynews4.com
    2024-05-16 16:07:37
    Comments...
    Original Article

    RENO, Nev. (News 4 & FOX 11) — The Nevada family who was featured in the popular Netflix documentary 'Take Care of Maya' filed a civil lawsuit against Dell Children's Medical Center in U.S. District Court last week.

    This comes seven months after Maya's family from 'Take Care of Maya' was awarded $261 million in damages after a jury found that Johns Hopkins All Children's Hospital was liable for charges including medical negligence and false imprisonment.

    As seen in our coverage of Lorina and Jason's story last year, child protective services took away their son and daughter, after their youngest son JJ was misdiagnosed with shaken baby syndrome. Jason faced two felony charges of child abuse, which are now dropped, and the children were placed in foster care for five months. Medical documents later show JJ actually had a birth injury and benign external hydrocephalus. Lorina and Jason were exonerated of any wrongdoing and a Texas court ordered the children to be returned home. Still, Jason had to leave his job and the family sold their house to pay for legal representation. The Troys later moved to Reno while they worked on a case with their attorneys.

    "Stephanie, and I wouldn't take the case, if it wasn't important," said Aaron Rapier, one of the family's attorneys. "We wouldn't take the case if it wasn't for a loving, innocent family. And frankly, we wouldn't take the case, if we didn't think we could not only help that family, but also changed the world."

    News 4 reached out to Dell Children's Medical Center. The hospital says they haven't been served the complaint yet, but the medical center shared a statement with News 4:

    We have not been served with this complaint, and therefore cannot speak to it. At Dell Children’s Medical Center, our highest priority is the safety and health of children in our community. As a healthcare provider in Texas, our doctors, nurses and care teams who have reasonable cause to believe that a child has been affected by abuse or neglect by any person must immediately report this to the appropriate authorities as required by law. We have a duty to work with authorities during their investigation as they make their decision on what is in the best interest of the child.

    Attorney for the Troys, Stephanie Proffitt, says the family's case is receiving a lot of attention.

    “I'm getting emails daily. I'm getting phone calls from people across the Houston area primarily, but also across the state saying, hey, that same thing happened to me. How do I how do I, you know, do something like this? What do I need to do? It's extremely unfortunate. And, like I said earlier, CPS targets the the disadvantaged the people with no money to fight back."

    You can read the Troy's civil complaint here:

    This is a developing story.

    EU investigates Facebook owner Meta over child safety and mental health concerns

    Guardian
    www.theguardian.com
    2024-05-16 16:00:04
    Company’s social media platforms, which also include Instagram, may have addictive effects, says European Commission • Business live – latest updates The European Commission has opened an investigation into the owner of Facebook and Instagram over concerns that the platforms are creating addictive b...
    Original Article

    The European Commission has opened an investigation into the owner of Facebook and Instagram over concerns that the platforms are creating addictive behaviour among children and damaging mental health.

    The EU executive said Meta may have breached the Digital Services Act (DSA), a landmark law passed by the bloc last summer that makes digital companies large and small liable for disinformation, shopping scams, child abuse and other online harms.

    “Today we open formal proceedings against Meta,” the EU commissioner for the internal market, Thierry Breton, said in a statement. “We are not convinced that it has done enough to comply with the DSA obligations to mitigate the risks of negative effects to the physical and mental health of young Europeans on its platforms Facebook and Instagram.”

    The investigation will explore potential addictive impacts of the platforms, known as “rabbit hole” effects, where an algorithm feeds young people negative content, such as on unrealistic body image. It will also look at the effectiveness of Meta’s age verification tools and privacy for minors. “We are sparing no effort to protect our children,” Breton said.

    A Meta spokesperson said: “We want young people to have safe, age-appropriate experiences online and have spent a decade developing more than 50 tools and policies designed to protect them. This is a challenge the whole industry is facing, and we look forward to sharing details of our work with the European Commission.”

    Last month the commission opened an inquiry into Meta under the DSA over its handling of political content amid concerns that it was not doing enough to counter Russian disinformation before the EU elections in June.

    Under the DSA, platforms are obliged to protect the privacy and safety of children. Following a preliminary investigation, EU officials are concerned that Facebook and Instagram “may exploit the weaknesses and inexperience of minors and cause addictive behaviour”.

    They are also sceptical about the platform’s age-verification tools. Users are meant to be at least 13 years old to open an account on Facebook or Instagram.

    One official said that it was “so obviously easy to circumvent some controls” that the commission wanted to know how it was ever assessed by Meta that these measures could be effective and appropriate.

    An EU official said on Thursday that the commission wanted to use the bloc’s European digital identity wallet for age verification. The wallet, which is still at the testing stage, is intended to make it easier for people across the 27-country union to prove who they are, whether they are opening a bank account, applying to university or applying for a job.

    The commission has also begun two investigations into TikTok, which led the Chinese-owned video-sharing platform to voluntarily withdraw its TikTok Lite reward-to-watch service in France and Spain last month.

    skip past newsletter promotion

    This followed the launch of DSA proceedings into X for alleged hate speech and into the online commerce site AliExpress over its advertising transparency and complaint handling.

    The latest Meta investigation is similar to the TikTok case as both are examining the potentially addictive nature of online platforms. Breton has previously said the TikTok Lite service could be “as toxic and addictive as cigarettes”.

    The DSA, which entered into force in February for platforms operating in Europe, was intended to force powerful online platforms that were “too big to care” to take responsibility for online safety.

    If the commission is not satisfied with Meta’s response it can impose a fine equating to 6% of its global turnover. More immediately, it can carry out on-site investigations and interview company executives, with no deadline publicly fixed to complete the investigation.

    Brothers indicted for $25 million MEV bot exploit

    Web3 Is Going Great
    web3isgoinggreat.com
    2024-05-16 15:41:26
    Two brothers, Anton and James Peraire-Bueno, were indicted for a theft involving MEV — maximal extractable value. MEV involves previewing upcoming transactions on a blockchain and taking actions to extract additional profits — which can sometimes be substantial — based on that information.According ...
    Original Article

    Two brothers, Anton and James Peraire-Bueno, were indicted for a theft involving MEV — maximal extractable value. MEV involves previewing upcoming transactions on a blockchain and taking actions to extract additional profits — which can sometimes be substantial — based on that information.

    According to the Justice Department, the Peraire-Buenos exploited a flaw in popular MEV software called "MEV-boost", which is used by most Ethereum validators. By creating their own validators and "bait transactions", they were able to trick MEV bots into proposing transactions involving illiquid cryptocurrencies, which the brothers then frontran. They were able to create false signatures that tricked a MEV-boost relay into releasing information about upcoming blocks that they were able to tamper with.

    The brothers were charged with conspiracy to commit wire fraud, wire fraud, and conspiracy to commit money laundering, and face up to 20 years in prison for each charge.

    The Justice Department is describing the case as a "first-of-its-kind manipulation of the Ethereum blockchain". The case is an interesting one, as some believe the practice of MEV itself exploits Ethereum users. Others believe anything you can do with code should be allowed — "code is law". However, by signing false transactions and tricking the relay into releasing private information, the brothers' actions do seem to go beyond simply making profits in a "code is law" Wild West, and into the realm of actual fraud.

    Sprint, T-Mobile Merger Killed Wireless Price Competition in U.S.

    Hacker News
    www.techdirt.com
    2024-05-16 15:38:40
    Comments...
    Original Article

    from the told-you-so dept

    Before T-Mobile acquired Sprint, activists, consumer groups, and deal critics (including me) warned repeatedly that the telecom sector megadeal would result in layoffs, less competition, higher prices, and a lower quality product overall. The Trump FCC and DOJ very clearly didn’t care; they rubber stamped the deal without even reading deal impact reports.

    T-Mobile CEO John Legere, famous for wearing magenta high tops and occasionally saying “fuck,” called deal critics liars, insisting that the combination of the fourth and third biggest carrier would result in lower prices, bold new innovations, untold new synergies, and would be “jobs positive from day one.”

    It didn’t take long before Legere and T-Mobile executives were proven to be liars. T-Mobile quickly moved to lay off 9,000 employees, and the company’s competitive edge completely evaporated. And a new report by Finland based research firm Rewheel found that the merger immediately effectively stopped nearly all meaningful price competition in the U.S. wireless market:

    “Five years on, the Sprint / T-Mobile 4-to-3 mobile merger made the US one of the most expensive mobile markets in the world.”

    Before the merger, deal critics repeatedly pointed out that in every single country where regulators allowed a consolidation from four to three wireless carriers, it effectively stopped price competition dead in its tracks. With less incentive to compete on price, U.S. wireless providers simply stopped trying. Now, U.S. consumers once again pay some of the highest prices for mobile data in the world:

    Keep in mind: these studies often can’t or won’t include all of the various ways telecoms nickel-and-dime you with hidden fees and surcharges post sale (activation fees, etc.), so the real world impact on consumers financially is actually likely worse. Gone also are all the little “uncarrier” pro-consumer efforts T-Mobile attempted to use to differentiate themselves from AT&T and Verizon.

    Employees, of which there are 9,000 less of now, will also tell you T-Mobile is a shadow of its former self.

    Of course T-Mobile knew this would happen. It was the entire point. Less competition allows for greater nickel-and-diming of consumers, higher prices, and fatter profits for investors (at first). Trump regulators obviously knew it would happen as well; to justify approval they proposed the half-assed, doomed effort to pretend Dish would become a viable fourth replacement option (as predicted, it isn’t).

    Trump regulators not only didn’t even read the deal impact reports, the Trump DOJ’s top “antitrust enforcer,” Makan Delrahim, actively worked with the companies using his personal devices in his free time to ensure the deal saw government approval. You might recall T-Mobile hired Corey Lewandowski and ramped up the time they spent at Trump hotel properties to help seal the clearly-corrupt deal.

    That is all, if you’re unfamiliar, not how “antitrust enforcement” is supposed to work, no matter what “free market” and “Libertarian” telecom sector funded think tanks like to claim.

    It’s important to remember that the previously competitive T-Mobile was a direct byproduct of the Obama DOJ’s decision in 2011 to block AT&T’s attempted acquisition of T-Mobile. That decision, actually based on evidence, protected competition and consumer welfare. That history is usually memory holed by “free market,” telecom-funded think tank apologists for mindless consolidation.

    Somewhere former T-Mobile CEO John Legere is sitting on a giant pile of money. Maybe he sometimes experiences a slight twinge of conscience watching the pro-consumer company he helped build steadily turn into AT&T. But so unconcerned are T-Mobile executives with accountability for lying to regulators, they still haven’t bothered to delete Legere’s 2019 pre-merger lies from the T-Mobile website.

    Filed Under: , , , , , , , ,
    Companies: sprint, t-mobile

    Researchers build AI-driven sarcasm detector

    Guardian
    www.theguardian.com
    2024-05-16 15:35:10
    Being able to detect lowest form of wit could help AI interact with people more naturally, say scientists Never mind that it can pass the bar exam, ace medical tests and read bedtime stories with emotion, artificial intelligence will never match the marvel of the human mind without first mastering t...
    Original Article

    Never mind that it can pass the bar exam, ace medical tests and read bedtime stories with emotion, artificial intelligence will never match the marvel of the human mind without first mastering the art of sarcasm.

    But that art, it seems, may be next on the list of the technology’s dizzying capabilities. Researchers in the Netherlands have built an AI-driven sarcasm detector that can spot when the lowest form of wit, and the highest form of intelligence, is being deployed.

    “We are able to recognise sarcasm in a reliable way, and we’re eager to grow that,” said Matt Coler at the University of Groningen’s speech technology lab. “We want to see how far we can push it.”

    There is more to the project than teaching algorithms that sometimes even the most effusive comments cannot be taken literally and must, instead, be interpreted as the diametric opposite. Sarcasm permeates our discourse more than we might appreciate, Coler said, so understanding it is crucial if humans and machines are to communicate seamlessly.

    “When you start studying sarcasm, you become hyper-aware of the extent to which we use it as part of our normal mode of communication,” Coler said. “But we have to speak to our devices in a very literal way, as if we’re talking to a robot, because we are. It doesn’t have to be this way.”

    Humans are generally adept at spotting sarcasm, though the limited cues found in text alone make it tougher than in a face-to-face interaction when delivery, tone and facial expressions all reveal the speaker’s intent. In developing their AI, the researchers found multiple cues mattered too for the algorithm to distinguish the sarcastic from the sincere.

    In work presented at a joint meeting of the Acoustical Society of America and the Canadian Acoustical Association in Ottawa on Thursday, Xiyuan Gao, a PhD student at the lab, described how the group trained a neural network on text, audio and emotional content of video clips from US sitcoms including Friends and The Big Bang Theory. The database, known as Mustard, was compiled by researchers in the US and Singapore, who annotated sentences from the TV shows with sarcasm labels to build their own detector.

    One scene the AI trained on was Leonard’s futile effort to escape from a locked room in The Big Bang Theory, prompting Sheldon to observe: “It’s just a privilege to watch your mind at work.” Another from Friends has Ross invite Rachel to come over and join Joey and Chandler in putting together some furniture, prompting Chandler to comment: “Yes, and we’re very excited about it.”

    After training on the text and audio, along with scores that reflected the emotional content of words spoken by the actors, the AI could detect sarcasm in unlabelled exchanges from the sitcoms nearly 75% of the time. Further work at the lab has used synthetic data to bump up the accuracy further, but that research is awaiting publication.

    Shekhar Nayak, another researcher on the project, said as well as making conversations with AI assistants more fluid, the same approach could be used to detect negative tone in language and detect abuse and hate speech.

    Gao said additional improvements could come from adding visual cues into the AI’s training data, such as eyebrow movements and smirks. Which raises the question of how accurate is accurate enough? “Are we going to have a machine that is 100% accurate?” said Gao. “That’s not something even humans can achieve.”

    Making programs more familiar with how humans really speak should help people converse with devices more naturally, Coler adds, but he wonders what will happen if machines embrace their newfound skills and start throwing sarcasm back at us. “If I ask: ‘Do you have time for a question?’ And it says: ‘Yeah, sure,’ I might think: well does it or doesn’t it?”

    Show HN: I'm 17 and wrote a guide on how to build your own programming language

    Hacker News
    easel.hackclub.com
    2024-05-16 15:34:24
    Comments...
    Original Article

    It's a normal Saturday for Orpheus the dinosaur. Or rather, not normal. This is the first Saturday in a while where she can lie in bed alone, and look out the window, and daydream about whatever she wants to. No tea parties to go to, no meetings, no nothing. She can just lie in bed and think about pancakes for breakfast, lunch, and dinner.

    What a perfect day. You know what would be even more perfect? Actual pancakes. Blueberry pancakes, chocolate pancakes, banana pancakes. That means she has got to get out of bed and check if she has those ingredients. She rolls over and out of bed and into the kitchen.

    When she gets to the kitchen, there's a knock on the door. Now, Orpheus' house is laid out in such a way where the front door leads to the kitchen. Or rather, the kitchen leads to the front door. (The magic of perspective.)

    Perfect timing!, she thinks. Almost like someone knows what I'm doing at the current moment.

    The doorbell rings insistently again. Orpheus runs stomps her way over to the door and opens it, but no one's there! She looks around. Nobody's around. It's kind of a dull and gray day outside, honestly, although the rain is making nice pitter-patter sounds on the porch screens.

    She looks down. There's a box at her feet. Ooh. Could it be fan mail? She bends down to pick it up.

    She rips apart the box with her claws, and three things fall out: a keyboard sort of thing with a very small screen (a computer??), a grid-like boxy sort of contraption (something like this. Orpheus and I couldn't come up with a better description when we were arguing over the sequence of events), and a nice, fancy piece of paper that Orpheus can't help but put her nose up to. It smells good. Like paper, you know?

    Orpheus reads the letter.

    I hope this letter finds you well. Maybe on a cozy rainy Saturday morning. In the confines of this package (there is only so much you can fit inside a decent package when you are trying to adhere to USPS shipping guidelines while also trying to be budget-friendly), there are two things: a computer unlike anything you normally use, for interfacing with the second thing, an easel.

    The easel is a blank, sad thing right now. You need to paint it. Now, you can't paint it with any normal paint and brush. What, do you think this is, that one boy with that one purple crayon that he can just make random shite come to life with by scribbling?

    No, you must talk to it.

    I know you've wanted to be an artist. And now you have a chance to be a special one. An artist that can also perform magic! Figure out how to talk to the easel with the computer I have provided, and you can do both. Hint: you need to write a programming language. The one I have included is called Easel, and is a good starting point.

    There is much you'll learn along the way. You might even find that there's a surprise or two, too. (See what I did there? Punny. Yes, I am quite a humorous person. It is something I pride myself on. Quite masterful at pranks, too.)

    You'll probably go back to cooking pancakes or something. There are many reasons to do this, though, and here I'll rank them in alphabetical order:

    P.S. I know that you would like to know who I am because who doesn't? So let's strike a compromise. Once you figure out how to paint this easel, you'll be able to run this:

    prepare rows as 64
    prepare cols as 64
    
    sketch color needs (r, g, b) {
      finished prep Color(r: r, g: g, b: b)
    }
    
    prepare me as [color(163, 165, 203), color(174, 178, 215), color(164, 171, 207), color(151, 158, 196), color(155, 159, 197), color(154, 158, 196), color(162, 166, 202), color(170, 173, 210), color(169, 176, 213), color(167, 176, 213), color(165, 173, 210), color(171, 179, 216), color(170, 178, 215), color(177, 185, 222), color(172, 180, 217), color(157, 165, 202), color(151, 159, 195), color(150, 158, 194), color(154, 162, 198), color(167, 175, 211), color(172, 180, 214), color(177, 187, 214), color(171, 181, 204), color(173, 182, 211), color(159, 167, 201), color(148, 158, 191), color(146, 152, 186), color(156, 162, 193), color(172, 179, 208), color(173, 180, 208), color(171, 179, 204), color(174, 182, 205), color(174, 181, 205), color(167, 174, 197), color(174, 181, 201), color(166, 173, 192), color(157, 164, 182), color(151, 155, 174), color(143, 145, 165), color(145, 146, 167), color(143, 144, 164), color(143, 144, 160), color(143, 145, 158), color(142, 144, 157), color(142, 141, 155), color(143, 142, 156), color(147, 146, 160), color(152, 157, 169), color(162, 168, 180), color(159, 164, 176), color(163, 166, 179), color(164, 167, 179), color(160, 161, 174), color(164, 166, 179), color(142, 144, 157), color(143, 145, 159), color(141, 143, 158), color(132, 138, 151), color(138, 141, 157), color(163, 163, 182), color(167, 168, 184), color(168, 174, 182), color(167, 174, 183), color(167, 175, 183), color(169, 170, 208), color(177, 182, 218), color(166, 173, 209), color(152, 158, 196), color(152, 156, 194), color(152, 156, 194), color(154, 158, 195), color(169, 173, 210), color(172, 179, 216), color(171, 179, 216), color(171, 179, 215), color(175, 183, 220), color(172, 180, 217), color(175, 183, 220), color(172, 180, 217), color(155, 163, 200), color(149, 157, 194), color(151, 159, 195), color(158, 166, 202), color(177, 185, 222), color(171, 180, 215), color(176, 185, 217), color(176, 185, 215), color(172, 181, 213), color(172, 181, 214), color(158, 169, 196), color(145, 152, 180), color(147, 154, 182), color(159, 166, 195), color(179, 186, 214), color(175, 181, 207), color(179, 185, 213), color(171, 179, 206), color(168, 174, 201), color(170, 176, 200), color(164, 171, 192), color(171, 177, 195), color(166, 171, 190), color(160, 162, 182), color(153, 154, 175), color(143, 144, 164), color(143, 144, 160), color(143, 145, 159), color(143, 144, 158), color(145, 144, 158), color(145, 144, 158), color(142, 141, 155), color(144, 147, 159), color(155, 159, 171), color(145, 149, 161), color(153, 155, 168), color(169, 171, 184), color(166, 168, 181), color(159, 161, 174), color(140, 142, 155), color(140, 142, 155), color(141, 143, 155), color(144, 146, 158), color(158, 160, 172), color(174, 177, 188), color(175, 177, 189), color(167, 170, 183), color(170, 173, 185), color(174, 179, 191), color(179, 181, 218), color(179, 183, 220), color(165, 171, 207), color(150, 157, 194), color(150, 155, 192), color(150, 154, 192), color(155, 159, 196), color(174, 178, 214), color(171, 178, 216), color(169, 177, 216), color(168, 176, 214), color(176, 184, 221), color(175, 183, 220), color(179, 187, 224), color(172, 180, 217), color(153, 161, 198), color(150, 158, 194), color(151, 159, 195), color(154, 162, 198), color(178, 187, 222), color(178, 185, 220), color(177, 185, 221), color(177, 185, 219), color(171, 179, 213), color(174, 183, 216), color(168, 178, 208), color(147, 155, 184), color(148, 155, 184), color(148, 155, 183), color(166, 173, 201), color(175, 182, 210), color(180, 188, 216), color(171, 179, 207), color(178, 184, 212), color(173, 179, 203), color(167, 173, 197), color(171, 178, 196), color(164, 170, 187), color(174, 177, 197), color(163, 164, 184), color(147, 147, 167), color(146, 148, 163), color(146, 148, 160), color(145, 146, 160), color(147, 147, 160), color(148, 147, 161), color(146, 145, 159), color(141, 143, 156), color(141, 143, 156), color(141, 141, 155), color(142, 143, 156), color(154, 156, 169), color(154, 157, 169), color(144, 144, 158), color(141, 141, 156), color(143, 145, 156), color(145, 146, 155), color(158, 155, 167), color(170, 170, 179), color(174, 176, 183), color(177, 178, 188), color(170, 172, 186), color(172, 173, 189), color(178, 180, 196), color(177, 179, 214), color(174, 178, 213), color(171, 178, 213), color(151, 160, 196), color(148, 154, 189), color(148, 152, 187), color(154, 158, 193), color(171, 178, 211), color(171, 179, 216), color(174, 181, 220), color(169, 177, 215), color(174, 182, 219), color(171, 179, 216), color(176, 184, 221), color(166, 174, 210), color(151, 159, 196), color(151, 159, 195), color(151, 159, 195), color(149, 157, 193), color(164, 171, 206), color(181, 187, 220), color(176, 181, 215), color(175, 181, 215), color(174, 179, 213), color(169, 176, 208), color(157, 164, 196), color(150, 157, 186), color(149, 156, 184), color(147, 154, 182), color(147, 154, 181), color(152, 159, 187), color(155, 164, 192), color(158, 166, 191), color(167, 173, 197), color(165, 171, 195), color(172, 178, 203), color(173, 180, 198), color(170, 175, 191), color(165, 166, 186), color(152, 150, 172), color(151, 149, 170), color(150, 150, 163), color(154, 154, 167), color(161, 160, 176), color(154, 156, 170), color(149, 148, 162), color(149, 145, 160), color(145, 144, 158), color(144, 144, 158), color(144, 144, 157), color(144, 145, 158), color(142, 145, 157), color(143, 143, 159), color(146, 143, 162), color(151, 148, 164), color(153, 150, 162), color(150, 148, 158), color(147, 145, 156), color(158, 156, 166), color(182, 181, 190), color(182, 181, 190), color(179, 181, 193), color(178, 180, 194), color(178, 180, 195), color(177, 182, 216), color(168, 174, 208), color(172, 180, 215), color(156, 165, 201), color(146, 152, 187), color(145, 150, 185), color(150, 154, 189), color(166, 174, 208), color(167, 176, 211), color(169, 177, 213), color(167, 175, 211), color(176, 184, 220), color(174, 182, 219), color(173, 181, 218), color(153, 161, 197), color(149, 156, 192), color(151, 158, 194), color(151, 159, 195), color(150, 158, 195), color(152, 158, 194), color(169, 175, 208), color(179, 186, 213), color(177, 184, 211), color(155, 161, 192), color(154, 159, 195), color(151, 155, 188), color(154, 159, 189), color(162, 168, 196), color(160, 168, 196), color(158, 165, 193), color(153, 159, 188), color(150, 155, 184), color(146, 152, 177), color(146, 153, 176), color(144, 150, 174), color(148, 153, 178), color(153, 156, 176), color(155, 158, 174), color(153, 153, 174), color(153, 151, 173), color(163, 161, 182), color(170, 169, 183), color(173, 172, 188), color(181, 179, 199), color(175, 175, 190), color(163, 162, 175), color(161, 158, 172), color(149, 147, 161), color(144, 144, 158), color(145, 144, 158), color(147, 146, 160), color(148, 146, 162), color(147, 144, 160), color(156, 154, 169), color(168, 166, 180), color(177, 175, 186), color(168, 166, 177), color(149, 148, 159), color(148, 147, 158), color(172, 170, 181), color(180, 178, 190), color(182, 181, 194), color(187, 187, 198), color(178, 179, 190), color(172, 179, 213), color(171, 180, 213), color(172, 180, 215), color(162, 170, 207), color(146, 153, 189), color(144, 150, 184), color(145, 153, 186), color(162, 171, 204), color(172, 181, 214), color(175, 185, 217), color(171, 180, 214), color(177, 186, 222), color(172, 180, 216), color(154, 163, 198), color(148, 156, 192), color(151, 159, 192), color(153, 159, 192), color(153, 159, 193), color(154, 160, 195), color(155, 161, 196), color(163, 168, 200), color(180, 186, 213), color(170, 177, 203), color(153, 158, 187), color(153, 158, 190), color(153, 157, 189), color(167, 172, 202), color(180, 185, 214), color(180, 185, 214), color(180, 186, 212), color(174, 179, 207), color(173, 178, 206), color(166, 172, 196), color(165, 171, 195), color(154, 160, 184), color(150, 155, 179), color(149, 152, 172), color(146, 147, 166), color(151, 149, 169), color(160, 158, 179), color(169, 167, 188), color(176, 173, 191), color(175, 173, 192), color(181, 178, 200), color(178, 177, 194), color(170, 168, 184), color(181, 178, 192), color(168, 166, 180), color(161, 159, 173), color(155, 154, 168), color(149, 147, 161), color(149, 146, 160), color(148, 146, 159), color(150, 148, 162), color(157, 155, 168), color(170, 168, 180), color(174, 172, 184), color(169, 167, 180), color(150, 148, 161), color(154, 151, 164), color(160, 158, 171), color(161, 158, 174), color(184, 181, 195), color(182, 181, 191), color(167, 175, 208), color(169, 178, 211), color(167, 175, 210), color(166, 174, 211), color(149, 157, 192), color(142, 152, 185), color(143, 152, 184), color(152, 161, 194), color(168, 177, 210), color(172, 182, 214), color(171, 181, 213), color(182, 190, 225), color(169, 178, 213), color(149, 158, 193), color(151, 160, 194), color(153, 160, 192), color(154, 159, 190), color(153, 158, 189), color(155, 160, 191), color(156, 160, 192), color(156, 160, 192), color(162, 167, 196), color(159, 163, 193), color(156, 161, 190), color(161, 166, 195), color(169, 174, 203), color(181, 187, 215), color(183, 188, 217), color(183, 187, 215), color(184, 188, 211), color(178, 183, 209), color(181, 187, 214), color(174, 180, 204), color(179, 185, 209), color(169, 175, 199), color(171, 177, 198), color(167, 171, 190), color(149, 150, 170), color(148, 147, 167), color(157, 155, 174), color(173, 172, 190), color(172, 170, 188), color(174, 171, 190), color(178, 175, 193), color(176, 173, 192), color(166, 163, 181), color(175, 172, 187), color(169, 167, 181), color(173, 171, 185), color(174, 172, 186), color(167, 165, 180), color(164, 162, 174), color(157, 154, 165), color(150, 148, 161), color(148, 146, 158), color(150, 148, 161), color(154, 151, 164), color(163, 159, 173), color(153, 148, 162), color(153, 148, 162), color(155, 150, 164), color(154, 148, 168), color(173, 167, 186), color(187, 183, 194), color(163, 173, 206), color(171, 180, 213), color(167, 176, 211), color(168, 176, 214), color(147, 155, 191), color(143, 152, 185), color(143, 152, 185), color(152, 161, 194), color(173, 180, 214), color(179, 185, 219), color(172, 178, 212), color(181, 187, 220), color(167, 173, 205), color(152, 159, 190), color(154, 160, 192), color(155, 159, 189), color(157, 162, 191), color(168, 173, 203), color(174, 179, 208), color(171, 176, 205), color(166, 171, 201), color(159, 164, 197), color(159, 165, 194), color(162, 167, 197), color(174, 180, 208), color(179, 186, 211), color(177, 184, 208), color(179, 184, 211), color(180, 184, 212), color(181, 185, 208), color(177, 182, 208), color(178, 184, 211), color(171, 177, 201), color(175, 181, 203), color(167, 174, 193), color(168, 174, 193), color(171, 175, 194), color(155, 157, 176), color(146, 145, 166), color(150, 149, 167), color(164, 164, 181), color(179, 178, 196), color(183, 180, 199), color(182, 179, 198), color(181, 178, 197), color(169, 166, 185), color(176, 174, 189), color(172, 170, 184), color(175, 173, 187), color(175, 174, 188), color(176, 171, 187), color(184, 176, 190), color(177, 171, 184), color(168, 167, 180), color(161, 159, 172), color(159, 154, 168), color(156, 149, 164), color(153, 147, 161), color(155, 148, 162), color(157, 150, 164), color(158, 151, 166), color(158, 150, 170), color(162, 154, 173), color(174, 166, 177), color(166, 175, 207), color(169, 177, 209), color(164, 173, 205), color(158, 168, 200), color(142, 150, 183), color(145, 153, 184), color(145, 152, 181), color(148, 155, 184), color(168, 175, 204), color(179, 185, 215), color(177, 182, 213), color(185, 190, 223), color(165, 169, 202), color(156, 160, 193), color(155, 158, 189), color(160, 163, 193), color(175, 179, 206), color(178, 183, 210), color(180, 186, 213), color(189, 195, 223), color(186, 191, 221), color(175, 179, 210), color(162, 165, 195), color(160, 161, 190), color(174, 174, 205), color(184, 184, 211), color(190, 191, 215), color(186, 188, 216), color(185, 186, 215), color(188, 190, 214), color(184, 188, 213), color(184, 190, 215), color(175, 181, 203), color(179, 185, 207), color(170, 176, 196), color(171, 177, 196), color(174, 176, 195), color(167, 167, 185), color(152, 149, 168), color(147, 144, 161), color(149, 146, 165), color(173, 170, 188), color(185, 182, 198), color(181, 175, 193), color(183, 177, 193), color(170, 166, 181), color(179, 175, 189), color(176, 173, 186), color(176, 173, 187), color(177, 173, 188), color(172, 168, 184), color(180, 174, 191), color(177, 170, 186), color(177, 172, 187), color(176, 172, 185), color(169, 164, 175), color(167, 161, 173), color(156, 151, 163), color(153, 146, 160), color(155, 148, 157), color(156, 148, 164), color(157, 148, 168), color(159, 150, 167), color(159, 151, 160), color(161, 166, 196), color(158, 164, 194), color(149, 156, 186), color(142, 152, 180), color(143, 149, 179), color(147, 152, 182), color(148, 152, 181), color(148, 153, 182), color(166, 172, 199), color(181, 187, 215), color(176, 183, 211), color(170, 175, 207), color(159, 162, 194), color(160, 160, 194), color(163, 164, 195), color(173, 175, 205), color(183, 184, 212), color(182, 184, 212), color(186, 191, 218), color(189, 196, 224), color(189, 193, 222), color(198, 200, 229), color(178, 179, 210), color(162, 161, 189), color(165, 161, 193), color(166, 163, 191), color(184, 181, 205), color(188, 185, 217), color(184, 183, 212), color(188, 188, 214), color(181, 183, 208), color(182, 185, 210), color(172, 176, 197), color(175, 178, 202), color(166, 170, 192), color(166, 169, 189), color(164, 165, 184), color(162, 162, 180), color(154, 151, 170), color(146, 142, 160), color(147, 144, 159), color(154, 151, 165), color(166, 161, 173), color(166, 158, 171), color(164, 156, 170), color(156, 149, 163), color(159, 152, 167), color(156, 150, 164), color(156, 149, 164), color(155, 149, 163), color(153, 147, 163), color(155, 151, 166), color(154, 148, 163), color(155, 147, 161), color(156, 149, 159), color(154, 146, 156), color(156, 148, 159), color(153, 145, 157), color(153, 144, 157), color(154, 145, 153), color(156, 146, 160), color(158, 147, 163), color(158, 147, 163), color(158, 149, 158), color(144, 149, 178), color(143, 148, 177), color(143, 149, 177), color(143, 150, 178), color(148, 151, 181), color(159, 162, 191), color(152, 158, 186), color(151, 156, 185), color(159, 163, 192), color(176, 179, 208), color(171, 174, 203), color(160, 163, 193), color(160, 160, 192), color(165, 164, 196), color(180, 179, 212), color(179, 178, 209), color(178, 177, 205), color(181, 181, 209), color(185, 187, 215), color(184, 188, 215), color(178, 181, 210), color(188, 187, 219), color(181, 182, 213), color(163, 163, 189), color(164, 161, 192), color(163, 161, 189), color(165, 162, 187), color(168, 165, 195), color(166, 165, 193), color(167, 166, 192), color(161, 161, 188), color(161, 162, 188), color(156, 156, 179), color(155, 155, 179), color(150, 150, 175), color(147, 148, 169), color(144, 146, 164), color(143, 143, 160), color(146, 143, 161), color(145, 142, 159), color(145, 144, 155), color(149, 145, 156), color(151, 144, 155), color(155, 145, 158), color(155, 143, 159), color(151, 140, 157), color(149, 139, 154), color(148, 139, 154), color(148, 139, 154), color(148, 140, 154), color(150, 142, 156), color(151, 143, 158), color(151, 142, 156), color(151, 142, 152), color(151, 142, 151), color(152, 142, 152), color(151, 141, 151), color(150, 140, 151), color(151, 140, 150), color(154, 143, 151), color(156, 145, 155), color(155, 143, 155), color(156, 144, 159), color(158, 146, 157), color(145, 148, 178), color(145, 149, 178), color(146, 150, 179), color(146, 150, 180), color(158, 159, 189), color(167, 167, 197), color(160, 161, 190), color(156, 157, 186), color(158, 158, 190), color(161, 161, 193), color(162, 161, 191), color(161, 160, 191), color(161, 160, 191), color(162, 161, 192), color(166, 165, 197), color(162, 161, 192), color(158, 157, 188), color(161, 160, 191), color(164, 163, 194), color(166, 165, 196), color(163, 164, 193), color(166, 165, 195), color(164, 162, 193), color(162, 160, 190), color(163, 159, 191), color(163, 160, 189), color(161, 159, 187), color(161, 158, 186), color(163, 159, 186), color(162, 158, 185), color(160, 158, 185), color(157, 157, 185), color(154, 153, 181), color(155, 152, 177), color(153, 150, 173), color(148, 146, 166), color(144, 146, 161), color(144, 143, 157), color(144, 142, 156), color(144, 142, 154), color(145, 140, 151), color(149, 142, 153), color(150, 141, 154), color(152, 142, 155), color(155, 141, 157), color(149, 137, 149), color(148, 137, 147), color(146, 138, 147), color(147, 139, 148), color(151, 141, 151), color(155, 143, 153), color(156, 144, 156), color(153, 141, 152), color(154, 140, 150), color(157, 142, 151), color(156, 140, 151), color(153, 139, 149), color(155, 139, 149), color(153, 136, 146), color(144, 128, 136), color(149, 134, 139), color(153, 134, 140), color(146, 126, 134), color(150, 131, 139), color(147, 148, 178), color(148, 148, 178), color(147, 149, 178), color(147, 150, 178), color(154, 152, 181), color(157, 154, 184), color(157, 158, 185), color(158, 158, 186), color(160, 159, 189), color(161, 161, 190), color(161, 161, 188), color(161, 160, 189), color(160, 159, 190), color(159, 158, 188), color(158, 157, 186), color(157, 157, 185), color(156, 155, 185), color(159, 158, 189), color(163, 162, 193), color(163, 163, 195), color(163, 163, 194), color(166, 164, 194), color(165, 161, 190), color(162, 159, 188), color(163, 160, 189), color(163, 160, 189), color(162, 159, 189), color(163, 159, 187), color(164, 160, 184), color(163, 158, 183), color(161, 157, 183), color(161, 157, 183), color(158, 154, 180), color(157, 153, 177), color(154, 150, 171), color(152, 147, 167), color(151, 144, 159), color(149, 143, 159), color(146, 141, 156), color(149, 139, 151), color(148, 140, 152), color(151, 137, 153), color(153, 131, 149), color(152, 129, 145), color(150, 131, 139), color(147, 131, 136), color(146, 131, 138), color(144, 126, 130), color(135, 115, 120), color(124, 104, 109), color(124, 100, 108), color(129, 101, 110), color(131, 101, 111), color(131, 104, 111), color(136, 107, 115), color(137, 108, 121), color(135, 106, 120), color(127, 98, 111), color(111, 82, 90), color(87, 57, 60), color(104, 71, 72), color(106, 72, 72), color(83, 51, 50), color(93, 63, 64), color(149, 149, 176), color(149, 149, 176), color(150, 149, 176), color(152, 151, 178), color(155, 152, 179), color(158, 155, 183), color(160, 158, 187), color(161, 159, 187), color(161, 160, 189), color(161, 161, 188), color(161, 161, 186), color(161, 161, 187), color(161, 161, 188), color(159, 159, 187), color(158, 158, 185), color(157, 157, 183), color(156, 155, 184), color(159, 158, 190), color(162, 160, 191), color(162, 162, 195), color(162, 162, 195), color(164, 162, 192), color(163, 160, 187), color(162, 159, 187), color(163, 160, 187), color(163, 160, 188), color(162, 159, 187), color(163, 159, 185), color(162, 159, 181), color(161, 158, 180), color(160, 156, 179), color(161, 156, 180), color(159, 154, 176), color(156, 151, 173), color(154, 147, 167), color(153, 147, 164), color(150, 146, 160), color(150, 140, 157), color(151, 133, 150), color(136, 115, 131), color(126, 102, 119), color(121, 93, 110), color(109, 77, 88), color(100, 66, 73), color(95, 65, 67), color(96, 68, 71), color(97, 70, 74), color(95, 67, 68), color(87, 59, 60), color(76, 48, 48), color(75, 45, 43), color(74, 45, 43), color(74, 44, 44), color(77, 45, 46), color(77, 48, 50), color(74, 47, 47), color(74, 46, 46), color(73, 44, 44), color(70, 43, 38), color(62, 37, 30), color(66, 43, 33), color(66, 42, 33), color(68, 43, 35), color(79, 52, 45), color(149, 149, 176), color(149, 149, 176), color(149, 150, 174), color(152, 153, 176), color(155, 154, 180), color(156, 154, 182), color(159, 156, 185), color(162, 159, 188), color(163, 160, 189), color(163, 160, 188), color(161, 159, 188), color(161, 161, 189), color(160, 160, 188), color(158, 158, 186), color(157, 157, 185), color(157, 157, 185), color(155, 155, 184), color(159, 158, 188), color(160, 159, 191), color(162, 163, 193), color(163, 163, 192), color(164, 162, 193), color(164, 161, 190), color(162, 159, 188), color(160, 159, 187), color(161, 161, 187), color(162, 161, 184), color(162, 159, 180), color(165, 161, 181), color(165, 162, 181), color(164, 161, 180), color(166, 163, 182), color(165, 162, 179), color(157, 154, 170), color(153, 148, 162), color(153, 145, 162), color(150, 144, 161), color(151, 141, 154), color(144, 119, 122), color(104, 70, 71), color(75, 48, 49), color(73, 47, 47), color(71, 44, 41), color(68, 42, 35), color(68, 46, 37), color(67, 46, 36), color(64, 44, 35), color(64, 47, 37), color(63, 47, 37), color(62, 46, 35), color(61, 47, 34), color(62, 50, 33), color(61, 48, 31), color(61, 47, 34), color(61, 46, 37), color(60, 46, 33), color(60, 45, 29), color(62, 44, 30), color(60, 46, 29), color(55, 42, 25), color(55, 42, 25), color(53, 41, 25), color(70, 55, 40), color(80, 62, 49), color(149, 149, 173), color(150, 149, 174), color(150, 150, 174), color(151, 153, 176), color(154, 154, 180), color(157, 154, 183), color(159, 156, 185), color(160, 157, 186), color(162, 159, 188), color(163, 160, 189), color(162, 159, 188), color(161, 161, 189), color(162, 162, 190), color(164, 164, 192), color(166, 166, 194), color(164, 164, 193), color(164, 164, 191), color(162, 162, 188), color(159, 159, 189), color(160, 161, 189), color(162, 163, 189), color(163, 162, 189), color(163, 160, 188), color(162, 159, 188), color(160, 159, 188), color(160, 161, 187), color(161, 159, 183), color(160, 157, 178), color(164, 161, 180), color(173, 170, 189), color(183, 180, 200), color(184, 181, 201), color(177, 174, 192), color(156, 153, 168), color(155, 150, 164), color(156, 148, 164), color(155, 145, 161), color(156, 140, 147), color(137, 103, 95), color(94, 64, 50), color(68, 53, 38), color(69, 51, 38), color(65, 50, 35), color(57, 50, 31), color(58, 50, 31), color(59, 49, 31), color(57, 48, 30), color(56, 49, 29), color(54, 47, 27), color(54, 46, 28), color(53, 47, 31), color(55, 50, 30), color(55, 50, 29), color(52, 46, 28), color(50, 44, 28), color(51, 42, 26), color(55, 42, 27), color(57, 42, 27), color(52, 43, 25), color(50, 43, 24), color(50, 41, 23), color(50, 38, 22), color(63, 47, 32), color(76, 59, 43), color(148, 148, 172), color(148, 149, 172), color(147, 149, 172), color(150, 151, 175), color(156, 157, 182), color(155, 154, 181), color(156, 152, 182), color(158, 155, 183), color(160, 157, 185), color(162, 159, 188), color(162, 158, 187), color(162, 159, 188), color(162, 162, 190), color(165, 165, 193), color(173, 172, 200), color(179, 179, 205), color(166, 166, 190), color(160, 160, 185), color(159, 158, 187), color(164, 165, 190), color(173, 174, 197), color(174, 173, 199), color(163, 161, 190), color(164, 162, 191), color(175, 173, 200), color(178, 177, 202), color(170, 168, 191), color(160, 157, 180), color(160, 156, 177), color(158, 155, 174), color(175, 172, 192), color(183, 180, 199), color(163, 160, 176), color(153, 150, 167), color(156, 149, 168), color(155, 146, 161), color(159, 146, 157), color(155, 131, 133), color(121, 86, 79), color(73, 55, 44), color(62, 52, 39), color(65, 50, 37), color(62, 49, 34), color(59, 50, 33), color(57, 48, 32), color(56, 46, 31), color(56, 46, 31), color(55, 46, 30), color(55, 46, 30), color(55, 47, 32), color(54, 46, 31), color(53, 45, 28), color(52, 45, 26), color(49, 42, 22), color(47, 40, 22), color(46, 38, 20), color(49, 40, 22), color(52, 40, 23), color(49, 41, 22), color(48, 42, 23), color(49, 41, 23), color(51, 39, 23), color(55, 42, 26), color(66, 53, 38), color(148, 148, 174), color(146, 148, 173), color(145, 148, 172), color(160, 163, 187), color(172, 175, 200), color(159, 160, 186), color(152, 149, 177), color(156, 153, 177), color(162, 159, 185), color(169, 167, 194), color(160, 157, 184), color(166, 163, 191), color(163, 160, 189), color(157, 154, 183), color(161, 158, 187), color(170, 167, 193), color(156, 156, 180), color(157, 157, 183), color(160, 159, 189), color(178, 178, 204), color(185, 186, 209), color(191, 191, 217), color(178, 178, 206), color(180, 181, 207), color(189, 189, 212), color(191, 189, 211), color(189, 188, 209), color(165, 162, 184), color(160, 156, 179), color(157, 154, 174), color(160, 157, 177), color(167, 164, 183), color(156, 153, 169), color(155, 150, 170), color(157, 148, 169), color(168, 159, 172), color(166, 149, 158), color(143, 113, 108), color(97, 67, 58), color(65, 49, 39), color(63, 54, 39), color(67, 54, 39), color(60, 49, 33), color(57, 50, 32), color(57, 49, 33), color(55, 47, 32), color(55, 46, 31), color(53, 47, 31), color(53, 47, 31), color(53, 47, 31), color(52, 45, 29), color(52, 45, 30), color(51, 44, 27), color(50, 43, 23), color(47, 40, 21), color(47, 39, 20), color(46, 38, 19), color(45, 37, 18), color(46, 38, 20), color(47, 39, 22), color(47, 39, 22), color(48, 41, 23), color(51, 44, 26), color(52, 44, 27), color(162, 161, 187), color(160, 163, 188), color(157, 162, 187), color(167, 171, 195), color(172, 178, 202), color(160, 162, 187), color(149, 147, 171), color(153, 150, 172), color(165, 163, 187), color(180, 178, 201), color(176, 174, 197), color(181, 178, 206), color(171, 168, 197), color(156, 153, 182), color(155, 152, 181), color(156, 154, 179), color(155, 154, 178), color(155, 155, 181), color(161, 161, 190), color(188, 188, 214), color(186, 186, 211), color(192, 191, 218), color(189, 189, 216), color(189, 190, 212), color(190, 191, 211), color(191, 189, 211), color(193, 191, 213), color(169, 166, 188), color(159, 156, 178), color(159, 156, 176), color(158, 155, 175), color(157, 153, 172), color(155, 153, 167), color(156, 150, 166), color(169, 159, 178), color(181, 173, 184), color(161, 139, 138), color(124, 89, 74), color(76, 51, 40), color(66, 49, 38), color(63, 53, 35), color(63, 52, 34), color(57, 48, 31), color(55, 49, 30), color(55, 48, 31), color(53, 46, 31), color(53, 47, 31), color(52, 46, 30), color(52, 46, 30), color(49, 44, 28), color(49, 45, 29), color(51, 46, 30), color(51, 46, 28), color(53, 46, 27), color(50, 43, 24), color(50, 44, 24), color(47, 41, 22), color(45, 38, 19), color(42, 36, 18), color(42, 36, 18), color(42, 37, 18), color(46, 40, 22), color(51, 45, 26), color(51, 43, 26), color(166, 164, 191), color(170, 173, 198), color(167, 173, 197), color(167, 173, 197), color(170, 177, 201), color(157, 159, 182), color(147, 146, 167), color(148, 148, 168), color(161, 162, 182), color(170, 171, 192), color(181, 179, 201), color(182, 179, 206), color(174, 171, 199), color(154, 151, 180), color(155, 152, 180), color(155, 152, 178), color(155, 154, 179), color(161, 162, 188), color(169, 169, 198), color(186, 186, 213), color(182, 182, 208), color(188, 188, 215), color(187, 187, 212), color(186, 186, 210), color(186, 186, 209), color(184, 185, 206), color(189, 189, 211), color(179, 177, 199), color(180, 177, 199), color(172, 170, 189), color(157, 154, 173), color(155, 151, 169), color(153, 148, 164), color(160, 153, 169), color(182, 172, 188), color(174, 156, 164), color(143, 114, 107), color(100, 65, 51), color(68, 48, 33), color(61, 48, 35), color(59, 49, 33), color(57, 48, 31), color(55, 48, 31), color(54, 48, 30), color(54, 47, 31), color(53, 46, 31), color(53, 47, 31), color(53, 47, 31), color(53, 47, 31), color(52, 47, 31), color(52, 47, 31), color(51, 46, 30), color(51, 45, 28), color(53, 46, 28), color(52, 45, 27), color(51, 45, 27), color(51, 45, 26), color(49, 43, 23), color(46, 41, 22), color(44, 39, 20), color(43, 37, 18), color(44, 40, 21), color(47, 44, 25), color(50, 45, 26), color(166, 165, 191), color(168, 170, 196), color(164, 171, 195), color(164, 170, 195), color(165, 171, 194), color(148, 152, 172), color(144, 144, 164), color(144, 145, 164), color(151, 154, 173), color(166, 169, 188), color(175, 174, 195), color(181, 179, 203), color(168, 165, 191), color(153, 150, 177), color(153, 150, 177), color(153, 149, 177), color(162, 161, 186), color(182, 182, 207), color(182, 182, 211), color(188, 188, 216), color(182, 182, 207), color(190, 190, 216), color(188, 188, 212), color(186, 186, 211), color(186, 187, 210), color(182, 184, 205), color(189, 190, 211), color(181, 179, 201), color(183, 182, 203), color(182, 180, 200), color(160, 159, 177), color(150, 146, 165), color(152, 144, 161), color(161, 155, 171), color(185, 173, 186), color(167, 138, 141), color(119, 83, 73), color(75, 50, 37), color(61, 49, 32), color(57, 49, 34), color(56, 47, 33), color(54, 46, 30), color(54, 47, 31), color(55, 47, 32), color(54, 47, 32), color(55, 48, 32), color(55, 48, 32), color(53, 47, 31), color(53, 47, 31), color(53, 47, 31), color(51, 47, 31), color(51, 46, 30), color(50, 45, 29), color(52, 45, 30), color(51, 44, 29), color(52, 45, 30), color(52, 45, 28), color(51, 45, 26), color(50, 45, 25), color(48, 43, 24), color(45, 40, 21), color(44, 41, 21), color(43, 39, 20), color(51, 43, 26), color(170, 168, 194), color(171, 174, 198), color(168, 175, 200), color(169, 174, 201), color(162, 170, 190), color(143, 147, 166), color(144, 144, 164), color(145, 145, 165), color(146, 148, 168), color(162, 165, 184), color(173, 172, 193), color(174, 172, 195), color(176, 174, 198), color(154, 152, 176), color(151, 148, 175), color(153, 150, 177), color(165, 163, 189), color(181, 181, 205), color(178, 178, 206), color(183, 183, 210), color(178, 178, 204), color(181, 181, 208), color(183, 183, 206), color(184, 185, 206), color(186, 187, 208), color(179, 181, 202), color(186, 187, 208), color(180, 178, 200), color(183, 181, 202), color(182, 181, 201), color(172, 170, 188), color(149, 144, 164), color(150, 143, 159), color(158, 150, 167), color(174, 156, 167), color(150, 114, 113), color(94, 60, 50), color(64, 48, 32), color(60, 49, 32), color(57, 48, 32), color(55, 46, 31), color(55, 46, 31), color(54, 47, 30), color(54, 47, 31), color(54, 47, 31), color(55, 48, 32), color(54, 47, 31), color(51, 46, 33), color(51, 46, 33), color(50, 45, 33), color(47, 46, 32), color(48, 46, 32), color(49, 45, 32), color(48, 44, 31), color(47, 44, 30), color(48, 44, 31), color(48, 44, 30), color(47, 45, 27), color(47, 43, 24), color(46, 41, 22), color(44, 39, 20), color(41, 38, 20), color(43, 36, 18), color(72, 53, 38), color(166, 164, 187), color(165, 167, 191), color(165, 168, 195), color(165, 165, 196), color(153, 155, 182), color(142, 141, 164), color(146, 143, 165), color(146, 143, 164), color(146, 146, 164), color(160, 160, 177), color(168, 167, 187), color(168, 168, 189), color(169, 170, 193), color(150, 151, 174), color(148, 145, 172), color(156, 153, 179), color(174, 172, 195), color(184, 184, 205), color(178, 179, 202), color(182, 183, 205), color(180, 181, 202), color(183, 184, 206), color(181, 182, 202), color(182, 183, 203), color(185, 186, 206), color(176, 178, 197), color(184, 185, 204), color(178, 177, 196), color(183, 182, 201), color(180, 179, 197), color(176, 175, 191), color(149, 144, 164), color(147, 142, 157), color(152, 147, 158), color(164, 140, 144), color(124, 89, 78), color(80, 54, 39), color(68, 51, 35), color(60, 49, 33), color(56, 48, 31), color(55, 47, 30), color(54, 46, 28), color(54, 47, 30), color(52, 47, 30), color(51, 46, 29), color(52, 46, 30), color(51, 45, 30), color(50, 46, 33), color(50, 46, 34), color(50, 46, 34), color(46, 46, 32), color(47, 45, 32), color(48, 45, 33), color(48, 46, 33), color(48, 46, 33), color(48, 45, 33), color(48, 44, 32), color(48, 44, 31), color(49, 43, 27), color(47, 41, 24), color(45, 39, 22), color(42, 39, 19), color(42, 34, 15), color(100, 71, 53), color(168, 167, 189), color(166, 167, 192), color(168, 169, 198), color(162, 160, 191), color(141, 141, 167), color(143, 141, 165), color(148, 144, 166), color(147, 144, 164), color(146, 145, 161), color(150, 149, 166), color(152, 151, 172), color(164, 165, 186), color(162, 164, 185), color(144, 144, 167), color(145, 142, 167), color(155, 153, 175), color(170, 168, 189), color(177, 177, 199), color(174, 176, 197), color(176, 178, 199), color(171, 174, 195), color(173, 175, 196), color(172, 174, 194), color(172, 173, 193), color(175, 176, 196), color(168, 169, 187), color(178, 180, 197), color(173, 173, 191), color(178, 176, 194), color(173, 172, 190), color(177, 175, 191), color(152, 147, 166), color(144, 137, 153), color(148, 139, 150), color(152, 126, 123), color(117, 83, 71), color(83, 59, 46), color(65, 48, 29), color(57, 47, 26), color(54, 45, 30), color(52, 45, 31), color(53, 45, 33), color(54, 47, 32), color(51, 47, 32), color(50, 45, 32), color(51, 45, 32), color(50, 44, 31), color(50, 46, 34), color(50, 46, 34), color(50, 46, 34), color(48, 46, 33), color(47, 45, 32), color(47, 46, 33), color(48, 46, 33), color(48, 46, 33), color(48, 45, 32), color(48, 44, 32), color(48, 43, 32), color(50, 44, 28), color(49, 43, 27), color(47, 41, 24), color(43, 40, 22), color(45, 35, 18), color(99, 67, 50), color(168, 166, 191), color(166, 165, 191), color(168, 168, 196), color(151, 151, 178), color(138, 138, 163), color(142, 140, 165), color(154, 151, 172), color(156, 154, 172), color(148, 146, 163), color(147, 147, 163), color(145, 145, 164), color(150, 148, 169), color(152, 151, 171), color(147, 147, 166), color(145, 144, 163), color(160, 160, 175), color(172, 171, 187), color(180, 178, 199), color(179, 179, 201), color(178, 182, 202), color(173, 179, 198), color(174, 180, 199), color(178, 178, 198), color(176, 175, 195), color(178, 178, 198), color(172, 173, 190), color(181, 182, 199), color(174, 175, 193), color(181, 180, 199), color(172, 171, 189), color(163, 162, 178), color(148, 143, 162), color(141, 136, 151), color(154, 138, 147), color(153, 125, 116), color(135, 103, 93), color(117, 85, 76), color(109, 87, 68), color(108, 90, 63), color(100, 80, 59), color(72, 58, 42), color(56, 47, 34), color(54, 47, 35), color(51, 47, 34), color(52, 46, 35), color(53, 46, 36), color(51, 46, 35), color(50, 46, 35), color(50, 46, 34), color(49, 45, 34), color(49, 46, 32), color(47, 44, 31), color(47, 45, 31), color(47, 45, 31), color(47, 45, 31), color(48, 44, 32), color(48, 44, 32), color(47, 43, 30), color(48, 43, 27), color(48, 42, 26), color(46, 41, 24), color(41, 37, 24), color(55, 43, 26), color(117, 80, 64), color(171, 168, 194), color(170, 167, 192), color(175, 173, 198), color(151, 151, 175), color(140, 138, 164), color(143, 140, 163), color(154, 152, 172), color(159, 158, 174), color(147, 145, 163), color(146, 145, 163), color(145, 144, 162), color(147, 146, 164), color(147, 145, 160), color(147, 144, 161), color(145, 142, 161), color(152, 149, 163), color(159, 158, 170), color(177, 176, 192), color(176, 177, 197), color(177, 178, 200), color(175, 176, 196), color(173, 176, 196), color(175, 175, 195), color(171, 172, 191), color(174, 174, 193), color(168, 168, 183), color(178, 177, 193), color(171, 171, 188), color(169, 169, 187), color(148, 149, 167), color(144, 144, 162), color(142, 138, 158), color(144, 139, 153), color(162, 141, 147), color(167, 136, 128), color(163, 135, 121), color(160, 130, 120), color(163, 136, 124), color(164, 143, 123), color(174, 148, 128), color(102, 80, 65), color(56, 43, 27), color(52, 48, 32), color(50, 47, 33), color(52, 46, 35), color(51, 48, 36), color(50, 45, 34), color(49, 47, 34), color(48, 46, 34), color(47, 45, 32), color(47, 44, 31), color(47, 44, 30), color(47, 44, 30), color(47, 44, 31), color(47, 45, 31), color(46, 44, 30), color(45, 43, 29), color(46, 44, 29), color(46, 41, 28), color(45, 42, 27), color(45, 42, 28), color(40, 39, 27), color(63, 51, 36), color(129, 88, 74), color(168, 166, 189), color(167, 165, 188), color(172, 172, 194), color(155, 156, 178), color(140, 138, 161), color(144, 140, 163), color(147, 142, 164), color(146, 142, 160), color(145, 143, 162), color(146, 144, 163), color(155, 150, 171), color(164, 156, 182), color(158, 151, 172), color(148, 143, 157), color(148, 142, 157), color(149, 144, 157), color(148, 142, 153), color(163, 161, 172), color(180, 176, 193), color(179, 147, 166), color(182, 120, 136), color(185, 142, 158), color(183, 165, 182), color(181, 175, 191), color(179, 179, 196), color(170, 169, 185), color(181, 180, 196), color(168, 167, 183), color(151, 147, 165), color(143, 140, 157), color(146, 142, 156), color(148, 140, 157), color(165, 153, 166), color(182, 159, 166), color(182, 152, 149), color(179, 150, 145), color(168, 141, 142), color(160, 135, 142), color(155, 136, 140), color(154, 130, 126), color(89, 67, 53), color(75, 59, 44), color(72, 66, 50), color(69, 65, 51), color(74, 68, 56), color(65, 62, 50), color(70, 67, 53), color(64, 60, 48), color(68, 64, 52), color(61, 59, 46), color(59, 56, 43), color(55, 51, 40), color(52, 50, 39), color(49, 47, 37), color(49, 46, 36), color(45, 43, 32), color(46, 44, 31), color(47, 45, 34), color(46, 42, 31), color(43, 42, 30), color(43, 43, 30), color(38, 39, 28), color(75, 58, 48), color(129, 82, 74), color(162, 161, 182), color(159, 157, 179), color(163, 162, 184), color(153, 155, 176), color(141, 139, 160), color(143, 139, 160), color(145, 138, 159), color(148, 141, 159), color(146, 145, 155), color(148, 147, 157), color(160, 152, 162), color(168, 152, 160), color(174, 156, 156), color(171, 148, 144), color(166, 134, 132), color(163, 130, 128), color(162, 133, 128), color(160, 139, 134), color(175, 150, 152), color(180, 116, 114), color(192, 76, 69), color(186, 82, 78), color(178, 110, 110), color(165, 127, 129), color(169, 164, 176), color(158, 160, 176), color(166, 165, 183), color(150, 148, 167), color(142, 140, 156), color(144, 141, 157), color(148, 140, 151), color(160, 141, 145), color(173, 138, 142), color(166, 124, 125), color(170, 134, 136), color(170, 148, 156), color(166, 148, 160), color(162, 146, 158), color(158, 144, 156), color(139, 124, 127), color(104, 90, 73), color(117, 104, 87), color(111, 99, 84), color(91, 83, 71), color(105, 98, 87), color(86, 80, 69), color(107, 103, 94), color(91, 85, 79), color(103, 96, 92), color(97, 89, 85), color(96, 86, 80), color(99, 89, 81), color(81, 73, 64), color(79, 77, 65), color(62, 60, 48), color(61, 59, 47), color(53, 51, 39), color(53, 51, 40), color(51, 49, 39), color(48, 47, 38), color(48, 47, 37), color(42, 44, 33), color(85, 67, 58), color(132, 80, 75), color(158, 156, 177), color(155, 153, 174), color(159, 158, 179), color(149, 150, 170), color(138, 137, 156), color(142, 138, 155), color(141, 137, 158), color(141, 139, 157), color(144, 140, 155), color(159, 142, 153), color(174, 144, 134), color(185, 148, 123), color(185, 142, 113), color(160, 110, 76), color(150, 88, 58), color(143, 77, 51), color(150, 93, 69), color(153, 109, 90), color(173, 132, 114), color(193, 146, 124), color(205, 141, 118), color(205, 129, 113), color(192, 126, 107), color(180, 132, 117), color(192, 175, 182), color(174, 167, 183), color(175, 163, 175), color(151, 139, 151), color(150, 139, 151), color(155, 135, 147), color(163, 133, 143), color(173, 132, 125), color(176, 118, 106), color(150, 86, 74), color(159, 113, 113), color(141, 121, 124), color(134, 116, 118), color(132, 115, 116), color(129, 111, 112), color(125, 106, 105), color(117, 100, 87), color(114, 97, 82), color(114, 102, 89), color(85, 77, 65), color(114, 107, 95), color(93, 84, 74), color(116, 111, 102), color(95, 91, 84), color(117, 109, 105), color(105, 95, 93), color(112, 102, 96), color(115, 103, 98), color(102, 92, 85), color(120, 113, 105), color(84, 81, 72), color(103, 101, 90), color(70, 67, 55), color(85, 83, 71), color(57, 58, 48), color(61, 63, 55), color(49, 51, 43), color(47, 50, 41), color(84, 70, 58), color(129, 85, 79), color(166, 164, 185), color(164, 162, 183), color(169, 169, 189), color(152, 154, 172), color(135, 134, 150), color(138, 136, 152), color(140, 136, 153), color(144, 141, 153), color(152, 144, 152), color(177, 149, 144), color(182, 133, 104), color(185, 129, 87), color(193, 135, 82), color(141, 80, 36), color(126, 72, 38), color(142, 87, 63), color(144, 89, 66), color(151, 98, 73), color(167, 118, 89), color(183, 144, 113), color(184, 143, 122), color(172, 128, 112), color(178, 134, 112), color(181, 138, 121), color(177, 139, 134), color(160, 125, 128), color(165, 129, 126), color(177, 137, 134), color(153, 111, 110), color(145, 100, 97), color(153, 99, 98), color(154, 100, 93), color(160, 102, 86), color(152, 95, 78), color(159, 120, 112), color(128, 115, 107), color(106, 90, 83), color(107, 92, 85), color(107, 92, 84), color(105, 90, 83), color(105, 89, 82), color(101, 89, 77), color(104, 96, 85), color(99, 90, 81), color(124, 116, 106), color(121, 114, 105), color(140, 135, 128), color(132, 127, 125), color(146, 138, 136), color(150, 140, 136), color(119, 108, 102), color(104, 93, 87), color(104, 93, 87), color(115, 104, 98), color(100, 93, 85), color(107, 101, 91), color(92, 86, 75), color(103, 99, 88), color(87, 84, 72), color(95, 93, 81), color(81, 77, 67), color(77, 76, 66), color(90, 80, 71), color(104, 82, 74), color(162, 159, 177), color(159, 156, 175), color(165, 165, 184), color(148, 149, 168), color(133, 133, 148), color(136, 135, 147), color(153, 148, 161), color(174, 153, 157), color(178, 147, 137), color(179, 131, 103), color(166, 104, 65), color(157, 95, 51), color(163, 104, 56), color(158, 104, 70), color(155, 110, 87), color(154, 108, 90), color(157, 110, 91), color(167, 116, 94), color(152, 101, 77), color(163, 106, 83), color(161, 103, 86), color(149, 95, 80), color(149, 96, 83), color(149, 99, 86), color(149, 100, 86), color(148, 98, 86), color(148, 99, 88), color(163, 113, 101), color(153, 103, 88), color(145, 96, 82), color(147, 99, 84), color(146, 97, 88), color(147, 96, 87), color(144, 90, 80), color(157, 124, 117), color(126, 118, 109), color(105, 93, 85), color(105, 96, 86), color(106, 98, 87), color(104, 96, 85), color(102, 93, 86), color(95, 90, 81), color(109, 104, 94), color(101, 92, 85), color(128, 119, 115), color(131, 122, 122), color(143, 136, 141), color(137, 129, 137), color(146, 137, 139), color(151, 141, 139), color(128, 117, 112), color(96, 85, 78), color(99, 88, 81), color(97, 87, 80), color(98, 91, 84), color(95, 88, 80), color(94, 85, 77), color(98, 89, 81), color(94, 83, 75), color(105, 92, 84), color(95, 84, 76), color(103, 96, 87), color(97, 86, 78), color(102, 92, 84), color(150, 144, 162), color(156, 152, 169), color(169, 167, 183), color(147, 145, 162), color(138, 135, 150), color(138, 136, 156), color(171, 156, 157), color(163, 117, 94), color(154, 90, 62), color(164, 94, 53), color(145, 76, 37), color(140, 76, 37), color(147, 88, 51), color(162, 107, 83), color(158, 104, 87), color(156, 102, 87), color(148, 92, 77), color(143, 89, 72), color(136, 87, 69), color(149, 101, 88), color(157, 106, 96), color(152, 97, 86), color(155, 96, 84), color(152, 97, 83), color(148, 96, 82), color(147, 94, 82), color(148, 98, 84), color(146, 99, 84), color(145, 97, 84), color(142, 92, 81), color(145, 96, 82), color(146, 97, 88), color(144, 95, 87), color(143, 87, 81), color(157, 120, 115), color(134, 125, 115), color(104, 96, 88), color(119, 111, 104), color(114, 105, 100), color(114, 105, 97), color(114, 104, 101), color(108, 102, 98), color(120, 115, 106), color(122, 112, 105), color(107, 97, 95), color(114, 105, 105), color(113, 102, 108), color(109, 99, 104), color(111, 102, 100), color(99, 88, 86), color(106, 95, 92), color(84, 73, 66), color(107, 96, 88), color(81, 70, 63), color(95, 87, 79), color(86, 76, 70), color(85, 74, 67), color(97, 85, 79), color(82, 69, 61), color(99, 85, 77), color(79, 66, 59), color(103, 91, 87), color(81, 70, 66), color(104, 93, 87), color(145, 135, 155), color(149, 142, 160), color(161, 157, 174), color(147, 142, 157), color(144, 141, 154), color(149, 143, 157), color(175, 139, 116), color(159, 94, 50), color(122, 53, 21), color(137, 72, 33), color(113, 57, 27), color(111, 58, 33), color(141, 90, 62), color(155, 103, 86), color(152, 96, 86), color(155, 99, 87), color(141, 86, 72), color(138, 83, 72), color(133, 81, 73), color(147, 99, 95), color(154, 104, 98), color(151, 95, 85), color(154, 96, 83), color(152, 99, 85), color(145, 93, 79), color(142, 86, 74), color(150, 97, 84), color(148, 100, 86), color(145, 99, 86), color(136, 86, 71), color(142, 89, 73), color(151, 97, 90), color(146, 94, 88), color(143, 90, 85), color(146, 105, 98), color(137, 107, 99), color(127, 97, 93), color(143, 118, 116), color(146, 127, 129), color(153, 142, 147), color(133, 123, 120), color(115, 105, 99), color(116, 105, 98), color(125, 114, 108), color(100, 89, 87), color(121, 110, 109), color(98, 86, 85), color(116, 108, 103), color(103, 95, 87), color(100, 88, 87), color(113, 101, 98), color(91, 80, 73), color(110, 100, 91), color(82, 71, 62), color(109, 96, 87), color(84, 70, 61), color(98, 84, 76), color(93, 80, 70), color(91, 77, 67), color(99, 84, 73), color(82, 69, 59), color(98, 88, 77), color(73, 62, 51), color(93, 83, 71), color(148, 138, 155), color(147, 139, 154), color(150, 142, 156), color(147, 142, 159), color(150, 145, 161), color(159, 143, 146), color(180, 128, 88), color(163, 98, 58), color(104, 49, 19), color(103, 54, 25), color(98, 53, 30), color(97, 55, 32), color(133, 90, 69), color(159, 112, 96), color(156, 106, 95), color(155, 105, 92), color(147, 96, 82), color(132, 80, 66), color(140, 87, 80), color(149, 95, 89), color(146, 96, 87), color(147, 92, 80), color(147, 87, 77), color(150, 96, 83), color(146, 94, 77), color(138, 82, 70), color(151, 93, 82), color(157, 100, 89), color(150, 100, 85), color(135, 84, 64), color(139, 83, 67), color(166, 109, 99), color(160, 105, 100), color(154, 100, 96), color(151, 101, 94), color(147, 99, 94), color(141, 90, 87), color(141, 100, 101), color(156, 142, 149), color(164, 155, 174), color(147, 137, 142), color(100, 89, 82), color(120, 107, 106), color(115, 104, 102), color(109, 98, 97), color(123, 111, 111), color(99, 87, 87), color(124, 114, 110), color(97, 86, 83), color(111, 100, 97), color(102, 92, 86), color(96, 86, 79), color(104, 95, 85), color(84, 76, 61), color(100, 91, 76), color(75, 64, 53), color(90, 79, 69), color(71, 61, 48), color(74, 61, 48), color(69, 55, 43), color(63, 51, 37), color(63, 55, 39), color(50, 44, 27), color(53, 47, 29), color(149, 140, 158), color(148, 140, 156), color(150, 141, 155), color(153, 143, 162), color(152, 144, 164), color(166, 140, 136), color(182, 120, 71), color(139, 76, 34), color(108, 59, 24), color(94, 56, 28), color(96, 59, 35), color(89, 53, 33), color(129, 91, 76), color(167, 117, 110), color(162, 113, 106), color(162, 113, 107), color(160, 111, 102), color(135, 86, 70), color(133, 84, 68), color(141, 91, 78), color(140, 93, 82), color(147, 92, 82), color(139, 76, 71), color(153, 97, 90), color(162, 106, 97), color(147, 80, 77), color(158, 90, 88), color(170, 109, 104), color(164, 108, 101), color(138, 85, 72), color(138, 86, 72), color(169, 116, 106), color(165, 109, 105), color(165, 104, 102), color(165, 107, 99), color(155, 98, 93), color(145, 91, 89), color(161, 135, 141), color(154, 154, 170), color(152, 152, 176), color(157, 153, 166), color(123, 115, 116), color(130, 116, 118), color(110, 98, 99), color(119, 108, 106), color(114, 102, 101), color(103, 92, 90), color(115, 104, 101), color(89, 78, 74), color(106, 95, 91), color(82, 73, 66), color(89, 80, 74), color(74, 67, 57), color(68, 62, 50), color(59, 53, 41), color(55, 49, 34), color(55, 49, 36), color(48, 43, 33), color(48, 44, 32), color(47, 43, 30), color(46, 42, 28), color(47, 42, 28), color(45, 43, 28), color(44, 42, 27), color(150, 141, 160), color(151, 143, 160), color(162, 151, 169), color(156, 145, 165), color(154, 144, 163), color(167, 141, 138), color(172, 116, 72), color(148, 89, 45), color(118, 69, 35), color(93, 57, 32), color(91, 55, 33), color(84, 49, 25), color(117, 80, 62), color(164, 116, 111), color(168, 119, 120), color(167, 118, 119), color(169, 121, 118), color(158, 110, 102), color(149, 100, 89), color(149, 101, 88), color(150, 104, 91), color(161, 110, 103), color(149, 90, 85), color(161, 110, 104), color(170, 118, 116), color(160, 92, 93), color(169, 101, 103), color(170, 118, 116), color(171, 122, 120), color(149, 101, 94), color(143, 96, 84), color(166, 118, 109), color(166, 111, 111), color(166, 107, 110), color(167, 108, 105), color(150, 94, 94), color(159, 125, 135), color(160, 154, 171), color(153, 153, 175), color(153, 151, 174), color(164, 160, 172), color(117, 107, 115), color(133, 121, 125), color(103, 92, 91), color(119, 109, 104), color(91, 81, 77), color(96, 86, 81), color(81, 71, 64), color(74, 64, 57), color(69, 59, 53), color(58, 51, 41), color(59, 52, 44), color(53, 48, 39), color(51, 49, 41), color(50, 48, 39), color(50, 47, 38), color(48, 46, 36), color(48, 46, 34), color(48, 45, 33), color(47, 45, 34), color(47, 44, 33), color(47, 43, 32), color(46, 44, 32), color(43, 45, 31), color(150, 141, 160), color(160, 151, 171), color(182, 174, 192), color(166, 156, 177), color(155, 143, 165), color(166, 147, 146), color(179, 124, 87), color(138, 77, 39), color(116, 67, 39), color(94, 55, 33), color(88, 50, 30), color(87, 51, 27), color(116, 76, 58), color(160, 115, 109), color(169, 120, 122), color(166, 118, 117), color(169, 120, 116), color(161, 110, 106), color(167, 116, 112), color(175, 126, 120), color(167, 119, 116), color(171, 123, 123), color(154, 100, 99), color(166, 113, 113), color(179, 125, 128), color(166, 102, 105), color(171, 114, 113), color(170, 124, 122), color(166, 121, 120), color(151, 107, 101), color(153, 108, 100), color(170, 116, 114), color(172, 112, 118), color(167, 111, 115), color(152, 98, 99), color(155, 122, 128), color(167, 156, 176), color(161, 152, 176), color(162, 155, 180), color(156, 148, 173), color(143, 133, 148), color(108, 97, 104), color(99, 89, 89), color(85, 77, 70), color(77, 69, 62), color(64, 56, 49), color(63, 56, 48), color(57, 50, 40), color(58, 51, 44), color(55, 48, 41), color(56, 49, 39), color(56, 49, 41), color(54, 48, 44), color(51, 48, 45), color(46, 47, 40), color(46, 47, 39), color(46, 47, 38), color(45, 47, 34), color(51, 45, 38), color(50, 44, 39), color(46, 43, 36), color(46, 43, 36), color(44, 44, 33), color(43, 45, 32), color(159, 150, 169), color(169, 160, 179), color(182, 174, 193), color(179, 169, 191), color(156, 145, 166), color(167, 149, 154), color(161, 112, 81), color(111, 57, 24), color(118, 70, 45), color(111, 72, 49), color(97, 60, 39), color(93, 56, 33), color(122, 82, 64), color(169, 125, 117), color(170, 121, 125), color(167, 118, 120), color(170, 121, 121), color(157, 106, 105), color(140, 90, 86), color(158, 107, 107), color(170, 121, 125), color(171, 124, 129), color(171, 119, 124), color(171, 119, 123), color(172, 122, 124), color(162, 108, 106), color(162, 111, 107), color(168, 120, 117), color(160, 115, 115), color(154, 109, 107), color(163, 114, 112), color(173, 112, 116), color(174, 112, 118), color(158, 105, 110), color(158, 120, 133), color(162, 151, 169), color(155, 157, 176), color(166, 159, 182), color(152, 140, 165), color(109, 97, 117), color(74, 64, 72), color(74, 67, 66), color(58, 52, 45), color(60, 54, 46), color(55, 50, 41), color(55, 52, 42), color(55, 52, 42), color(55, 52, 42), color(54, 50, 44), color(53, 48, 43), color(52, 48, 40), color(51, 47, 42), color(50, 46, 42), color(49, 46, 43), color(47, 48, 40), color(45, 47, 39), color(44, 46, 36), color(44, 46, 34), color(49, 44, 38), color(48, 45, 38), color(44, 44, 36), color(46, 43, 36), color(44, 43, 33), color(41, 43, 30), color(178, 169, 188), color(179, 170, 190), color(183, 174, 193), color(186, 177, 199), color(159, 146, 168), color(165, 147, 162), color(157, 112, 88), color(105, 55, 24), color(113, 69, 48), color(107, 67, 45), color(96, 60, 38), color(90, 54, 30), color(120, 80, 62), color(171, 126, 122), color(171, 121, 128), color(170, 121, 124), color(177, 127, 131), color(167, 115, 119), color(134, 85, 79), color(131, 82, 79), color(163, 114, 116), color(170, 123, 126), color(172, 120, 128), color(173, 122, 126), color(171, 123, 124), color(169, 120, 118), color(161, 114, 109), color(158, 114, 110), color(158, 113, 113), color(159, 114, 115), color(165, 114, 119), color(173, 115, 125), color(169, 119, 126), color(169, 138, 147), color(174, 157, 179), color(167, 158, 183), color(162, 153, 173), color(135, 124, 140), color(82, 70, 79), color(61, 49, 51), color(61, 53, 52), color(56, 51, 45), color(57, 53, 43), color(55, 51, 42), color(53, 50, 42), color(52, 49, 42), color(51, 48, 40), color(51, 48, 42), color(52, 48, 45), color(52, 48, 46), color(52, 49, 44), color(51, 48, 44), color(51, 47, 44), color(51, 46, 44), color(49, 48, 41), color(46, 44, 38), color(44, 43, 33), color(44, 44, 32), color(45, 43, 35), color(44, 44, 36), color(43, 44, 36), color(45, 43, 36), color(43, 43, 32), color(40, 42, 28), color(169, 160, 177), color(172, 163, 183), color(176, 165, 187), color(179, 169, 190), color(162, 150, 172), color(159, 145, 168), color(172, 138, 124), color(125, 71, 39), color(107, 65, 44), color(96, 56, 36), color(88, 52, 30), color(93, 57, 33), color(115, 75, 55), color(168, 124, 118), color(175, 125, 132), color(175, 126, 131), color(176, 126, 134), color(171, 121, 123), color(147, 98, 90), color(141, 93, 90), color(160, 114, 118), color(174, 127, 131), color(172, 123, 127), color(171, 120, 124), color(172, 122, 123), color(170, 122, 123), color(159, 121, 114), color(158, 126, 122), color(163, 128, 128), color(164, 133, 132), color(164, 130, 136), color(169, 131, 139), color(165, 136, 148), color(143, 128, 142), color(128, 115, 131), color(122, 106, 128), color(99, 84, 106), color(70, 57, 67), color(61, 51, 54), color(59, 53, 54), color(58, 53, 50), color(57, 52, 46), color(54, 51, 42), color(54, 51, 42), color(53, 50, 46), color(52, 49, 47), color(52, 49, 43), color(52, 48, 42), color(52, 48, 45), color(52, 48, 46), color(52, 48, 45), color(53, 48, 45), color(53, 48, 45), color(53, 49, 46), color(52, 48, 44), color(51, 44, 43), color(47, 43, 39), color(46, 45, 34), color(46, 43, 34), color(44, 41, 36), color(41, 42, 36), color(41, 42, 33), color(42, 43, 33), color(40, 43, 27), color(172, 163, 180), color(176, 167, 188), color(179, 168, 190), color(185, 175, 196), color(167, 155, 177), color(158, 143, 168), color(171, 150, 155), color(137, 93, 71), color(116, 71, 47), color(105, 66, 45), color(91, 55, 32), color(98, 61, 37), color(110, 69, 47), color(161, 117, 105), color(175, 126, 128), color(173, 124, 129), color(173, 123, 132), color(174, 124, 126), color(155, 105, 98), color(153, 105, 103), color(165, 119, 123), color(174, 128, 132), color(170, 121, 125), color(168, 118, 122), color(164, 114, 115), color(162, 123, 122), color(171, 151, 152), color(171, 152, 161), color(155, 137, 150), color(149, 138, 146), color(155, 144, 152), color(140, 120, 128), color(87, 67, 79), color(72, 55, 68), color(71, 55, 65), color(66, 55, 62), color(63, 54, 58), color(63, 54, 56), color(60, 52, 54), color(57, 51, 53), color(59, 53, 51), color(56, 52, 46), color(55, 52, 43), color(54, 51, 41), color(53, 50, 43), color(53, 50, 45), color(55, 52, 44), color(54, 52, 42), color(54, 51, 44), color(53, 50, 46), color(52, 48, 45), color(52, 48, 46), color(52, 47, 43), color(49, 46, 41), color(49, 47, 42), color(49, 45, 41), color(49, 46, 42), color(47, 47, 40), color(48, 45, 40), color(48, 44, 42), color(43, 43, 41), color(41, 43, 35), color(40, 42, 34), color(39, 42, 26), color(174, 166, 181), color(178, 170, 188), color(178, 169, 189), color(186, 175, 198), color(167, 155, 178), color(159, 141, 163), color(168, 149, 165), color(161, 129, 119), color(121, 76, 56), color(117, 75, 58), color(108, 71, 53), color(103, 67, 46), color(101, 66, 42), color(135, 95, 80), color(165, 118, 114), color(168, 119, 122), color(169, 119, 126), color(168, 118, 119), color(162, 114, 108), color(161, 113, 111), color(161, 114, 120), color(163, 115, 120), color(164, 115, 117), color(165, 109, 115), color(164, 115, 119), color(159, 135, 137), color(173, 166, 177), color(173, 162, 179), color(153, 143, 160), color(144, 135, 149), color(147, 136, 146), color(156, 140, 144), color(120, 99, 99), color(72, 54, 53), color(65, 57, 59), color(61, 57, 58), color(63, 55, 52), color(62, 53, 51), color(60, 52, 52), color(57, 52, 52), color(57, 52, 49), color(54, 50, 44), color(53, 50, 41), color(53, 50, 41), color(53, 50, 43), color(54, 50, 42), color(56, 52, 43), color(55, 51, 43), color(55, 51, 45), color(55, 51, 47), color(54, 51, 47), color(54, 49, 46), color(59, 51, 48), color(85, 67, 57), color(77, 56, 50), color(92, 68, 63), color(96, 77, 67), color(66, 53, 45), color(48, 45, 39), color(45, 46, 41), color(45, 44, 42), color(44, 41, 39), color(42, 41, 36), color(40, 42, 25), color(170, 164, 179), color(176, 169, 187), color(178, 170, 191), color(185, 175, 199), color(164, 151, 175), color(156, 145, 158), color(159, 146, 158), color(179, 158, 162), color(165, 129, 115), color(123, 81, 58), color(116, 76, 58), color(109, 71, 52), color(97, 65, 40), color(104, 64, 47), color(121, 75, 67), color(136, 88, 85), color(140, 92, 91), color(138, 88, 84), color(135, 84, 73), color(135, 88, 76), color(144, 103, 98), color(150, 107, 103), color(164, 107, 106), color(167, 115, 118), color(174, 144, 144), color(172, 160, 166), color(168, 164, 175), color(172, 163, 178), color(166, 157, 171), color(155, 149, 163), color(146, 140, 156), color(148, 137, 148), color(162, 146, 140), color(110, 86, 80), color(62, 49, 46), color(58, 55, 52), color(60, 52, 49), color(59, 51, 48), color(58, 50, 47), color(55, 49, 46), color(53, 48, 44), color(51, 46, 40), color(51, 46, 37), color(53, 48, 40), color(54, 50, 41), color(54, 50, 41), color(55, 50, 41), color(55, 50, 43), color(53, 48, 45), color(53, 48, 45), color(55, 51, 47), color(54, 47, 44), color(70, 58, 54), color(148, 108, 93), color(133, 82, 74), color(151, 97, 91), color(129, 78, 67), color(111, 72, 63), color(92, 69, 63), color(69, 58, 48), color(48, 45, 35), color(44, 44, 36), color(45, 44, 34), color(40, 39, 21), color(166, 162, 180), color(168, 163, 184), color(172, 168, 190), color(176, 169, 193), color(159, 150, 172), color(155, 147, 160), color(157, 148, 158), color(168, 151, 166), color(176, 159, 161), color(149, 116, 99), color(130, 91, 70), color(112, 77, 55), color(100, 69, 44), color(96, 60, 40), color(98, 61, 41), color(105, 69, 54), color(109, 70, 58), color(113, 75, 62), color(122, 88, 71), color(155, 133, 117), color(182, 168, 166), color(171, 153, 156), color(177, 144, 150), color(182, 162, 168), color(173, 168, 176), color(171, 167, 183), color(172, 167, 179), color(175, 167, 182), color(171, 165, 179), color(175, 172, 189), color(160, 157, 173), color(154, 145, 154), color(158, 143, 150), color(150, 125, 122), color(78, 53, 46), color(57, 47, 43), color(55, 48, 44), color(56, 48, 44), color(53, 47, 42), color(50, 46, 40), color(51, 46, 40), color(52, 46, 40), color(50, 47, 38), color(51, 47, 38), color(52, 48, 39), color(52, 48, 39), color(51, 47, 38), color(52, 48, 37), color(52, 48, 40), color(52, 47, 42), color(51, 46, 40), color(52, 46, 40), color(55, 43, 40), color(129, 81, 74), color(151, 92, 85), color(136, 81, 72), color(136, 81, 70), color(131, 83, 75), color(126, 85, 78), color(124, 86, 77), color(93, 68, 52), color(53, 46, 28), color(38, 38, 20), color(41, 36, 17), color(164, 161, 179), color(162, 159, 180), color(170, 167, 189), color(177, 174, 194), color(169, 163, 186), color(152, 145, 163), color(156, 143, 162), color(157, 144, 164), color(154, 143, 161), color(163, 144, 151), color(169, 145, 140), color(145, 124, 107), color(135, 114, 90), color(135, 111, 87), color(140, 118, 98), color(142, 119, 108), color(146, 125, 112), color(152, 138, 122), color(167, 158, 153), color(172, 168, 172), color(170, 169, 180), color(170, 165, 185), color(175, 168, 188), color(165, 162, 179), color(162, 162, 179), color(165, 166, 184), color(164, 161, 177), color(170, 166, 180), color(167, 164, 178), color(175, 172, 190), color(172, 168, 182), color(175, 164, 177), color(159, 141, 153), color(159, 138, 140), color(113, 83, 75), color(67, 48, 43), color(54, 46, 38), color(51, 46, 36), color(52, 44, 36), color(51, 45, 36), color(52, 45, 38), color(51, 46, 40), color(50, 47, 38), color(52, 46, 36), color(52, 46, 37), color(52, 46, 36), color(52, 45, 36), color(53, 46, 36), color(51, 48, 36), color(49, 46, 36), color(48, 43, 35), color(51, 46, 38), color(44, 39, 33), color(91, 58, 50), color(157, 103, 96), color(142, 87, 85), color(150, 95, 97), color(139, 88, 89), color(137, 90, 85), color(125, 78, 67), color(132, 86, 70), color(97, 64, 50), color(39, 35, 15), color(39, 35, 13), color(164, 161, 181), color(158, 154, 177), color(167, 163, 186), color(171, 168, 189), color(175, 171, 193), color(162, 155, 173), color(150, 141, 161), color(152, 141, 165), color(153, 139, 157), color(153, 140, 155), color(169, 156, 168), color(177, 167, 176), color(179, 167, 172), color(174, 159, 161), color(159, 146, 150), color(154, 141, 152), color(159, 146, 160), color(172, 163, 175), color(175, 172, 187), color(169, 168, 183), color(174, 172, 188), color(171, 167, 188), color(172, 166, 190), color(170, 166, 187), color(167, 167, 185), color(171, 171, 189), color(168, 165, 183), color(172, 169, 183), color(167, 165, 180), color(176, 173, 193), color(173, 169, 185), color(175, 165, 179), color(152, 137, 146), color(158, 140, 145), color(133, 105, 100), color(74, 51, 44), color(56, 45, 37), color(53, 45, 35), color(51, 42, 33), color(52, 45, 37), color(51, 46, 41), color(50, 47, 42), color(51, 47, 40), color(53, 46, 37), color(53, 46, 36), color(53, 46, 36), color(53, 46, 36), color(53, 46, 36), color(51, 47, 36), color(48, 46, 34), color(47, 43, 33), color(47, 43, 33), color(40, 38, 27), color(73, 54, 42), color(155, 108, 102), color(149, 98, 97), color(150, 100, 105), color(149, 102, 103), color(152, 105, 101), color(132, 86, 80), color(144, 95, 84), color(113, 72, 63), color(44, 34, 17), color(39, 35, 10), color(166, 163, 183), color(160, 157, 179), color(168, 165, 187), color(170, 167, 188), color(177, 172, 194), color(171, 168, 185), color(149, 144, 165), color(148, 136, 163), color(150, 136, 157), color(151, 139, 161), color(162, 153, 177), color(167, 162, 189), color(170, 165, 188), color(171, 163, 182), color(152, 142, 155), color(147, 136, 152), color(146, 134, 152), color(158, 149, 165), color(173, 167, 188), color(164, 164, 186), color(168, 168, 190), color(168, 165, 187), color(167, 163, 186), color(167, 167, 189), color(164, 166, 185), color(170, 170, 188), color(166, 162, 179), color(169, 167, 181), color(165, 162, 181), color(175, 172, 194), color(174, 168, 186), color(166, 156, 171), color(145, 133, 148), color(150, 138, 148), color(147, 123, 119), color(89, 58, 55), color(61, 44, 38), color(53, 45, 36), color(54, 45, 36), color(52, 46, 40), color(48, 47, 42), color(48, 48, 44), color(53, 48, 44), color(55, 48, 42), color(55, 48, 38), color(54, 48, 37), color(51, 44, 34), color(49, 42, 32), color(47, 42, 31), color(43, 41, 30), color(43, 39, 27), color(46, 41, 29), color(40, 39, 26), color(69, 52, 40), color(151, 106, 105), color(153, 103, 101), color(152, 104, 104), color(150, 105, 102), color(152, 106, 101), color(143, 96, 93), color(157, 108, 106), color(134, 89, 83), color(54, 36, 19), color(38, 34, 6), color(158, 157, 175), color(157, 155, 174), color(164, 162, 181), color(164, 161, 181), color(168, 165, 185), color(167, 166, 183), color(151, 148, 173), color(142, 135, 161), color(146, 135, 157), color(154, 143, 168), color(168, 160, 183), color(164, 162, 183), color(166, 164, 185), color(157, 154, 175), color(145, 137, 156), color(146, 135, 155), color(146, 133, 154), color(150, 142, 163), color(170, 168, 188), color(167, 167, 188), color(171, 169, 192), color(171, 169, 191), color(170, 168, 190), color(171, 169, 192), color(167, 166, 187), color(172, 171, 189), color(166, 165, 182), color(170, 168, 187), color(165, 161, 181), color(171, 168, 188), color(172, 166, 185), color(153, 144, 161), color(145, 134, 149), color(146, 134, 149), color(155, 137, 139), color(115, 86, 77), color(68, 47, 40), color(54, 45, 39), color(55, 47, 38), color(52, 46, 38), color(49, 47, 38), color(50, 48, 43), color(53, 47, 43), color(52, 47, 38), color(50, 44, 34), color(48, 41, 31), color(47, 40, 30), color(45, 41, 29), color(45, 41, 29), color(45, 41, 30), color(44, 42, 28), color(46, 44, 31), color(42, 43, 28), color(62, 48, 37), color(146, 100, 103), color(156, 106, 103), color(152, 105, 99), color(151, 103, 100), color(154, 109, 105), color(147, 100, 94), color(156, 106, 104), color(148, 103, 93), color(87, 60, 36), color(54, 41, 15), color(147, 143, 162), color(154, 150, 169), color(167, 162, 182), color(164, 161, 180), color(166, 163, 182), color(165, 163, 182), color(156, 155, 176), color(138, 135, 156), color(143, 134, 157), color(153, 144, 167), color(157, 152, 174), color(160, 158, 178), color(161, 159, 180), color(149, 147, 168), color(140, 135, 155), color(142, 134, 155), color(143, 134, 155), color(141, 136, 156), color(154, 152, 171), color(159, 157, 176), color(164, 163, 182), color(165, 163, 184), color(164, 163, 182), color(166, 165, 185), color(166, 164, 184), color(168, 167, 185), color(164, 163, 181), color(171, 168, 187), color(161, 157, 175), color(166, 163, 181), color(159, 153, 172), color(143, 135, 152), color(146, 135, 151), color(144, 133, 147), color(154, 141, 150), color(132, 107, 102), color(73, 50, 43), color(58, 45, 42), color(56, 46, 39), color(54, 45, 38), color(51, 45, 37), color(50, 45, 36), color(50, 46, 36), color(48, 44, 35), color(45, 42, 31), color(45, 42, 30), color(45, 42, 30), color(46, 42, 30), color(46, 42, 30), color(46, 42, 30), color(45, 42, 32), color(46, 43, 33), color(48, 45, 33), color(56, 44, 34), color(133, 93, 91), color(162, 112, 109), color(150, 102, 99), color(152, 103, 104), color(157, 111, 109), color(153, 106, 98), color(157, 107, 106), color(150, 105, 97), color(131, 88, 71), color(108, 73, 53), color(143, 139, 160), color(147, 142, 162), color(160, 156, 176), color(153, 150, 169), color(163, 160, 179), color(162, 162, 179), color(156, 158, 175), color(137, 136, 154), color(139, 133, 155), color(147, 141, 164), color(161, 159, 179), color(160, 158, 179), color(161, 159, 180), color(153, 151, 171), color(137, 134, 155), color(140, 134, 157), color(141, 135, 156), color(140, 138, 156), color(142, 137, 158), color(140, 138, 157), color(155, 156, 173), color(165, 164, 182), color(163, 162, 180), color(166, 165, 183), color(165, 163, 181), color(167, 166, 183), color(161, 160, 178), color(168, 167, 184), color(148, 145, 161), color(142, 140, 154), color(143, 138, 153), color(143, 135, 151), color(145, 135, 150), color(145, 135, 147), color(154, 142, 157), color(143, 125, 123), color(83, 59, 50), color(61, 46, 42), color(58, 45, 39), color(55, 44, 38), color(53, 45, 37), color(48, 43, 32), color(47, 44, 32), color(47, 44, 35), color(49, 45, 35), color(48, 46, 35), color(47, 45, 35), color(48, 44, 32), color(48, 44, 32), color(47, 45, 32), color(47, 44, 36), color(47, 45, 38), color(50, 47, 41), color(48, 45, 39), color(80, 56, 51), color(130, 85, 82), color(145, 99, 97), color(155, 106, 106), color(160, 113, 110), color(155, 110, 103), color(155, 107, 108), color(155, 107, 102), color(146, 102, 88), color(134, 91, 75), color(142, 139, 159), color(141, 138, 159), color(145, 142, 162), color(140, 137, 157), color(148, 145, 163), color(161, 159, 174), color(159, 159, 175), color(138, 136, 155), color(138, 135, 156), color(140, 138, 158), color(156, 153, 174), color(149, 145, 168), color(144, 140, 163), color(143, 139, 162), color(138, 135, 157), color(147, 143, 166), color(149, 147, 169), color(141, 138, 159), color(143, 136, 159), color(139, 137, 157), color(145, 146, 164), color(161, 160, 178), color(167, 165, 183), color(162, 159, 178), color(155, 152, 170), color(168, 165, 182), color(162, 159, 175), color(167, 165, 181), color(144, 141, 159), color(139, 137, 150), color(142, 138, 148), color(147, 138, 153), color(152, 142, 160), color(144, 134, 149), color(147, 141, 156), color(150, 138, 138), color(94, 75, 60), color(60, 47, 38), color(57, 43, 38), color(55, 46, 39), color(53, 47, 39), color(51, 47, 37), color(52, 49, 39), color(51, 48, 41), color(53, 50, 43), color(54, 50, 45), color(54, 50, 47), color(53, 50, 44), color(53, 50, 42), color(53, 50, 44), color(52, 49, 47), color(49, 49, 49), color(52, 49, 49), color(51, 49, 43), color(52, 46, 39), color(62, 42, 39), color(77, 50, 47), color(105, 69, 65), color(132, 91, 87), color(147, 102, 96), color(155, 106, 101), color(155, 109, 95), color(152, 106, 91), color(140, 92, 77), color(142, 140, 156), color(141, 139, 157), color(140, 137, 157), color(140, 137, 158), color(138, 135, 152), color(141, 139, 155), color(143, 142, 158), color(137, 136, 156), color(140, 137, 158), color(139, 136, 157), color(140, 136, 157), color(141, 137, 160), color(141, 137, 160), color(142, 138, 161), color(149, 145, 169), color(162, 158, 181), color(166, 163, 185), color(151, 148, 169), color(144, 138, 161), color(143, 139, 160), color(142, 140, 158), color(148, 146, 164), color(158, 155, 174), color(146, 142, 162), color(139, 136, 155), color(149, 146, 163), color(157, 154, 171), color(150, 147, 164), color(138, 135, 150), color(139, 138, 152), color(145, 140, 153), color(162, 153, 168), color(163, 153, 171), color(147, 140, 156), color(141, 139, 151), color(156, 144, 150), color(117, 93, 87), color(61, 45, 39), color(53, 44, 38), color(53, 45, 38), color(51, 46, 38), color(52, 48, 40), color(54, 52, 45), color(56, 53, 49), color(57, 53, 49), color(58, 54, 49), color(57, 54, 48), color(54, 50, 45), color(52, 49, 46), color(51, 47, 43), color(49, 43, 42), color(46, 43, 40), color(47, 42, 39), color(46, 41, 36), color(46, 43, 39), color(50, 45, 41), color(51, 44, 41), color(52, 42, 42), color(65, 45, 43), color(88, 55, 49), color(104, 64, 51), color(113, 74, 57), color(122, 80, 67), color(114, 68, 53), color(142, 139, 158), color(142, 139, 155), color(141, 137, 155), color(140, 137, 155), color(140, 137, 154), color(137, 136, 152), color(137, 135, 151), color(137, 135, 153), color(140, 137, 157), color(141, 138, 159), color(141, 138, 159), color(142, 138, 159), color(142, 138, 159), color(142, 139, 161), color(146, 144, 164), color(152, 149, 171), color(154, 151, 173), color(152, 149, 170), color(144, 140, 161), color(144, 138, 159), color(144, 139, 161), color(142, 138, 159), color(145, 142, 160), color(144, 140, 158), color(142, 138, 156), color(142, 139, 155), color(143, 140, 156), color(142, 139, 156), color(139, 137, 152), color(145, 140, 157), color(154, 148, 164), color(161, 153, 169), color(162, 154, 171), color(159, 152, 167), color(143, 139, 151), color(152, 143, 155), color(144, 122, 122), color(78, 56, 48), color(52, 46, 38), color(53, 46, 40), color(53, 46, 40), color(53, 48, 40), color(54, 49, 43), color(53, 50, 46), color(52, 49, 45), color(52, 49, 44), color(50, 47, 39), color(48, 45, 36), color(47, 44, 34), color(46, 44, 33), color(48, 44, 34), color(45, 42, 27), color(39, 39, 21), color(37, 35, 23), color(37, 34, 24), color(40, 35, 25), color(44, 37, 28), color(43, 39, 32), color(48, 42, 37), color(52, 44, 41), color(55, 42, 36), color(65, 44, 38), color(78, 52, 38), color(72, 44, 22), color(143, 140, 158), color(142, 139, 154), color(140, 136, 155), color(142, 137, 155), color(139, 137, 153), color(139, 137, 154), color(139, 136, 154), color(138, 135, 152), color(139, 136, 156), color(142, 139, 160), color(142, 139, 160), color(141, 138, 160), color(140, 138, 159), color(140, 137, 158), color(138, 137, 155), color(140, 138, 159), color(141, 139, 161), color(141, 138, 160), color(139, 138, 157), color(142, 139, 160), color(143, 140, 161), color(141, 140, 161), color(142, 139, 158), color(142, 139, 156), color(143, 139, 156), color(143, 139, 156), color(143, 138, 154), color(140, 137, 155), color(138, 136, 155), color(146, 137, 155), color(146, 138, 154), color(144, 138, 154), color(146, 138, 154), color(148, 139, 156), color(146, 136, 153), color(146, 137, 154), color(158, 141, 147), color(109, 87, 77), color(59, 46, 41), color(55, 48, 44), color(55, 48, 43), color(55, 47, 41), color(53, 48, 41), color(50, 47, 42), color(50, 47, 40), color(49, 46, 39), color(49, 46, 39), color(49, 46, 39), color(49, 46, 36), color(45, 42, 33), color(44, 42, 29), color(40, 39, 20), color(37, 36, 17), color(40, 38, 25), color(40, 38, 25), color(39, 35, 18), color(41, 35, 18), color(39, 33, 18), color(42, 36, 25), color(50, 44, 43), color(50, 48, 46), color(52, 47, 46), color(55, 47, 37), color(51, 41, 27), color(141, 138, 156), color(140, 138, 153), color(141, 136, 156), color(142, 136, 155), color(139, 137, 153), color(138, 137, 154), color(139, 136, 156), color(140, 137, 158), color(140, 137, 158), color(140, 137, 158), color(141, 138, 159), color(139, 139, 164), color(139, 140, 162), color(141, 141, 160), color(141, 139, 161), color(142, 140, 164), color(141, 140, 166), color(141, 140, 164), color(139, 139, 161), color(141, 140, 161), color(141, 141, 161), color(139, 142, 161), color(140, 140, 160), color(139, 139, 158), color(140, 139, 157), color(142, 139, 158), color(140, 137, 157), color(138, 137, 156), color(138, 136, 155), color(144, 135, 153), color(145, 136, 152), color(142, 136, 152), color(143, 135, 151), color(142, 134, 152), color(143, 133, 153), color(142, 133, 153), color(156, 143, 155), color(132, 115, 111), color(67, 51, 46), color(56, 48, 46), color(59, 51, 48), color(59, 51, 50), color(57, 52, 50), color(55, 52, 47), color(52, 49, 44), color(50, 46, 42), color(50, 46, 43), color(50, 46, 43), color(50, 48, 42), color(46, 43, 35), color(40, 38, 25), color(37, 36, 18), color(37, 36, 18), color(43, 41, 28), color(41, 39, 26), color(40, 38, 22), color(42, 41, 23), color(43, 41, 26), color(40, 37, 25), color(44, 41, 37), color(48, 48, 44), color(49, 49, 49), color(49, 50, 49), color(49, 50, 47), color(141, 138, 156), color(140, 137, 154), color(140, 137, 156), color(140, 136, 155), color(138, 135, 155), color(139, 135, 156), color(140, 136, 159), color(139, 136, 156), color(139, 137, 157), color(140, 138, 160), color(142, 139, 163), color(140, 140, 167), color(141, 140, 166), color(142, 141, 159), color(142, 140, 162), color(142, 140, 163), color(141, 139, 164), color(141, 139, 166), color(140, 139, 163), color(140, 139, 162), color(142, 141, 163), color(141, 141, 164), color(140, 141, 161), color(139, 141, 161), color(139, 140, 161), color(140, 140, 158), color(142, 139, 158), color(141, 138, 157), color(140, 137, 154), color(141, 137, 152), color(143, 138, 153), color(141, 137, 153), color(141, 137, 153), color(142, 136, 154), color(143, 133, 152), color(144, 133, 154), color(149, 138, 154), color(151, 135, 137), color(83, 66, 62), color(57, 48, 51), color(63, 53, 54), color(62, 53, 54), color(58, 53, 53), color(56, 51, 49), color(52, 48, 45), color(49, 45, 44), color(50, 46, 44), color(50, 46, 43), color(49, 45, 41), color(46, 42, 34), color(40, 37, 24), color(38, 36, 20), color(42, 39, 25), color(46, 43, 33), color(46, 43, 31), color(44, 41, 28), color(40, 38, 25), color(40, 38, 26), color(39, 39, 28), color(44, 44, 38), color(47, 47, 45), color(49, 49, 49), color(50, 50, 50), color(49, 50, 50), color(150, 147, 167), color(141, 138, 159), color(140, 137, 158), color(139, 137, 157), color(140, 137, 158), color(138, 137, 158), color(142, 140, 162), color(150, 149, 167), color(143, 144, 162), color(138, 138, 160), color(139, 139, 166), color(139, 141, 168), color(140, 139, 167), color(142, 140, 160), color(141, 139, 161), color(143, 141, 161), color(144, 142, 165), color(142, 139, 166), color(142, 140, 162), color(142, 140, 163), color(143, 140, 165), color(144, 142, 165), color(140, 141, 162), color(139, 140, 161), color(138, 140, 161), color(140, 140, 158), color(142, 139, 159), color(142, 137, 157), color(139, 136, 155), color(138, 136, 150), color(139, 137, 152), color(139, 137, 154), color(139, 137, 153), color(140, 135, 152), color(142, 134, 152), color(144, 134, 153), color(143, 134, 151), color(152, 141, 149), color(141, 129, 132), color(95, 84, 87), color(68, 57, 57), color(61, 53, 53), color(56, 50, 50), color(56, 50, 50), color(57, 50, 50), color(53, 47, 47), color(52, 46, 46), color(49, 43, 41), color(43, 38, 34), color(45, 40, 33), color(47, 43, 34), color(49, 45, 36), color(49, 44, 39), color(50, 45, 42), color(49, 44, 36), color(40, 38, 25), color(37, 35, 22), color(41, 39, 26), color(41, 42, 31), color(45, 46, 39), color(48, 49, 46), color(49, 49, 49), color(50, 50, 50), color(50, 50, 50), color(167, 163, 186), color(154, 150, 173), color(138, 135, 157), color(140, 137, 159), color(140, 136, 157), color(138, 137, 158), color(136, 137, 158), color(140, 142, 160), color(138, 141, 159), color(136, 138, 159), color(145, 147, 173), color(154, 158, 186), color(146, 148, 176), color(139, 138, 160), color(140, 138, 161), color(143, 140, 165), color(151, 149, 173), color(156, 154, 177), color(159, 156, 177), color(159, 157, 180), color(161, 159, 184), color(160, 157, 182), color(155, 155, 176), color(155, 156, 177), color(145, 146, 167), color(138, 138, 157), color(142, 138, 158), color(141, 138, 158), color(146, 143, 164), color(146, 143, 161), color(146, 143, 159), color(146, 143, 160), color(143, 141, 158), color(142, 139, 156), color(143, 138, 155), color(143, 136, 154), color(141, 134, 150), color(143, 137, 152), color(155, 147, 160), color(159, 148, 155), color(137, 126, 131), color(121, 111, 113), color(104, 98, 98), color(77, 72, 70), color(64, 56, 56), color(56, 46, 48), color(52, 43, 43), color(50, 45, 42), color(55, 49, 44), color(52, 47, 41), color(51, 46, 45), color(52, 47, 45), color(52, 47, 48), color(54, 48, 49), color(51, 46, 37), color(41, 38, 26), color(41, 39, 26), color(44, 43, 29), color(43, 44, 32), color(43, 44, 37), color(47, 47, 45), color(48, 49, 49), color(50, 51, 51), color(50, 50, 50), color(165, 163, 182), color(165, 162, 185), color(149, 146, 169), color(151, 150, 169), color(146, 144, 165), color(138, 136, 160), color(134, 134, 158), color(137, 137, 159), color(137, 138, 158), color(137, 137, 160), color(156, 157, 182), color(162, 167, 194), color(158, 164, 192), color(147, 151, 177), color(137, 138, 166), color(140, 140, 165), color(142, 139, 163), color(154, 152, 173), color(162, 161, 181), color(164, 164, 184), color(166, 167, 190), color(169, 169, 194), color(170, 171, 192), color(165, 166, 186), color(142, 143, 163), color(137, 138, 156), color(142, 142, 160), color(149, 148, 167), color(168, 167, 187), color(162, 161, 179), color(166, 164, 182), color(164, 162, 180), color(163, 160, 179), color(163, 159, 178), color(163, 157, 177), color(161, 157, 175), color(155, 151, 166), color(155, 153, 169), color(154, 149, 164), color(160, 149, 161), color(155, 146, 156), color(156, 146, 156), color(161, 152, 158), color(153, 146, 146), color(132, 126, 126), color(111, 105, 104), color(99, 94, 90), color(118, 111, 107), color(135, 126, 123), color(89, 79, 71), color(55, 47, 40), color(52, 45, 43), color(49, 46, 42), color(54, 51, 47), color(56, 49, 43), color(47, 43, 31), color(45, 43, 31), color(47, 45, 33), color(41, 41, 32), color(41, 42, 33), color(42, 42, 40), color(49, 48, 48), color(51, 50, 52), color(49, 50, 53), color(159, 159, 172), color(168, 167, 183), color(161, 162, 179), color(161, 162, 181), color(160, 161, 182), color(153, 153, 178), color(137, 136, 161), color(137, 138, 160), color(137, 138, 160), color(139, 139, 162), color(161, 160, 185), color(165, 170, 196), color(165, 172, 197), color(162, 168, 194), color(137, 141, 171), color(138, 140, 165), color(140, 140, 163), color(140, 138, 161), color(151, 150, 171), color(167, 167, 187), color(163, 164, 187), color(168, 168, 194), color(165, 166, 187), color(145, 146, 166), color(136, 137, 156), color(146, 147, 165), color(159, 161, 178), color(161, 162, 179), color(167, 168, 186), color(160, 161, 179), color(167, 168, 186), color(164, 164, 182), color(164, 164, 182), color(166, 164, 182), color(164, 163, 181), color(166, 165, 183), color(158, 156, 173), color(163, 160, 178), color(161, 157, 174), color(155, 146, 166), color(143, 134, 153), color(143, 134, 151), color(155, 145, 157), color(168, 160, 169), color(166, 159, 166), color(164, 158, 163), color(164, 158, 161), color(168, 159, 163), color(171, 159, 167), color(157, 145, 143), color(131, 118, 112), color(115, 103, 101), color(90, 82, 80), color(59, 54, 49), color(55, 50, 43), color(45, 42, 31), color(45, 43, 31), color(46, 45, 34), color(43, 43, 34), color(46, 47, 35), color(48, 46, 42), color(53, 49, 47), color(52, 50, 50), color(50, 50, 51), color(152, 151, 168), color(164, 162, 181), color(161, 161, 182), color(161, 163, 185), color(163, 165, 189), color(162, 165, 190), color(146, 147, 172), color(136, 136, 158), color(138, 139, 160), color(141, 141, 163), color(164, 165, 189), color(167, 173, 199), color(160, 166, 192), color(165, 170, 198), color(148, 153, 181), color(136, 139, 165), color(140, 141, 166), color(142, 140, 164), color(142, 139, 162), color(150, 150, 171), color(154, 155, 177), color(148, 148, 171), color(144, 145, 166), color(139, 140, 160), color(139, 140, 160), color(145, 146, 165), color(155, 156, 174), color(164, 166, 184), color(164, 167, 184), color(162, 165, 182), color(168, 170, 189), color(165, 166, 185), color(165, 166, 185), color(166, 167, 185), color(166, 167, 185), color(169, 169, 186), color(159, 156, 174), color(166, 164, 184), color(161, 157, 176), color(148, 142, 158), color(137, 131, 150), color(148, 141, 158), color(159, 152, 168), color(160, 155, 172), color(162, 154, 169), color(161, 153, 166), color(161, 154, 165), color(162, 151, 165), color(163, 151, 167), color(166, 154, 164), color(167, 155, 160), color(167, 159, 163), color(157, 149, 151), color(107, 99, 92), color(53, 50, 40), color(41, 40, 30), color(46, 44, 33), color(49, 47, 36), color(46, 43, 32), color(49, 46, 34), color(52, 47, 42), color(54, 49, 46), color(52, 49, 49), color(51, 50, 48), color(142, 140, 162), color(155, 153, 175), color(167, 166, 189), color(158, 162, 187), color(163, 168, 194), color(160, 167, 191), color(149, 154, 179), color(141, 140, 166), color(146, 145, 167), color(149, 149, 172), color(167, 168, 193), color(171, 175, 202), color(166, 170, 197), color(170, 174, 201), color(157, 161, 188), color(137, 138, 166), color(141, 139, 167), color(143, 141, 166), color(142, 140, 162), color(140, 139, 161), color(141, 140, 162), color(143, 141, 164), color(144, 144, 165), color(146, 147, 168), color(142, 142, 163), color(142, 139, 161), color(144, 143, 163), color(154, 153, 174), color(169, 171, 188), color(170, 172, 189), color(177, 177, 198), color(177, 174, 196), color(175, 173, 194), color(176, 174, 195), color(177, 175, 196), color(173, 171, 191), color(161, 159, 174), color(165, 163, 183), color(148, 144, 166), color(139, 133, 150), color(141, 134, 152), color(153, 145, 164), color(161, 154, 172), color(155, 152, 169), color(164, 155, 172), color(163, 153, 170), color(162, 154, 170), color(162, 151, 167), color(164, 153, 169), color(166, 155, 171), color(160, 150, 162), color(160, 150, 163), color(159, 149, 158), color(152, 142, 140), color(90, 78, 71), color(47, 41, 32), color(48, 45, 36), color(49, 45, 37), color(45, 43, 34), color(47, 45, 33), color(48, 47, 40), color(51, 50, 46), color(51, 49, 52), color(50, 50, 48), color(142, 139, 164), color(143, 140, 165), color(163, 161, 187), color(167, 168, 194), color(168, 170, 195), color(167, 172, 197), color(149, 153, 178), color(147, 146, 172), color(151, 148, 172), color(166, 166, 191), color(176, 177, 205), color(176, 177, 206), color(171, 172, 200), color(170, 172, 200), color(160, 164, 191), color(149, 150, 178), color(144, 141, 169), color(142, 139, 164), color(142, 140, 162), color(144, 142, 165), color(145, 142, 167), color(143, 141, 164), color(149, 150, 171), color(159, 160, 181), color(155, 154, 175), color(144, 142, 163), color(147, 144, 166), color(146, 145, 166), color(156, 155, 172), color(171, 170, 187), color(178, 176, 197), color(173, 171, 192), color(168, 166, 187), color(163, 160, 181), color(158, 156, 177), color(154, 152, 172), color(148, 145, 163), color(148, 145, 164), color(141, 138, 159), color(140, 134, 157), color(140, 134, 153), color(145, 140, 157), color(157, 153, 170), color(160, 154, 172), color(168, 158, 176), color(164, 156, 172), color(158, 155, 170), color(159, 153, 167), color(156, 149, 164), color(156, 149, 164), color(150, 142, 157), color(149, 142, 157), color(148, 140, 155), color(157, 149, 155), color(153, 143, 143), color(104, 95, 90), color(58, 51, 42), color(50, 43, 36), color(46, 43, 34), color(45, 43, 31), color(48, 46, 39), color(52, 48, 46), color(53, 48, 51), color(52, 50, 48), color(143, 142, 167), color(144, 142, 167), color(161, 157, 183), color(174, 173, 200), color(165, 167, 192), color(169, 172, 198), color(152, 155, 180), color(153, 152, 177), color(154, 151, 177), color(168, 168, 196), color(172, 173, 202), color(172, 172, 200), color(172, 171, 197), color(174, 173, 200), color(164, 166, 193), color(164, 166, 194), color(150, 150, 178), color(141, 140, 166), color(142, 140, 162), color(144, 141, 166), color(144, 142, 169), color(142, 142, 166), color(156, 157, 178), color(158, 160, 182), color(160, 162, 184), color(152, 151, 172), color(151, 150, 171), color(151, 149, 170), color(150, 148, 167), color(154, 152, 170), color(158, 156, 177), color(154, 152, 173), color(151, 149, 170), color(151, 149, 170), color(150, 148, 169), color(156, 154, 175), color(157, 154, 175), color(159, 156, 176), color(159, 157, 176), color(149, 149, 169), color(135, 135, 157), color(134, 133, 153), color(142, 139, 156), color(147, 140, 159), color(158, 151, 168), color(158, 155, 169), color(146, 144, 158), color(147, 143, 157), color(145, 140, 154), color(145, 138, 152), color(144, 139, 151), color(145, 139, 152), color(145, 138, 152), color(145, 137, 150), color(151, 142, 149), color(158, 149, 147), color(106, 97, 88), color(54, 44, 37), color(49, 43, 35), color(44, 42, 30), color(49, 46, 39), color(52, 48, 46), color(54, 48, 51), color(53, 50, 49)]
    
    sketch draw {
      loop x through (0, rows) {
        loop y through (0, cols) {
          prepare color as me.get(x * rows + y)
          Canvas.fill(x, y, color)
        }
      }
    }
    
    draw()
    

    And figure out who I am.

    Orpheus is slightly taken aback. Erm, crepey. Sorry, creepy. Her stomach rumbles. Sorry. Just a little bit hungry. How does this mysterious sender know everything that is happening, in realtime? Guess the only way to find out is to write that programming language.

    Hm. Orpheus could go cook pancakes, or she could figure out this easel and who in the hecktie-neckties this mysterious person is. Or she could do both.

    She's never written a programming language before, but then, I presume you haven't, either. This is an invitation for you to join Orpheus' pancake party.

    Go cook your pancakes! We'll be back in half an hour.

    Ok. Now that we both have a steaming pile of pancakes, let's take a look at Easel:

    I bet you can already start to see the different features Easel has. Orpheus can, although it's ended up in a lot of dripping syrup over the letter.

    Variables are created with the prepare keyword and as keywords, like prepare [name] as [value]. We can have strings, numbers, booleans, or arrays.

    Comments are dictated by the tilde symbol. Me and Orpheus have decided that it looks pretty similar to her eyebrows when she's surprised by something, and comments help you when you're surprised by a piece of code, so we've decided that it's a pretty effective way of annotating our comments.

    Structs are basically maps/objects/dicts/whatever you want to call them with a predefined list of keys. Defining a struct looks something like brush Cell has { x, y, live }. Creating a struct looks something like prep Cell(x: 1, y: 1, live: false). Get it? You're prepping a brush. Hehe.

    We call functions sketches so we define them with the sketch keyword. If a function takes in parameters, you'll need to use the needs keyword before defining those.

    These are pretty obvious.

    sketch includes needs (array, value) {
      loop i through (0, array.length) {
        if (array[i] == value) {
          finished true
        }
      }
    
      finished false
    }
    
    prepare test as ["hello", "world", "fox"]
    
    if (!(false && includes(test, "foxes"))) {
      ink("NOT (false AND includes foxes in test) evaluates to true")
    }
    

    Easel also has support for the usual operators: AND &&, OR ||, and NOT !.

    Orpheus wipes her mouth with her hands and pushes her plate aside. Let's start doing this! We're going to make sure we have the basics first. It's like building Lego, really. The first step is to open dat terminal and start a new project:

    mkdir easel
    cd easel
    npm init -y
    

    Of course, if you're on a Chromebook or some device of that sort, and you've been following along with our built-in editor, you won't be able to follow this step or the following ones. Just skip down to writing the actual code.

    Open up the package.json that's been created, and add this extra line that'll let us use the modern import syntax.

    {
      // ...
      "type": "module"
    }
    

    Next, let's start writing some code! Here's some boilerplate code to go inside easel.js:

    Let's also get some error handling in there. It'll be useful later on for checking if errors are being thrown by our programming language or by JavaScript. Create a new file named stdlib.js and throw this in there:

    You can run node easel.js test.easel now and it's rather boring. We could probably spruce it up a bit by writing that programming language. Let's get a-moving!

    The spy who flunked it: Kurt Gödel's forgotten part in the atom-bomb story

    Hacker News
    www.nature.com
    2024-05-16 15:27:52
    Comments...
    Original Article
    Kurt Goedel and Albert Einstein. Princton. Photography. 1950.

    Kurt Gödel (left) and Albert Einstein in Princeton, New Jersey, in 1950.Credit: Imagno/Getty

    The 2023 film Oppenheimer narrates the story of the atomic bomb entirely from the perspective of its eponymous hero. But there’s much that is left out. It is well-known that US efforts to build the bomb started years before physicist J. Robert Oppenheimer took over as director of the Manhattan Project at Los Alamos Laboratory in New Mexico in 1943. That project was initiated by fellow physicist Leo Szilard. Concerned by the pace at which nuclear-science discoveries were being made in Germany, Szilard persuaded Albert Einstein in August 1939 to write a letter to then-president Franklin D. Roosevelt, warning him of the risk of an atomic bomb in Adolf Hitler’s hands.

    But Szilard wasn’t the only physicist to try to use Einstein’s prestige to alert the president. Viennese physicist Hans Thirring independently arrived at the same idea. Thirring’s attempt petered out, but deserves a footnote in history, if only because it involves none less than Kurt Gödel in the unexpected role of a secret agent. The tale has all the trappings of an Alfred Hitchcock movie.

    Vienna Circle

    Gödel, a mathematician and philosopher, was called by Einstein “the greatest logician since Aristotle” — a phrase coined in 1924 that stuck. Yet when Kurt enrolled at the University of Vienna 100 years ago, he started out in physics. Relativity was all the rage then, and Gödel’s professor, Hans Thirring, was an expert. He had just co-discovered an important feature of the Universe — that the gravitational field of a spinning ball (such as Earth) differs from that when the ball is still, now known as the Lense–Thirring effect. The difference is tiny, however, and it wasn’t measured until 80 years later, using first-rate space technology.

    The avant-garde philosophers of the Vienna Circle, a group of self-appointed heralds of the scientific world view, also influenced Gödel and turned his mind towards the foundations of mathematics. By age 25, he had discovered his ‘incompleteness theorem’, which states roughly that there is no consistent formal system in which all arithmetical propositions can be proved. This was an epoch-making result.

    Gödel became one of the first postdocs to be invited to the newly founded Institute for Advanced Study in Princeton, New Jersey. But when he returned from the United States to Vienna in 1934, he had a nervous breakdown. Indeed, bouts of persecution mania and fears of poisoning would dog him for the rest of his life. Thus, during the 1930s, Gödel shuttled between seminars in Vienna, the Institute for Advanced Study and mental-health clinics.

    His mathematical work shifted to ‘set theory’, especially the theory of infinites. And again, he achieved a landmark result. He obsessively pursued the ‘continuum hypothesis’, which states roughly that the infinitude of real numbers is next largest to that of natural numbers. Gödel managed to show that this hypothesis is compatible with the axioms of set theory — a brilliant feat. His shorthand notebooks from that period, which are currently being deciphered and published, show that he pursued in parallel a stupendous range of interests, including parapsychology and quantum mechanics — two fields that also engrossed his former physics professor, with whom he had never lost touch.

    Thirring was charismatic, popular with his students and brim-full of ideas. He had invented a cape-like ‘hover-coat’ for skiers and held a patent on films with sound. He, too, was in close touch with the hard-nosed ‘positivists’ of the Vienna Circle, who thought that knowledge comes only from experience and logical analysis. But this did not dampen Thirring’s interest in paranormal phenomena.

    To hold a truly scientific world view, one must be ready to swim against the mainstream. This applies to political tides, too: Thirring was one of the woefully few in Vienna to stand up firmly against the flood of Nazi students after Hitler came to power. The ‘brownshirt’ storm troopers — the paramilitary wing of the Nazi Party — could not accuse him of being of Jewish descent, but his support of Einstein (who was Jewish) was bad enough in their eyes. And in 1938, as soon as Austria was annexed to the Third Reich, 50-year-old Thirring lost his professorial chair. But he did not lose contact with former colleagues. And he was well aware that, in physics labs everywhere, everyone was talking about nuclear fission — the division of the atomic nucleus and the resulting release of energy — which had just been discovered in Hitler’s Berlin.

    Mounting concern

    In the summer of 1939, after reading an article in the scientific journal Die Naturwissenschaften by Siegfried Flügge — later a leading member of Uranverein, the ominous ‘Uranium Club’ that was behind the German effort to build a nuclear bomb — Thirring had learnt enough to feel that the US government should be warned. Like Szilard, and at about the same time, he came up with the idea to use Einstein to alert Roosevelt. But how could Thirring contact Einstein? The Gestapo, the Nazi secret police force, would intercept every phone call or letter from Vienna to Princeton, where Einstein lived.

    This is when Thirring heard that Gödel happened to be on a brief visit to Vienna, to see his mother and take his wife Adele back with him to Princeton. Why not use Gödel as a secret messenger to reach Einstein? Thirring entrusted Gödel confidentially with the task of warning Einstein about Hitler’s bomb.

    Unfortunately, the plan proved ill-fated. Gödel’s departure was delayed for nearly four months by an avalanche of bureaucratic hurdles. At times, escape looked hopeless.

    Difficulties and chicanery piled up. After Germany annexed Austria, Gödel automatically became a German citizen, and had to return his old passport. The visa for multiple re-entry into the United States was in the old passport, and the hopelessly overtaxed US consulate could not simply transfer it to the new one. Gödel had to re-apply to enter the United States, and thus join a queue of thousands who were desperately trying to escape from the Reich.

    The Ski-Sailing” invented in Austria has now also entered Switzerland, where the famous ski resort at St. Moritz has been demonstrated. Photo: An impression of the new sport, St. Moritz, Switzerland January 1938.

    The ‘hover-coat’ designed by Hans Thirring.Credit: BNA Photographic/Alamy

    Gödel had also lost his lectureship, and thus his professorial status. The Nazis were re-structuring academic life, and Gödel’s former contacts aroused their suspicion. Would he be able to represent ‘New Germany’ abroad? A minor bureaucrat had found fault with Gödel’s previous journey to the United States; the revenue service questioned the few hundred dollars on his account. It seemed he was of Aryan descent, but where was his grandparents’ marriage certificate, and that of his wife’s grandparents? Administration ran amok.

    As one Viennese eye-witness, the writer Leo Perutz, described it: “Obscure offices that no one had ever heard of before would suddenly emerge from hiding, would make their demands imperiously known, and would insist on being satisfied, or at least noticed and consulted.”

    Gödel and his wife had moved out of their flat in September — but because they couldn’t leave the country as planned, they had to look urgently for new lodgings. On top of it all, a mustering commission of the German armed forces, the Wehrmacht, declared Gödel fit for garrison duty. It was like a bad dream. Indeed, many years later, he would still be plagued by nightmares about being trapped in Vienna.

    Perilous flight

    In the end, thanks to vigorous interventions by mathematician John von Neumann and others at the Institute for Advanced Study, the visas came through in early January 1940. By then, Hitler’s troops had overrun Poland, and Europe was torn apart by war. The United States wasn’t involved yet, and some neutral vessels still plied the Atlantic Ocean. However, they were routinely searched by Allied warships, and all German passengers were sent to internment camps. On top of that, there was the risk of running through the periscope sight of a trigger-happy German U-boat skipper. Obviously, an Atlantic crossing would not do.

    The only way out was the other way around: eastward, through Siberia and the Pacific. A tight-rope act, but just feasible. The Soviet Union and Japan were both waging wars, but not against Germany, or the United States, or each other.

    Thirring’s plan was still alive, and on the eve of Gödel’s departure, the dauntless physicist met him and relayed the secret message. It was by no means sure that it would reach its destination. At each hitch, the Gödels risked being stopped. They had a long way to go.

    To Berlin first, for some final stamps on their documents. From there, across half of Prussia, to reach occupied Poland, with its bombed railway stations and baleful troop transports clustering the sidings. On through twilight Latvia and Lithuania, and into Joseph Stalin’s Soviet Union. Each border crossing took hours. Each luggage search was nerve-racking, and each knock on the compartment door was ill-boding. Finally in Moscow, the Gödels spent a night in the gigantic Hotel Metropol, a gloomy block housing mostly Communist Party delegates, some anxiously awaiting their upcoming trials for disloyalty. These were the heydays of communist purges and spy scares.

    At Yaroslavski station in central Moscow, the Gödels boarded the Trans-Siberian Express. Its other terminus was more than 9,000 kilometres away, in Vladivostok. During the seemingly endless nights of ice and snow, the train accumulated a colossal delay. After finally reaching Vladivostok, they had to take a ship — often running behind schedule — to Yokohama, Japan. While in Berlin, Gödel and Adele had booked a cabin in the SS President Taft for the leg from Yokohama to San Francisco, California. Inevitably, they missed the ocean liner, and had to wait for two weeks for the next one, the SS President Cleveland.

    Once aboard, things started picking up. A day’s stopover in sight of Oahu, Hawaii, came as a welcome change from icy Siberian train platforms. The coast of California rising from the horizon was the climax. Years later, Gödel would still enthuse: “San Francisco is absolutely the most beautiful city I have ever seen.” There was just one last formality before landing: the immigration papers, with their obnoxious queries — “Have you ever been a patient in an institution for the care and treatment of the insane?” No.

    Another railway ticket; another trans-continental ride, now in an elegant Pullman sleeper train; and the safe haven of Princeton at last, after almost two months of travelling. Gödel’s long-time friend, economist Oskar Morgenstern, reported in his diary on 12 March 1940: “Gödel arrived. This time with wife. Via Siberia. When asked about Vienna: The coffee is wretched!”

    After having circled three-quarters of the globe, Gödel had reached Einstein’s doorstep. He could finally fulfil his mission. Despite all obstacles, Thirring’s message had arrived. Quite conceivably, it could save the world.

    And this is where Gödel failed.

    He confessed it to Thirring more than three decades later: on meeting Einstein, Gödel had not transmitted the warning, but merely “greetings from Thirring”. The bizarre excuse: he, Gödel, had felt that a nuclear chain reaction would be possible only “in a distant future”.

    Lost legacy

    What did Thirring make of this? We can only wonder. He had outlasted the Third Reich unbowed, reassumed his professorship and become one of the firmest voices against nuclear armament. By then, however, Einstein’s letter to Roosevelt, prompted by Szilard, was public knowledge. Thirring’s son Walter, who was also a theoretical physicist and a colleague of mine in Vienna, later told me that his father was always uneasy about his (imagined) role in the bomb project. Hans, who was an inveterate pacifist, saw himself as a link in the causal chain that had led to the horrors of the atom bombs dropped on Hiroshima and Nagasaki in Japan in 1945. Only in 1972, shortly before his death and already weakened by a stroke, did he learn that his message had never reached its goal.

    As a secret agent, Gödel had proved a dud. But then again, fortunately, the spectre of Hitler’s atomic bomb had turned out to be no great shakes either.

    Microsoft: Windows Server 2019 updates fail with 0x800f0982 errors

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-16 15:25:28
    ​Microsoft has acknowledged a new known issue causing this month's KB5037765 security update for Windows Server 2019 to fail to install with 0x800f0982 errors. [...]...
    Original Article

    Windows Server

    ​Microsoft has acknowledged a new known issue causing this month's KB5037765 security update for Windows Server 2019 to fail to install with 0x800f0982 errors.

    "Windows servers attempting to install the May 2024 security update (KB5037765), released May 14, 2024, might face issues during the installation process," Microsoft explains on the Windows health dashboard.

    "The installation might fail with an error code 0x800f0982. This issue is more likely to affect devices that do not have en_us language pack support."

    This confirmation comes after many Windows admins reported seeing install failures when trying to deploy cumulative updates released during the May 2024 Patch Tuesday on Windows Server 2019 systems.

    As German tech blogger Günter Born first reported, these widespread issues impact devices running non-English Windows Server installations.

    "In our test environment KB5037765 failed on all (german) Windows Server 2019 machines with error 0x800f0982. 5 servers total/different sites (both dcs + member)," one admin said.

    Unofficial workaround available

    While Microsoft has yet to provide an official workaround for these install problems and is still working on a fix, installing the en-US language pack on affected systems using the LPKSetup tool will likely allow the buggy KB5037765 security update to be installed.

    To do that, you will have to go through the following procedure:

    1. Download the ISO image with the language packs from here.
    2. Mount the ISO image.
    3. Press the Windows logo key+R to open the "Run" dialog box. Type "lpksetup.exe", and then select "OK."
    4. Step through the wizard to select and install the English language pack (you can also use the LPKSetup command-line options to install the language pack using an elevated command prompt.)

    This week, Redmond also fixed a known issue caused by the April 2024 Windows security updates, which broke VPN connections across client and server platforms.

    The company also addressed a bug that triggered domain controller reboots and NTLM authentication failures after installing last month's Windows Server security updates.

    D3 in Depth

    Hacker News
    www.d3indepth.com
    2024-05-16 15:18:07
    Comments...
    Original Article

    BOOKS & COURSES

    D3 Start to Finish book cover

    Visualising Data with JavaScript teaches you how to build charts, dashboards and data stories using Chart.js, Leaflet, D3 and React.

    Find out more

    "One of the best D3 books I've read. The contents are very clear, it is easy to follow and the concepts are very solid."

    Javier García Fernández

    Learn how to make a custom data visualisation using D3.js.

    Find out more

    Learn the fundamentals of HTML, SVG, CSS and JavaScript for building data visualisations on the web.

    Find out more

    NEWSLETTER

    Get book discounts and receive D3.js related news and tips.

    Subscribe

    Learn D3.js from the ground up

    Llama3.np: pure NumPy implementation of Llama3

    Hacker News
    github.com
    2024-05-16 14:53:22
    Comments...
    Original Article

    llama3.np

    llama3.np is pure NumPy implementation for Llama 3 model. For an accurate implementation, I ran the stories15M model trained by Andrej Karpathy.

    Usage

    $ python llama3.py "I have a dream"
    """
    I have a dream. He dream of a big, beautiful garden full of flower and tree. He dream of playing with hi friend and eating yummy snack.
    One day, he wa walking in the garden when he saw
    
    Token count: 50, elapsed: 1.53s, 33 tokens/s
    """

    Citing llama3.np

    If you use or discuss llama3.np in your academic research, please cite the project to help spread awareness:

    @misc{llama3.np,
      title = {llama3.np: pure NumPy implementation for Llama 3 model},
      author = {Sang Park}, 
      howpublished = {\url{https://github.com/likejazz/llama3.np}},
      note = {llama3.np, MIT License}
      year = {2024},
    }
    

    References

    Thank you to the creators of the following libraries and tools and their contributors:

    I got a lot of information from the articles below:

    License

    MIT

    Llama 3 implemented in pure NumPy

    Hacker News
    docs.likejazz.com
    2024-05-16 14:53:22
    Comments...
    Original Article

    Understand the exact structure with working implementation of the Llama 3 model.

    May 16, 2024

    Overview

    Llama 3 model unveiled at Meta is creating a buzz.

    As expected, the scale and performance is overwhlming. 24K GPUs, 15T training data, 10M instruction data, 1.3M GPU hours, it’s all overwhelming. One interesting fact is that the model structure hasn’t changed. Of course, Llama 3 have changed to using GQA, but this was already implemented in Llama 2 70B, so it’s practically the same model structure.

    We’ll let it run for an accurate implementation, and we’ll use only NumPy to make the model structure more intuitive to understand. We use the stories15M model that Andrej Karpathy trained while creating llama.2, by converting it to a NumPy compressed format using a converter. We will actually read in the model that Karpathy trained with the Llama 2 structure and implement it as executable code. One thing to note is that the stories15M model does not use GQA, so while we implement GQA in our code but not apply it to model behavior.

    Structure

    Llama 3 model structure is exactly same with the 42dot LLM, so we import the illustration from the 42dot Blog, we’ll get the following:

    The Model has the following parameters:

    # Model params for ./stories15M.model.npz
    dim: int                    = 288       # D
    n_layers: int               = 6
    n_heads: int                = 6         # QHN, HN, HD = 48
    n_kv_heads: Optional[int]   = None      # KVHN = 6
    vocab_size: int             = 32000     # VS
    max_seq_len: int            = 256       # M
    max_new_tokens: int         = 50
    

    The designations D, HN, HD, VS, M etc. in the comments are ised to manage the shape of each variable in code. Also note that unlike the 24x in the model illustation, stories15M model has 6 layers, so it iterates 6x.

    RoPE #1

    The first step is to precompute cos and sin for RoPE embedding. These values are later used by Q and K. This calculation only needs to be done once for every request, so it can be cached. The size is HD(48)//2, which is an exponential multiple of base(10000), so it can be a larger value, but the maximum value is never more than 1, so it is converted to a scaled value between 0 ~ 1, and then again to a value between \(1 \sim \frac{1}{10000}\).

                            np.arange(0, 48, 2)  # [24,]
      1.0 / (base(10000) ** ([0, 2,          ..., 44,         46] / 48))
    = 1.0 / (base(10000) **  [0, 0.04166667, ..., 0.9166667,  0.958333344])
    = 1.0 /                  [1, 1.4677993,  ..., 4641.59,    6812.9194]
    =                        [1, 0.68129206, ..., 0.00021544, 0.00014678]
    

    The result of the calculation is np.outer multiplied by max_seq_len(256), and then cos and sin are calculated.

    # [256,] x [24,] = [256, 24]
    freqs = np.outer([0 ~ 255], [1, 0.68129206, ..., 0.00021544, 0.00014678])
    self.freqs_cos: Array["M, HD//2"] = np.cos(freqs)
    self.freqs_sin: Array["M, HD//2"] = np.sin(freqs)
    

    The heatmap of cos and sin looks like this:

    The stories15M model is max_seq_len(256), but I think it could scale up to 8K if we utilize all values up to horizontal axis 24.

    RMSNorm

    RMSNorm normalizes activation values based on the Root Mean Square of the activation values, as opposed to using traditional Mini Batch or Layer statistics. This has the advantage of scaling activation consistently, regardless of Mini Batch size or Layer. Like other normalization techniques, it also has separate training parameters.

    1

    The formula implementation is as follows:

    z: Array["B, L or 1, 1"] = (x ** 2).mean(-1, keepdims=True) + self.eps
    z: Array["B, L or 1, D"] = x / np.sqrt(z)
    return z * self.weight
    

    QKV

    The way to calculate QKV is to matmul one weight in GPT and then split it, but Llama have their own weights for QKV, so we need to matmul them separately. Then, for Multi-Head Attention, we reshape each one to separate them by Multi-Head.

    # QKV
    xq: Array["B, L or 1, D"] = x @ self.q_weight
    xk: Array["B, L or 1, D"] = x @ self.k_weight
    xv: Array["B, L or 1, D"] = x @ self.v_weight
    
    # ["B, L or 1, D"] -> ["B, L or 1, QHN or KVHN,  HD"]
    xq: Array["B, L or 1, QHN,  HD"] = xq.reshape(B, L, self.n_local_heads, self.head_dim)
    xk: Array["B, L or 1, KVHN, HD"] = xk.reshape(B, L, self.n_local_kv_heads, self.head_dim)
    xv: Array["B, L or 1, KVHN, HD"] = xv.reshape(B, L, self.n_local_kv_heads, self.head_dim)
    

    RoPE #2

    Now it’s time to actually apply the RoPE using the values we calculated earlier.

    2

    RoPE is a new type of position encoding technique that has the characteristics of both absolute and relative, and performs well because it has the characteristics of both. It only applies to Q and K, dividing each input by the sum of its parts, then multiplying by cos and sin, adding and subtracting the results, and returning the sum back to reshape.

    xq_out_r: Array["B, L or 1, QHN,  HD//2"] = xq_r * freqs_cos - xq_i * freqs_sin
    xq_out_i: Array["B, L or 1, QHN,  HD//2"] = xq_r * freqs_sin + xq_i * freqs_cos
    xk_out_r: Array["B, L or 1, KVHN, HD//2"] = xk_r * freqs_cos - xk_i * freqs_sin
    xk_out_i: Array["B, L or 1, KVHN, HD//2"] = xk_r * freqs_sin + xk_i * freqs_cos
    
    xq_out: Array["B, L or 1, QHN,  HD//2, 2"] = np.stack([xq_out_r, xq_out_i], axis=-1)
    xk_out: Array["B, L or 1, KVHN, HD//2, 2"] = np.stack([xk_out_r, xk_out_i], axis=-1)
    xq_out: Array["B, L or 1, QHN,  HD"] = xq_out.reshape(xq_out.shape[:-2] + (-1,))
    xk_out: Array["B, L or 1, KVHN, HD"] = xk_out.reshape(xk_out.shape[:-2] + (-1,))
    

    RoPE are applied after the Q and K have been multiplied by the weights in the attention mechanism, while in the vanilla transformer they’re applied before.

    KV Cache

    3

    Since the GPT-style generative model is Masked Attention, it is possible to KV Cache. Since the previous result will always be the same, regardless of what comes after it, since we are not allowed to see the next word, we can cache K and V, and Q only needs to compute the last value. The cache is held by max_seq_len(256), so the result of the calculation is put in and then extracted back to the only current length.

    # KV Cache
    self.cache_k[:B, start_pos: start_pos + L] = xk
    self.cache_v[:B, start_pos: start_pos + L] = xv
    ks: Array["B, L, KVHN, HD"] = self.cache_k[:B, : start_pos + L]
    vs: Array["B, L, KVHN, HD"] = self.cache_v[:B, : start_pos + L]
    # (1, 256, 6, 48) -> (1, 5, 6, 48)
    
    # GQA
    xk: Array["B, L, HN, HD"] = repeat_kv(ks, self.n_rep)
    xv: Array["B, L, HN, HD"] = repeat_kv(vs, self.n_rep)
    
    xq: Array["B, HN, L or 1, HD"] = xq.transpose(0, 2, 1, 3)
    xk: Array["B, HN, L, HD"] = xk.transpose(0, 2, 1, 3)
    xv: Array["B, HN, L, HD"] = xv.transpose(0, 2, 1, 3)
    

    Here, we fetch the cache values and then transpose them back to reshape them, but this could be done more efficiently by skipping this step. For reference, the maximum size of the KV Cache is \(1 \times 256 \times 6 \times 48 \times 2 \times 6 = 884K\) on batch size 1. Since it is a 15M model, it takes up about 6% more memory.

    GQA(Grouped-Query Attention)

    4

    MQA, which is a Multi-query, has the advantage of being compact and memory-saving compared to MHA, which is a Multi-head, but it suffers from poor performance and unstable learning. Therefore, Grouped-query, GQA, was introduced in Llama 2. In Llama 2, GQA was only applied to 70B, but from Llama 3, GQA was applied to all models above 8B. Since we are using a model that was trained without GQA, we do not use GQA, but we have implemented it in the code. We have implemented it by simply copying it by a multiple, and it can be improved by referencing the previous value for future optimization. We have avoided using GQA when n_rep==1.

    if n_rep == 1:
        return x
    z: Array["B, L, QHN, HD"] = np.repeat(x, n_rep, axis=2)
    

    Scaled Dot-Product Attention

    Attentions are calculated separately by Multi-Head.

    \(Attention(Q, K, V) = softmax(\frac{QK^T}{\sqrt{d_k}})V\)

    # Scaled Dot-Product Attention
    # ["B, HN, L or 1, HD"] @ ["B, HN, HD, L"] -> ["B, HN, L or 1, L"]
    attention: Array["B, HN, L or 1, L"] = xq @ xk.transpose(0, 1, 3, 2) / math.sqrt(self.head_dim)
    # `mask` is used only once at the beginning.
    if mask is not None:
        attention = attention + mask[None, None, :, :]
    attention = softmax(attention)
    output: Array["B, HN, L or 1, HD"] = attention @ xv
    

    Masking is only done at the beginning and only the last Q needs to be processed afterward, so no masking is needed. The result can then be obtained with softmax and matmul. Finally, the result of the Multi-Head calculation is reshaped to full dimension to combine the heads and matmul once more.

    # ["B, HN, L or 1, HD"] -> ["B, L or 1, D"]
    output: Array["B, L or 1, D"] = output.transpose(0, 2, 1, 3).reshape(B, L, -1)
    output: Array["B, L or 1, D"] = output @ self.o_weight
    

    Computing the entire QKV at once is only done in the Prefill Phase. At this time, TTFT (Time To First Token) is called Prefill Latency, and only ‘vector @ matrix’ operations need to be performed from the Decode Phase onward. Flash Attention is also effective only when reducing the Prefill Latency during inference, and it performs somewhat well when the input is long.

    Feed Forward

    In Llama model, Feed Forward uses 3 linear with matmul only and no bias, so unlike GPT, it is not a complete fully-connected layer. We create a swish value from the silu result, multiply it with x_V up-scaled from D to FD, and down-scale it again. Here, the size of FD is FD = 2 * 4 * D / 3, which is D(288), so FD(768).

    swish: Array["B, L or 1, FD"] = silu(x @ self.gate_weight)
    x_V: Array["B, L or 1, FD"] = x @ self.up_weight
    x: Array["B, L or 1, FD"] = swish * x_V
    x: Array["B, L or 1, D"] = x @ self.down_weight
    

    SwiGLU

    In the paper, the SwiGLU formula looks like this:

    1

    Multiplying x_V with swish and matmul it with W_2 is called SwiGLU. This unique combination of multiple feed forwards layers increases the performance of the model. Let x be a real number between approximately \(-14 \sim 11\), which is the input to the silu function. The silu implementation is as follows:

    x * (1 / (1 + np.exp(-x)))
    

    Linear

    After passing through all the transformer blocks, the final output is only the last logit computed by matmul to speed things up. The transformer block always outputs ["1, D"] as the result after the Prefill Phase.

    # ["B, 1, VS"] = ["B, 1(L), D"] @ ["D, VS"]
    logit: Array["B, 1, VS"] = h[:, [-1], :] @ self.lm_head_weight
    

    Generation

    Now, we generate tokens one after the other using the extracted logit. For simplicity, we’ve omitted sampling from the generation process and only output the Greedy result.

    for i, curr_pos in enumerate(range(L, max_new_tokens)):
        if i == 0:  # Prefill Phase
            inputs = input_ids
            pos = 0
        else:       # Decode Phase
            inputs = next_id
            pos = curr_pos
        logits: Array["B, 1, VS"] = self(inputs, pos)
        next_id = logits[:, -1, :].argmax(-1, keepdims=True)
        yield next_id
    

    The first step is Prefill Phase, or sometimes called Summarization. It passes all input and starts at position 0. This is also where Flash Attention comes into play.

    From then on, it is the Decode Phase and thanks to the KV Cache, only the last token ID is passed to Q and the result is the also last logit. Here, we omit sampling and only extract the maximum value. If you want to add a sampling process, you can take softmax and implement top_p and top_k.

    You can now yield the token ID we generated as a result, decode it in the next step and print the output token to finalize the process.

    Example

    You can run it like this:

    $ python llama3.py "I have a dream"
    """
    I have a dream. He dream of a big, beautiful garden full of flower and tree. He dream of playing with hi friend and eating yummy snack.
    One day, he wa walking in the garden when he saw
    
    Token count: 50, elapsed: 1.53s, 33 tokens/s
    """
    

    Karpathy has trained the model to a certain extent, and the result is that model is not performing badly. It ran at 33 tokens/s on an M2 MacBook Air.

    GitHub

    The full source code is available at likejazz/llama3.np.

    References

    Kimsuky hackers deploy new Linux backdoor in attacks on South Korea

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-16 14:28:37
    The North Korean hacker group Kimsuki has been using a new Linux malware called Gomir that is a version of the GoBear backdoor delivered via trojanized software installers. [...]...
    Original Article

    Kimsuky hackers deploy new Linux backdoor via trojanized installers

    The North Korean hacker group Kimsuki has been using a new Linux malware called Gomir that is a version of the GoBear backdoor delivered via trojanized software installers.

    Kimsuky is a state-sponsored threat actor linked to North Korea’s military intelligence, the Reconnaissance General Bureau (RGB).

    In early February 2024, researchers at the SW2 threat intelligence company reported about a campaign where Kimsuky used trojanized versions of various software solutions, e.g. TrustPKI and NX_PRNMAN from SGA Solutions, Wizvera VeraPort, to infect South Korean targets with Troll Stealer and the Go-based Windows malware GoBear.

    Analysts at Symantec, a Broadcom company, looking into the same campaign that targeted South Korean government organizations, discovered a new malicious tool that appears to be a Linux variant of the GoBear backdoor.

    The Gomir backdoor

    Gomir shares many similarities with GoBear and features direct command and control (C2) communication, persistence mechanisms, and support for executing a wide range of commands.

    Upon installation, the malware checks the group ID value to determine if it runs with root privileges on the Linux machine, and then copies itself to /var/log/syslogd for persistence.

    Next, it creates a systemd service named ‘syslogd’ and issues commands that start the service before deleting the original executable and terminating the initial process.

    The backdoor also tries configure a crontab command to run on system reboot by creating a helper file (‘cron.txt’) in the current working directory. If the crontab list is updated successfully, the helper file is removed as well.

    Gomir supports the following 17 operations, triggered when the corresponding command is received from the C2 via HTTP POST requests.

    • Pause communication with the C&C server.
    • Execute arbitrary shell commands.
    • Report the current working directory.
    • Change the working directory.
    • Probe network endpoints.
    • Terminate its own process.
    • Report the executable pathname.
    • Collect statistics about directory trees.
    • Report system configuration details (hostname, username, CPU, RAM, network interfaces).
    • Configure a fallback shell for executing commands.
    • Configure a codepage for interpreting shell command output.
    • Pause communication until a specified datetime.
    • Respond with "Not implemented on Linux!"
    • Start a reverse proxy for remote connections.
    • Report control endpoints for the reverse proxy.
    • Create arbitrary files on the system.
    • Exfiltrate files from the system.

    According to Symantec researchers, the commands above "are almost identical to those supported by the GoBear Windows backdoor."

    Based on the analysis of the campaign, the researchers believe that supply-chain attacks (software, trojanized installers, fake installers) represent the preferred attack method for North Korean espionage actors.

    The researchers note that the choice of the software to be trojanized "appears to have been carefully chosen to maximize the chances of infecting its intended South Korean-based targets."

    Symantec's report includes a set of indicators of compromise for multiple malicious tools observed in the campaign, including Gomir, Troll Stealer, and the GoBear dropper.

    You thought OpenStreetMap uses WGS84? No it doesn't (2019)

    Hacker News
    www.openstreetmap.org
    2024-05-16 14:24:02
    Comments...
    Original Article

    More precisely, the WGS84 Datum is not used everywhere.

    Here is some background:

    • The WGS84 Coordinate Reference System uses an ITRF datum, locked with the Earth’s rotation.

    • The tectonic plates we’re living on, are moving, up to 70 to 80 mm/year for the Australian plate, 20 to 25 mm/year for the Eurasian one.

    • The tectonic plates have internal distortions (we do ignore them here)

    If you have a very accurate GNSS receiver which shows you WGS84 coordinates, and place it on a survey mark, because this mark moves, you won’t get the same coordinates year after year. If you surveyed a mark in Australia 13 years ago, today’s coordinates are 1 meter off. So, accurate WGS84 coordinates are not accurate at all if you don’t know the epoch, just as a time value is unuseful if you don’t know the time zone. Working with dynamic coordinates would be a nightmare for the surveyors. To make their life easier they use a datum associated with their continental plate, locked at a point in time. And for a few decades now, many countries have chosen an ITRF datum and “locked” it at a specific date. With such a datum, the coordinates of survey marks remain the same over the years.

    • USA is using NAD83

    • Australian is using GDA94 (ITRS epoch 1994.0)

    • Europe is using ETRS89 (ITRS epoch 1993.0)

    • France (in europe) is using RGF93, a more accurate ETRS89 realization. We consider that RGF93 = ETRS89.

    You could object this is not an OSM problem : we use gpx trace, aerial imagery, opendata sets, all with WGS84 coordinates!

    • At first, don’t forget that a WGS84 datum without epoch can’t be accurate at a submeter level.

    • Secondly, if you use a standard GNSS receiver, it doesn’t matter, as your accuracy is too low (3 to 5 meters). If you use RTK, like I do, your datum is the one used by the base station, and it’s usually plated-fixed.

    • Thirdly, if your aerial imagery has a low resolution like 50cm/pixel, it will be very difficult to see small details.

    However, we have more and more high-res imagery. In some places, you can see some survey marks and check the coordinates. Let’s go to Australia, next to the Mount Stromlo Observatory. This node is a GNSS antenna, part of the IGS network. You can go to the Geoscience Australia website to find the GDA94 coordinates of this antenna and enter them in JOSM with the “Lat Lon Tool”. Then, if you switch between the 3 good imagery (ACTmapi Imagery 2017, ACTmapi Imagery 2018, LPI Nsw Imagery), you will see that the antenna, the node with the GDA94 coordinates, and the 3 imagery layers, are aligned: Stromlo GNSS Antenna (GDA94 coordinates)

    Ok, but what are the WGS84/IRTF coordinates for this antenna? Luckily, you can download the data from this GNSS station and process them with a PPP software. The Australian online AUSPOS service gives you the PPP results with GDA94, GDA2020 and IRTF (@epoch data) coordinates. Here are the locations, more than 1.5m to north-east: !! Stromlo GNSS Antenna (GDA94, GDA2020, IRTF coordinates)

    The conclusion is that these imageries are not using an IRTF datum, but the local one: GDA94. Therefore any OSM data created using these layers are not in WGS84.

    Now let’s go to France, to this node : https://www.openstreetmap.org/node/670517301

    This is a survey mark with coordinates using RGF93 datum and the accuracy is better than 10cm. survey_point near Charly The alignment is good. We can say that this imagery layer use RGF93, not WGS84, or we would have seen a 70 to 80 cm offset. I’ve checked check some other survey marks in the country…all aerial imagery are RGF93/ETRS89.

    This is our first problem: Some OSM data are not using WGS84 coordinates ; the offset could be as high as 2 meters.

    Our second issue is: How do we guarantee a good accuracy over the years?

    Here are a couple of options.

    1. We keep using local datums.
      • This is simple, but we don’t want too many datums: perhaps we should select a single datum for each tectonic plate.

      • Aerial imageries with the same local datum remain aligned.

      • We should inform data consumers, so that they can decide to convert the coordinates to WGS84 if they want to.

      • We will need to move a lot of data when a new datum replaces an old one (more on that later)

    2. We convert all data to an ITRF datum.
      • We must convert data with local datum (Australia, France, …) to WGS84. This is not an easy task, but this is feasible with a plate motion model.

      • The date a node is created in OSM doesn’t inform about the original epoch.

      • Should we keep the old aerial imageries to their original location, or transform them to today’s location? It could be difficult for the editors (Josm, ID, …) to do this if there is a translation and a rotation.

      • When you load data in an editor, it should check all nodes coordinates, find the epochs, and dynamicaly move them to the actual localization with an Helmert transformation. It would be the same problem if you want to reuse the data. Another way is to create a bot which moves all the nodes in the database regularly (twice a year?).

      • Prone to errors

    Whatever the decision is, we should check what is the real datum of all high-res imagery. To do so we need more reference points that are visible on one or more imagery. These could be a survey mark on the ground with public and accurate coordinates, or a GNSS antenna on or near the ground (we can’t use an object on a roof) with observation data freely available. I’ve already started a list on the wiki, feel free to add more reference points. A new tag on these nodes would be useful.

    Let’s go back to Australia: The Auspos service provides GNSS coordinates with 3 datums : GDA94, WGS84 and GDA2020. What is the last one? As you know, the Australian plate is moving pretty fast. In 2020 the offset between GDA94 and the real location will be more than 1.8 meters. They decided they will use a new datum from 2020: GDA2020 It means that new high-res aerial imagery in this country will have a big offset relative to the old imagery. They will use a dynamic reference frame too, but I’m not sure it will be used by the GIS world: ATRF

    Another country will change its datum : the U.S.A., with the plate-fixed NATRF2022, in replacement of NAD83.

    Summary:

    • On Earth, everything is moving, up to 80mm/year.

    • A fix point on a tectonic plate will see its WGS84 coordinates changing over the years, but the same point have static coordinates with a plate-fixed local datum.

    • WGS84 coordinates without epoch can’t be accurate.

    • Contrary to what is stated, not all OSM data are using a WGS84 datum. In some country, the offset could be as high as 1.8 meters.

    • Some aerial imagery are not using a WGS84 coordinate reference system, but a local datum.

    • What should OSM do? Keep the dynamic WGS84 coordinates, or use some local datums as the surveyor’s world do?

    Thank you to naomap for his help with the translation.

    Security updates for Thursday

    Linux Weekly News
    lwn.net
    2024-05-16 14:17:45
    Security updates have been issued by AlmaLinux (.NET 7.0, .NET 8.0, and nodejs:20), Debian (chromium, firefox-esr, ghostscript, and libreoffice), Fedora (djvulibre, mingw-glib2, mingw-python-jinja2, and mingw-python-werkzeug), Oracle (.NET 7.0, .NET 8.0, kernel, and nodejs:18), Red Hat (nodejs:20), ...
    Original Article
    Dist. ID Release Package Date
    AlmaLinux ALSA-2024:2843 9 .NET 7.0 2024-05-16
    AlmaLinux ALSA-2024:2842 9 .NET 8.0 2024-05-16
    AlmaLinux ALSA-2024:2853 9 nodejs:20 2024-05-16
    Debian DSA-5689-1 stable chromium 2024-05-15
    Debian DLA-3815-1 LTS firefox-esr 2024-05-16
    Debian DSA-5691-1 stable firefox-esr 2024-05-15
    Debian DSA-5692-1 stable ghostscript 2024-05-15
    Debian DSA-5690-1 stable libreoffice 2024-05-15
    Fedora FEDORA-2024-e8b9bedd36 F38 djvulibre 2024-05-16
    Fedora FEDORA-2024-891c09df97 F39 djvulibre 2024-05-16
    Fedora FEDORA-2024-d20163632f F40 djvulibre 2024-05-16
    Fedora FEDORA-2024-be032e564d F39 mingw-glib2 2024-05-16
    Fedora FEDORA-2024-2ce1c754f7 F40 mingw-glib2 2024-05-16
    Fedora FEDORA-2024-e609c057ad F39 mingw-python-jinja2 2024-05-16
    Fedora FEDORA-2024-e3caf31c98 F40 mingw-python-jinja2 2024-05-16
    Fedora FEDORA-2024-8e8ff9d6ec F40 mingw-python-werkzeug 2024-05-16
    Oracle ELSA-2024-2843 OL9 .NET 7.0 2024-05-16
    Oracle ELSA-2024-2842 OL9 .NET 8.0 2024-05-16
    Oracle ELSA-2024-12385 OL8 kernel 2024-05-16
    Oracle ELSA-2024-12385 OL9 kernel 2024-05-16
    Oracle ELSA-2024-12385 OL9 kernel 2024-05-16
    Oracle ELSA-2024-2779 OL9 nodejs:18 2024-05-16
    Red Hat RHSA-2024:2853-01 EL9 nodejs:20 2024-05-15
    Slackware SSA:2024-136-01 gdk 2024-05-15
    Slackware SSA:2024-136-02 git 2024-05-15
    SUSE SUSE-SU-2024:1667-1 SLE12 python 2024-05-16
    Ubuntu USN-6766-2 20.04 22.04 linux-hwe-5.15, linux-raspi 2024-05-15

    (Log in to post comments)

    Republicans Can't Decide: Do They Hate Prosecutors Because of Bail Reform or Abortion?

    Intercept
    theintercept.com
    2024-05-16 14:00:00
    Since Dobbs, state-level Republicans have sought to strip power from DAs elected in Democratic cities who won't prosecute abortion care. The post Republicans Can’t Decide: Do They Hate Prosecutors Because of Bail Reform or Abortion? appeared first on The Intercept....
    Original Article

    The national right-wing attack on elected district attorneys has merged with the Republican project to criminalize abortion. 

    After the Supreme Court overturned the constitutional right to abortion in the landmark case Dobbs v. Jackson’s Women’s Health Organization, many Republican dominated state governments quickly moved to ban all or some abortions. Many of the populous cities in these state, however, are dominated by Democratic Party politics. In those cities, elected prosecutors pledged not to prosecute reproductive care, setting up a clash with state-level governments. 

    The clash came first in Florida, where in 2022, Republican Gov. Ron DeSantis became the first state official to suspended an elected prosecutor who said they would not charge people who sought abortions. In January, a three-judge federal appeals circuit panel said DeSantis’s decision to suspend Former States Attorney Andrew Warren violated First Amendment provisions for protected speech, including Warren’s comments on protecting abortion and transgender care.  

    “Those prosecutors who have recognized that they have no place interfering with patients’ personal decisions have found themselves under threat.”

    Since then, at least five states have introduced legislative measures to strip power from elected prosecutors who have made similar pledges. Over the last two years, Republicans in Georgia, Idaho, Indiana, South Carolina, and Texas have introduced or passed legislation making it easier to prosecute people who seek abortions. 

    “As reproductive health care became criminalized in the wake of Dobbs, prosecutors around the country became a front line for this essential right,” said Jill Habig, founder and CEO of the the Public Rights Project. “Those prosecutors who have recognized that they have no place interfering with patients’ personal decisions have found themselves under threat for that decision.” 

    On Thursday, the Public Rights Project released a report tallying and detailing a wave of new attacks against prosecutors vowing to defend abortion rights. The attacks target democratically elected prosecutors for routine speech about practices in their offices. In Florida, Warren was suspended in part because of his statements on the right to abortion. In Texas, lawmakers who launched a petition to remove Travis County District Attorney Jose Garza also cited his pledge not to prosecute abortion care.

    The new research by Public Rights Project shows that the salvos against supporters of abortion rights are just part of a growing, nationwide right-wing effort to limit the powers of elected, reform-minded prosecutors. Since early 2023, there have been 53 attempts to restrict prosecutorial authority in 26 states — attempts that are increasingly effective, with 15 new measures enacted in the same time period.

    Idaho, Georgia, and More

    The recent pushes to strip power from prosecutors who support abortion rights have seen some successes. In Idaho, if an elected prosecutor has a policy in place not to prosecute violations of the state’s abortion ban, a law enacted last year would give the state attorney general power to take over any related cases.

    A similar bill was proposed in South Carolina last year but died in committee. 

    In Texas, at least four bills would create new and severe criminal offenses for abortion care and give the state attorney general power to bring criminal prosecutions and sue over related cases.

    A Georgia law enacted last year gives a politically-appointed commission the power to remove and discipline elected DAs over decisions not to prosecute certain offenses, including abortions. 

    Other states have fought to curb the attacks on abortion care. A proposed bill in Wisconsin would give the state attorney general concurrent jurisdiction to take over certain prosecutions that target people who seek abortions under the state’s law prohibiting abortions from 22 weeks. 

    In Arizona, state officials are deliberating on efforts to block the repeal of an 1800s-era abortion ban. Democratic Gov. Katie Hobbs issued an executive order in 2023 giving all duties related to prosecuting abortion care over to the state attorney general, a Democrat who supports protecting the right to abortion.

    Tons of New Bills to Curb DAs

    The anti-abortion measures are the outgrowth of a broader national attack on elected prosecutors who ran on reform policies. National Republicans have fomented and harnessed a backlash to candidates who ran on ending cash bail, declining to prosecute cannabis possession, overturning wrongful convictions and prosecuting police misconduct.

    Last year, the Public Rights Project and Local Solutions Support Center released a report that outlined efforts to curb the power of reform-minded prosecutors. The research released about restricting prosecutors who vow to defend abortion rights was part of a new paper that updated last year’s tally.

    More than 37 bills to strip power from prosecutors were introduced in 17 states between 2017 and early 2023. Some singled out reform-minded DAs elected in places like Philadelphia and St. Louis

    Since then, the new research showed, the numbers ballooned to 53 attempts introduced in 26 states. Texas is home to at least 13 such efforts, including bills that further criminalize abortion and make it easier to file complaints against and investigate DAs who decline to prosecute certain offenses. 

    While the bulk of legislation introduced between 2017 and 2022 didn’t pass, newer bills have been more successful. Fifteen new measures have been enacted in 14 states since last year. 

    Texas enacted a law last year that makes it easier to bring private lawsuits to remove prosecutors, Habig added. Now the state is following the example set by Georgia and considering creating a new government agency for the same purpose.

    “The bills introduced and passed in the last year show that the trend from 2017-22 has not stopped — in fact, it’s only accelerating,” Habig said. “And states that have taken some efforts to restrict prosecutorial discretion have shown that they are not satisfied with their early steps.”

    "Rampage of Killings, Looting, Torture, Rape": Ethnic Cleansing in Sudan's Darfur Region

    Democracy Now!
    www.democracynow.org
    2024-05-16 13:47:47
    Human Rights Watch has documented ethnic cleansing in the West Darfur region of Sudan by the paramilitary Rapid Support Forces and allied militias against the Masalit people and other non-Arab communities. “These allied militia and the RSF then, from April until June, conducted a rampage of ki...
    Original Article

    This is a rush transcript. Copy may not be in its final form.

    NERMEEN SHAIKH: Well, Belkis, we want to turn now to a conflict that is very rarely covered, and certainly not covered to the extent that it should be, which is in Sudan, where a humanitarian catastrophe in North Darfur is escalating, as Human Rights Watch has documented. On Wednesday, the United Nations humanitarian coordinator for Sudan said people are, quote, “trapped in an inferno of brutal violence” between the army and paramilitary forces, which has made it hard to deliver aid, and now, quote, “famine is closing in” for more than 4 million people. Also on Wednesday, the United States imposed sanctions against two commanders of Sudan’s paramilitary Rapid Support Forces.

    This is human rights lawyer Jamal Abdallah Khamis describing how he nearly escaped a massacre orchestrated by the Rapid Security Forces, or RSF. He spoke in a video for a new Human Rights Watch report titled “Sudan: Ethnic Cleansing in West Darfur.”

    JAMAL ABDALLAH KHAMIS: [translated] I was accompanying my injured friend, Yousef Haroun Kabello. Minutes later, around eight militiamen wearing Rapid Support Forces uniforms appeared. There were others with them from these well-known Arab militias. They were arguing with people. They stopped the cars. They opened fire on us. They shot at the chests of children, women, old and young men. It was a harrowing scene. We thought about how to escape. But we needed a way to escape. How were we going to escape? They started chasing people down the valley and firing on people who were in the water. It was terrifying.

    NERMEEN SHAIKH: So, Belkis Wille, that was an excerpt from the video that accompanied your report, Human Rights Watch’s report on Sudan. If you could talk about the key findings in the report and why Human Rights Watch has concluded that the RSF may have committed genocide?

    BELKIS WILLE: So, this report is about a period last year between April and June, and then subsequently in November. And we’ve centered the report around events that occurred in the capital of West Darfur, the city of El Geneina. The reason we focused there is because though there has been fighting across Sudan since last April, when there was a split between the Sudanese Armed Forces and the Rapid Support Forces, the RSF, the violence has been perhaps most acute there. And this is, you know, an area that since 2003 has faced waves of violence and horrific killings.

    Last April, with this split and fighting that developed in Khartoum, the capital, we saw the RSF proceed to encircle the city of El Geneina, where there was a limited presence of the Sudanese Armed Forces. They pulled out of the city at that point, leaving civilians in the city to the hands of the RSF. The RSF brought in allied militia. And these allied militia and the RSF then, from April until June, conducted a rampage of killings, of looting, of torture, of rape, targeting a specific ethnic group, the Masalit population, and a few other specific ethnic groups. And this was a campaign, as you say, of ethnic cleansing that we saw conducted over about six weeks.

    And over that time, these armed forces encircled this population, pushing them into a smaller and smaller sector of the city, and then ultimately pushed them out of the city in one mass wave of killing, where you had tens of thousands of people on the streets, mostly Masalit, walking, trying to get to safety, and Rapid Support Forces along the sides of the road just opening fire and shooting them. People started running. They jumped into the river, which was deep. They were drowning. As they were drowning, they were being shot and killed. Some then turned around and ran in the direction of the border with Chad. And they, along that road, were also rounded up by forces, and many were killed.

    At the end of last summer, my colleague and I interviewed dozens of survivors of this violence. We ended up interviewing 200 or so. And they shared with us horrific details about these killings. And it’s really important that states focus on the acuteness of this violence and focus on examining whether indeed there was intent to commit genocide by the RSF and whether there should be prosecutions for genocide.

    AMY GOODMAN: And, Belkis Wille, if you can explain: Who is arming both sides? I mean, we’ve just passed the first anniversary of this conflict between the Sudanese military and the RSF, who were together before this. And explain who the leaders are and the countries on both sides.

    BELKIS WILLE: Unfortunately, this is an incredibly murky picture. We have different governments providing arms to either side of these groups. We ourselves have been trying to track some of these arms transfers, because, of course, the more that weapons continue to get poured into this conflict, the more the fighting will continue and the more civilians will pay the price.

    I think what’s perhaps the most notable, though, is actually the lack of action to protect civilians, whether that’s by the U.N. Security Council or by the African Union. You know, there was a U.N. mission of peacekeepers that was based in Sudan, and their mission ended in 2020. A new mission was created by the U.N. that had no peacekeeping or protection of civilian mandate. It was only a, you know, political negotiations mission. But even that closed at the end of last year, last November. So, at the moment in Sudan, there is absolutely no entity that is focused on the protection of civilians.

    And so, what we’re calling for in this report is a new mission, that needs to be created both by the U.N. and the African Union, sent into Sudan with a mission to protect civilians. And at the same time, we need to see an effective arms embargo. Currently there’s an arms embargo in place in the context of Darfur. It’s not being complied with. As you said, there are different states pouring weapons into the country. And that needs to be complied with in order to better protect civilians.

    If I may just add one thing, which is there is another city, a city in northern Darfur, which you mentioned, El Fasher. That city, as of this morning, is in flames in the eastern part of the city. We saw satellite imagery from two days ago showing that the RSF has encircled the city and that there are fires developing in civilian neighborhoods. And this is a city that’s been housing tens of thousands of people who have been displaced from fighting in other parts of Darfur.

    NERMEEN SHAIKH: Belkis, as you mentioned, there is an existing arms embargo. So, if you could say, I mean, how is an arms embargo normally enforced, and why hasn’t it been enforced in this case? And what are the countries that are violating the arms embargo consistently? Outside powers who are involved in this conflict include the United Arab Emirates, Iran, Egypt and, no doubt, others.

    BELKIS WILLE: Absolutely. So, you know, I mean, the effectiveness of arms embargoes really comes also from political will to impose those arms embargoes, political will on the sides of states not to send weapons to specific conflict zones, but then also on the side of the international community, the watchdog community, the U.N. Security Council, to hold states accountable when they are breaking that arms embargo. And that’s something that we’re not seeing happening in the context of Darfur specifically.

    You mentioned the name of a few states, like the United Arab Emirates and others, that are shipping weapons into this conflict and context. But, as I said, it’s extremely murky. There is limited tracking of what kind of weapons are being brought into the country and how they’re being used by these warring parties — exactly the reason that, indeed, there should be an arms embargo, a complete arms embargo, in place that is being effectively enforced by the U.N. and the global community.

    NERMEEN SHAIKH: And, Belkis, if you could say, you know, just outline what the scale of the crisis is for refugees and internally displaced people in Sudan. A new report from the International Organization for Migration has found 20,000 people are forced to flee their homes in Sudan every day — 20,000 people every day, half of them children. What do you think needs to be done to help these people get to a place that’s safe?

    BELKIS WILLE: As you say, I mean, the scale of the conflict really can’t be understated. We have areas in the country that are approaching famine. We have areas of the country, like Darfur, where the violence and the conditions have been so bad and the violence so acute that over half a million people have had to flee across the border into Chad. We’ve seen many people have to flee to other neighboring countries, including South Sudan and elsewhere. So, it really speaks to the horrifying situation that civilians are facing.

    Unfortunately, as long as the fighting continues and as long as there is no entity to put in place, you know, a civilian protection strategy, we’re going to continue to see the conditions that you’re describing. There are so many areas that are completely outside of the access of aid groups and aid workers. So those are areas where there’s no way to bring food or medicine or water in. And that’s because of the warring parties. The RSF and the Sudanese Armed Forces are blocking access for aid workers into these areas. They’re blocking civilians from fleeing from certain areas. And that’s really the context of the conditions you described.

    AMY GOODMAN: Belkis Wille, we want to thank you so much for being with us, associate director with the Crisis, Conflict, and Arms Division at Human Rights Watch, speaking to us from the capital of Ukraine, from Kyiv.

    And speaking of international human rights, the International Court of Justice today is hearing from South Africa, their request over the Israeli assault on Gaza’s southern city of Rafah. We’ll have more on that tomorrow. I’m Amy Goodman, with Nermeen Shaikh, for another edition of Democracy Now!

    The original content of this program is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.

    F* – A Proof-Oriented Programming Language

    Hacker News
    www.fstar-lang.org
    2024-05-16 13:47:07
    Comments...
    Original Article

    Introduction


    F* (pronounced F star) is a general-purpose proof-oriented programming language, supporting both purely functional and effectful programming. It combines the expressive power of dependent types with proof automation based on SMT solving and tactic-based interactive theorem proving.

    F* programs compile, by default, to OCaml. Various fragments of F* can also be extracted to F#, to C or Wasm by a tool called KaRaMeL, or to assembly using the Vale toolchain. F* is implemented in F* and bootstrapped using OCaml.

    F* is open source on GitHub and is under active development by Microsoft Research, Inria, and by the community.

    Download


    F* is distributed under the Apache 2.0 license. Binaries for Windows, Linux, and Mac OS X are posted regularly on the releases page on GitHub. You can also install F* from OPAM, Docker, Nix, or build it from sources, by following the instructions in INSTALL.md.

    Learn F*


    An online book Proof-oriented Programming In F* is being written and regular updates are posted online. You probably want to read it while trying out examples and exercises in your browser by clicking the image below.

    F* Tutorial

    Low*

    We also have a tutorial that covers Low*, a low-level subset of F*, which can be compiled to C by KaRaMeL.

    Course Material

    F* courses are often taught at various seasonal schools. Lectures and course materials for some of them are also a useful resource.

    Community


    Please use GitHub Discussions to ask questions about F*, learn about announcements, etc.

    We also have a mailing list, which has very low traffic. You can subscribe at fstar-mailing-list.

    The F* developers and many users interact on this Slack forum---you should be able to join the forum automatically by clicking here, but if that doesn't work,please ask for access on this thread.

    There is also a public forum on Zulip.

    The F* PoP Up Seminar, a users and developers meeting is open to all. We aim to schedule it once a month, though the schedule is irregular---we hope to see you there!

    You can also contact the maintainers of F* at fstar-maintainers@googlegroups.com.

    Uses


    F* is used in several projects in both industrial and academic settings. We list a few of them here. If you are using F* in your project, please let us know by writing to the fstar-mailing-list.

    Project Everest

    Project Everest is an umbrella project that develops high-assurance secure communication software in F*. A big part of the development of F* has been motivated by the scenarios that Project Everest targets. Several offshoots from Project Everest continue as their own projects, including some of those listed below.

    HACL*, ValeCrypt, and EverCrypt

    HACL* is a library of high-assurance cryptographic primitives, written in F* and extracted to C. ValeCrypt provides formally proven implementations of cryptographic primitives in Vale, a framework for verified assembly language programming embedded in F*. EverCrypt combines them into a single cryptographic provider. Code from these projects is now used in production in several projects, including Mozilla Firefox, the Linux kernel, Python, mbedTLS, the Tezos blockchain, the ElectionGuard electronic voting SDK, and the Wireguard VPN.

    EverParse

    EverParse is a parser generator for binary formats that produces C code extracted from formally proven F*. Parsers from EverParse are used in production in several projects, including in Windows Hyper-V, where every network packet passing through the Azure cloud platform is parsed and validated first by code generated by EverParse. EverParse is also used in other production settings, including ebpf-for-windows.

    Research


    F* is an active topic of research, both in the programming languages and formal methods community, as well as from an application perspective in the security and systems communities. We list a few of them below, with full citations to these papers available in this bibliography. If you would like your paper included in this list, please contact fstar-maintainers@googlegroups.com.

    The Design of F* and its DSLs

    Semantics and Effects

    Applications in Security and Cryptography

    Many papers applying F* in security and cryptography can be found in the Project Everest bibliography. We mention a few prominent ones here as well as other applications not related to Project Everest.

    Applications in Systems

    Applications in Parsing

    Applications in Programming, Program Proof, and Program Analysis

    Miscellaneous

    Papers about an older version of F*

    The first paper to introduce a system called F* was in 2011. Although the current version of F* was redesigned and implemented in 2015, we include some of these older papers here for completeness.

    "In Cold Blood": Russian Forces Executing Surrendering Ukrainian Soldiers

    Democracy Now!
    www.democracynow.org
    2024-05-16 13:39:23
    Ukrainian forces are withdrawing from some areas in the northeastern region of Kharkiv as Russian forces continue a new offensive that has displaced thousands. This latest setback for Ukraine comes more than two years after Russia invaded the country. Human Rights Watch has documented several incide...
    Original Article

    This is a rush transcript. Copy may not be in its final form.

    AMY GOODMAN: This is Democracy Now!, democracynow.org, The War and Peace Report. I’m Amy Goodman, with Nermeen Shaikh, as we continue our conversation with Belkis Wille. She is the associate director with the Crisis, Conflict, and Arms Division at Human Rights Watch, and she’s joining us from Kyiv, the capital of Ukraine, where U.S. Secretary of State Antony Blinken made a surprise trip on Tuesday. He spoke at a joint press conference in Kyiv with Ukrainian Foreign Minister Dmytro Kuleba.

    SECRETARY OF STATE ANTONY BLINKEN: We will provide an additional $2 billion in foreign military financing for Ukraine. And we put this together in a first-of-its-kind defense enterprise fund, and it has three components. One is to provide weapons today, so this will assist Ukraine in acquiring those weapons. Two is to focus, as well, on something that Dmytro just talked about: investing in Ukraine’s defense industrial base, helping to strengthen even more its capacity to produce what it needs for itself, but also to produce for others. And finally, using this fund to help Ukraine purchase military equipment from other countries, not just the United States, for Ukraine’s use.

    NERMEEN SHAIKH: This comes as Ukrainian forces are withdrawing from some areas in the northeastern region of Kharkiv as Russian forces continue a new offensive that’s displaced thousands. The Ukrainian city of Vovchansk is reportedly in ruins following relentless Russian shelling. Ukrainian President Volodymyr Zelensky has postponed all of his upcoming foreign travel amid the new Russian offensive.

    Human Rights Watch has a new report out on Ukraine titled “Russian Forces Executed Surrendering Ukraine Soldiers.”

    So, Belkis Wille, if you could talk about that report, the human rights report — Human Rights Watch report, on this, on Russia and Ukraine and these incidents that you document of Russians killing surrendering Ukrainian soldiers?

    BELKIS WILLE: Unfortunately, this is not something new in this conflict. Since the full-scale invasion, we’ve seen instances of execution of prisoners of war on the Ukrainian side and even on the Russian side. But what we’ve seen now in the last months and the report that we published covers these new emerging videos. It’s clips of drone footage. We believe these to probably be Ukrainian military drones that are flying near the frontline.

    And in the context, as you said, of Russia retaking certain areas where there had been fighting and pushing the frontline, we have these five incidents that we’ve documented where you see, in clear detail in some cases, in this drone footage Ukrainian soldiers coming out of foxholes and dugouts. They are very clearly intending to surrender. They take off their vests, they put down their helmets, they lie on the ground and put their hands up. And then we see them being executed by Russian soldiers in cold blood. The footage is really shocking, I would say, to watch and really captures the brutality of these killings.

    AMY GOODMAN: Belkis, can you talk about what’s changed right now, the intensification of the Russian attack, especially on Ukraine’s second-largest city, Kharkiv, and the region around it? And the significance now of — you have Xi meeting with Putin, and Xi presenting the peace plan and saying that — it looks like he wants to be a negotiator of that plan, that there must be peace in the region?

    BELKIS WILLE: Absolutely. You know, we’ve come, unfortunately, to a moment in this full-scale invasion where Russia seems to have the upper hand, is pushing the frontline. And the reality, of course, is: Who pays the price? Ukrainian civilians. Ukrainian civilians are coming under repeated attack, as you said, in some cities that recently have been decimated by consistent shelling. Kharkiv is a huge city full of a civilian population. Many of them already had to evacuate in 2022 as Russian forces were approaching the city. They returned home. They’ve done a lot to rebuild parts of the city that were damaged. And now, again, they come to this moment where they wonder whether they need to evacuate, including families with young children, that really don’t know if they’re safe in their homes, because of this Russian assault.

    NERMEEN SHAIKH: And, Belkis, for this, the Human Rights Watch report that we’re talking about, you wrote — Human Rights Watch wrote a letter to the Russian defense minister, Sergei Shoigu, at the end — towards the end of April, asking about the incidents that you document. If you could explain what the letter said and whether you’ve received a response? You’ve also pointed out that Human Rights Watch for decades has documented Russian war crimes, from Chechnya to Syria and now in Ukraine. Has the Russian government responded in the past to requests from Human Rights Watch for responses to incidents that you have documented?

    BELKIS WILLE: In this letter, we asked about these very specific incidents. We shared with them links to access the drone footage that we reviewed. We asked them to share with us what information there was into why these killings occurred, why these Ukrainian soldiers were executed. And we wanted to know whether there’s actually an order that’s been put in place, a command telling Russian soldiers to execute Ukrainian soldiers rather than take them prisoners — of course, a very serious war crime.

    We did not receive a response to that letter. And as you said, in the, sadly, decades of our documentation of war crimes committed by Russia, we do not receive substantive responses to our letters at all. And so, it really blocks any ability on our side to directly engage with the Russian government and with the Russian army on the abuses that continue to be perpetrated. And what we don’t see, or we don’t know of, is any measures being taken by the Russian military to hold its own soldiers accountable when they commit war crimes.

    AMY GOODMAN: And, of course, now Shoigu is out as defense minister. What are you calling on Russia and the United States to do, particularly as both continue to use or provide banned munitions? And let’s talk about Secretary of State Tony Blinken in Ukraine this week, where he announced a $2 billion in additional military funding to Ukraine, saying the U.S. is working to quickly get more ammunition and weapons to the frontlines. Is this the answer, Belkis Wille?

    BELKIS WILLE: Well, here, I really want to dive into one very specific issue, which is the issue of banned munitions being used in this war. The particular munition that I’m speaking about are cluster munitions. These are a type of munition that most countries around the world banned the use of absolutely because of the harm they pose to civilians. There’s a convention that many states have signed on to, indeed. Unfortunately, the U.S., Ukraine and Russia have not signed the treaty that bans the use of cluster munitions.

    And since — I remember it. It was in the very first hours of the full-scale invasion by Russia of Ukraine in 2022 that we heard about a cluster munitions attack. Only two weeks ago, there was a horrifying cluster attack by Russian forces on the city of Odesa. This was at 7 p.m. on a joggers path. It killed five civilians, injured over 30 more, including two children and a pregnant woman.

    And then, tying this, of course, to the U.S., the U.S. has been shipping more cluster munitions, these same munitions, to Ukraine for Ukraine to use. The latest shipment, the fifth shipment of cluster munitions from the United States, was announced in late April. And clearly, adding banned munitions, more banned munitions, into this conflict is absolutely not the answer. And this is what continues to harm Ukrainian civilians.

    The original content of this program is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.

    Human Rights Watch: Israeli Forces Attack Known Aid Worker Locations in Gaza

    Democracy Now!
    www.democracynow.org
    2024-05-16 13:29:25
    A new Human Rights Watch Report finds Israeli forces have attacked humanitarian aid convoys and facilities at least eight times since October 7 despite being given their coordinates. Israeli authorities did not issue advance warnings to any of the aid organizations before the attacks, which killed a...
    Original Article

    This is a rush transcript. Copy may not be in its final form.

    AMY GOODMAN: This is Democracy Now!, democracynow.org, The War and Peace Report. I’m Amy Goodman, with Nermeen Shaikh.

    NERMEEN SHAIKH: Israeli forces have attacked humanitarian aid convoys and buildings in Gaza at least eight times since October, despite being given coordinates to ensure their protection. That’s according to a new report by Human Rights Watch published this week. Israeli authorities did not issue advance warnings to any of the aid organizations before the attacks. In the eight incidents documented by Human Rights Watch, Israeli forces killed at least 15 people, including two children, and injured at least 16 others. More than 250 aid workers have been killed in Gaza over the past seven months, according to the U.N.

    AMY GOODMAN: For more, we’re joined by Belkis Wille, associate director with the Crisis, Conflict, and Arms Division at Human Rights Watch, their new report titled “Gaza: Israelis Attacking Known Aid Worker Locations.” Belkis Wille is joining us from the capital of Ukraine, in Kyiv. And we’re going to talk about Ukraine in a minute, but first Gaza.

    Belkis, thanks so much for being there. Can you describe what you found? You know, it’s interesting that in the last few days, yet another U.N. worker was killed, and Israel claimed that they weren’t given the coordinates of where they were. But if you can talk about the fact that when they know the coordinates, these places, these aid workers and areas are attacked?

    BELKIS WILLE: Absolutely. You know, in armed conflicts around the world, there’s something known as a humanitarian deconfliction system. This is a system employed where aid organizations, U.N. agencies will transmit to the warring parties GPS coordinates of their locations, both moving convoys and fixed locations, like guesthouses where their staff are sleeping, or, you know, hospitals, other facilities where they’re operating. And the intention of transmitting those coordinates is to ensure that those locations do not come under attack, because this is where aid activities are being carried out.

    And what’s really striking in the context of Gaza and these military operations is how many times we’ve seen attacks on aid workers, whether it’s in their guesthouses or, again, as they’re moving in convoy, where those attacks come exactly at the locations that the Israeli authorities know about. In some cases, these were convoys that actually took the routes that the Israeli military told them to take, and they were still bombed, with some people being killed, along those routes with no prior warning.

    NERMEEN SHAIKH: And, Belkis, if you could just give us, you know, a comparative sense: How effective is this deconfliction system in other war zones that you’ve worked in? And then talk about some of the incidents that you document in this report, the attacks on convoys, from Doctors Without Borders to the International Rescue Committee, the World Central Kitchen and so on.

    BELKIS WILLE: Absolutely. You know, aid workers, unfortunately, die in conflict zones. That’s not something unique. But I think what’s really unique in the context of Gaza is the high number in such a short period of time. As you said earlier, over 250 aid workers have been killed since October in Gaza. That is extremely high. I cannot think of seeing a number that high in any other conflict that I’ve worked on in that same period of time.

    Deconfliction is a process that normally works. And sophisticated militaries have a way of doing deconfliction effectively when they want to do it effectively.

    In this report, we look at various incidents. As you said, there were attacks on guesthouses of Doctors Without Borders, MSF, and indeed one of their convoys. There was also one particularly egregious attack. It was on a guesthouse of a medical team that was a joint team of an NGO called MAP and IRC — IRC, the International Rescue Committee — and this guesthouse was surrounded by nothing. It’s near the beach, so it was just sand all around the building — no other buildings, no vehicles. And there was a massive airstrike on the wall next to the guesthouse. It blew through the wall. It damaged the guesthouse significantly, injured people inside. And this, again, was an incident where we know both MAP and IRC had multiple times shared their coordinates directly with the Israeli authorities, with the U.N., which shared it with the Israeli authorities, and even with the British government, which shared it with the Israeli authorities. And yet they came under attack.

    NERMEEN SHAIKH: And if you could talk about, Belkis, I mean, all of this happening in the context of this massive humanitarian crisis unfolding in Gaza? Human Rights Watch has also accused Israel of using starvation as a weapon of war. If you could talk about that, as well as the attacks on health facilities, on so many hospitals in Gaza in the last seven months?

    BELKIS WILLE: Absolutely. As you said, it’s so important to see these attacks within the broader context. Every single aid group that we have spoken to that is operating right now inside of Gaza, those that came under attack and those who are also operating in Gaza and fearful of coming under attack, have told us very clearly that these attacks on aid workers have significantly limited their ability to meet the ongoing famine in some areas, as you said, impending famine in others. They’re so worried about their own staff being killed that they’re actually having to decide to send less people into Gaza, knowing that they’re opening them up to the risk of being killed, and, when inside Gaza, severely limiting their movements and minimizing their aid footprint, just so that they can minimize the chance of coming under attack. As you said, these attacks have hit hospitals. We’ve also seen a severe restriction put in place by the Israeli military preventing aid organizations and the U.N. from bringing aid directly to northern Gaza, where the humanitarian situation is by far the worst.

    NERMEEN SHAIKH: And, Belkis, let’s talk about the support that Israel continues to receive from the U.S. despite the fact that a recent long-awaited State Department report has laid out several suspected international human rights violations by Israel and says that Israel likely used U.S.-supplied weapons in, quote, “incidents that raise concerns.” And yet, despite this report, the Biden administration suggests no changes in policy or any consequences against Israel. What are you calling on the U.S. to do?

    BELKIS WILLE: Well, first, to take that report head-on, frankly, it is surprising to have seen this conclusion that the U.S. government does not have enough information to be sure whether violations of international humanitarian law have occurred, specific ones. Human Rights Watch, Amnesty International, Oxfam and many other organizations provided hundreds of pages of evidence to the U.S. government exactly about international humanitarian law violations being conducted by Israel in Gaza.

    And this report also said that it could not determine and did not have enough information about whether Israel was blocking aid into Gaza or these violations of international humanitarian law. That is shocking coming from the U.S., such a close partner to Israel, that surely should have access to this kind of information, including their rules of engagement, including the obstacles being put in place on aid coming in and out of the country.

    As you said, the United States absolutely has to start doing more to limit military assistance to Israel. We’re calling on an arms embargo on all warring parties because of the violations being carried out. And it needs to do far more to protect civilians more broadly.

    AMY GOODMAN: Belkis Wille, we want to have you stay with us, associate director of the Crisis, Conflict, and Arms Division at Human Rights Watch. We’re going to link to your report on Gaza.

    When we come back from break — I mean, you’re in Kyiv, in the capital of Ukraine — we’re going to talk about Russian forces executing surrendering Ukrainian soldiers and also look at Human Rights Watch’s reports on Sudan, ethnic cleansing, possible genocide. Stay with us.

    The original content of this program is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.

    “American Lessons” From the Labor Notes 2024 Conference

    Portside
    portside.org
    2024-05-16 13:16:01
    “American Lessons” From the Labor Notes 2024 Conference Kurt Stand Thu, 05/16/2024 - 08:16 ...
    Original Article

    In 2023, more than half a million American workers went on strike, winning average wage increases of 6.6%. These are just some of the concrete examples of this phase of change:

    • The recent sensational victories against the three auto giants (Ford, GM and Stellantis)
    • The unionization of a large plant in the anti-union deep South (Volkswagen of Chattanooga, Tennessee)
    • The paralysis imposed by actors and authors, until victory, in the world of Hollywood
    • The unionization of 10,000 employees in 400 Starbucks coffee shops, as well as among the warehouse workers and drivers of UPS and Amazon, in Staten Island (NYC)
    • The 25% wage increase in fast food restaurants in California
    • Various victories of educators and academic workers

    Part of making this possible – to give them their due – is this peculiar network “Labor Notes”(LN). Both an editorial and political-union elaboration, LN was born in 1979, on the initiative of a group of trade union militants and radical left socialists. It first took the form of an information and struggle magazine, publishing some handbooks, two being “Secrets of a Successful Organizer” and the “Troublemakers Handbook”. The latter handbook was a text that the current President of the renewed automotive workers’ union (UAW), Shawn Fain, has defined as nothing less than his secular “Bible” as an activist, inspiring him in the radical renewal with which he first climbed the ranks of the organization, and then guided it – in these last two years – towards goals that would have seemed unthinkable, until now. 

    But Labor Notes is also a Conference that is organized every two years, with continuous and exponential growth between one edition and another. April 19-21 saw as many as 4,700 grassroots delegates and trade union officials converge on a big hotel in Chicago from all over the United States. There was also representation from various other countries, including some of us – from FIOM and FDV-CGIL – brought together to discuss, exchange experiences and ideas in almost 300 workshops on trade union and industrial relations topics. This was a very interesting format due to its extremely pragmatic, operational, horizontal and decentralized character. Aimed at achieving maximum valorization and comparison between fighting practices conducted, mostly in single production units, it was a search for the most effective and successful tools and methods. The key to this grassroots unionism lies in the connection that can and must be built between organizing – understood as the ability to represent the unorganized – conflict, and collective bargaining aimed at an agreement truly full of improvements reflected in wages, and general working and living conditions. The workshops began with short keynote speeches and many concrete experiences shared to be passed on to network and establish contacts. 

    With just a couple of moments in plenary, at the beginning and at the end, the conference was a very dense program that lasted late into the evenings. Moments of leisure, and musical or theatrical performances, produced an atmosphere of great effervescence, because of the extraordinary presence of young and very young people. Children and grandchildren of that “Other America”, which has now powerfully returned to the international political and media scene, thanks to the pro-Palestine mobilizations on many university campuses. The keffiyeh was, even in Chicago, a dominant symbol placed on t-shirts and organizational jerseys: UAW, Teamsters for a Democratic Union (TDU) or teachers, flight attendants, Amazon, UPS or Starbucks employees. 

    “How to overcome the apathy of your colleagues?”, “Overcoming workplace divisions”, “You can’t do it all yourself: learn it, do it”, “Planning for a strike”, “Before, during, and after negotiations: step-by-step strategies”. These were just some of the titles of the many workshops that each participant could choose to go to and listen and speak out in. They often sang in the halls of the Hyatt Hotel, and sometimes it almost seemed like attendance at a session of collective self-awareness, as when a workshop discussed “What to do when your union breaks your heart?”. But there were also presentations about history, as in the workshop about Socialists at work, or on the legendary figure of Walter Reuther, leader of the UAW during the “Thirty Glorious” years, from 1946 to 1970.

    What was striking, at least from an Italian viewpoint, was the almost total lack of speeches and debates regarding the current political situation. Both with respect to the Biden presidency – which had initially proclaimed itself to be the most pro-union since Lyndon Johnson’s times, and which was supportive of the autoworkers during their three-week strike – and with respect to the risk, although clearly perceived as catastrophic, of a new Trump victory. Politics, conventionally understood, was simply the great absentee of the three days in Chicago. The reason can probably be found in the idea – typical in the USA – that workers and their union representatives must first know how to do it themselves. Meaning being able to face and seek the solution to their problems with their own strength, without placing too many expectations on the policies of “friendly” governments or diverting forces and energies into an unequal clash with hostile executives. The structurally decentralized character of the U.S. state, as well as of the trade unions and North American industrial relations, has evidently contributed to this. Collective action has always had to deal with the deliberate cumbersomeness of the procedures for accessing representation in the workplace, and – above all – with the virulent hostility of employers to union recognition, representation and collective bargaining. 

    There are many States where, in the name of a misunderstood (and legally sanctioned) “right-to-work,” employers can do everything they wish to ostracize requests for representation and strikes, including the systematic use of scabs. The bosses are therefore the first and true target of trade union action; and only secondarily does state power become the target. The inter-sectoral dimension: class, gender and race are intertwined. Yet research, discussion and mobilization are not dispersed in a thousand streams but are, as they say, “focused”, on the concrete possibilities that the trade union movement can realistically translate into conquests. A well-known orientation, however, since the times in which Selig Perlman, Samuel Gompers or Walter Reuther defined the theoretical outlines for the AFL-CIO. This had significant repercussions also on the Italian trade union scenario, traditionally skeptical in its left-wing towards that “trade unionism”, stigmatized by Lenin, to be ideologically weak (more job consciousness, than class consciousness). This theory was learned and translated by the greatest master of Italian labor law, Gino Giugni, who had discovered it in the 1950s, during his Fulbright at the University of Wisconsin, Madison. With his special doctrine on collective autonomy and auxiliary legislation, as the 1935 Wagner Act, which inspired the Italian Workers’ Statute of 1970, largely edited by the Giugni, at the time adviser of the socialist Ministry of Labor. Today that old and classic “voluntarist” matrix lives again in a radical sauce, as it did in our “hot” 70s keeping its distance from those bureaucratic and collaborationist encrustations that we had known at the time when Marchionne of FIAT, in Detroit, embraced the UAW leaders and extolled their virtues and exemplary values to their Italian colleagues. A piece of that UAW union leadership – let it be said here – came to an end following scandals and convictions for the corruption of having exchanged concessions for personal gain at the expense of workers.

    Today the UAW wins again and does it in a big way as beacon of hope offering a model for everyone. The union proclaimed, and successfully concluded, three weeks of strike:

    • With resistance funds capable of covering 500 dollars a week, for each striker (when will we reflect on this instrument profitably used by many unions abroad?)
    • Increases of 25% in four and a half years (+11% immediately)
    • Re-introduction of the so-called “COLA” (cost-of-living-adjustment)
    • End of the two-tier regime, depending on professional seniority
    • Increase in the starting hourly wage, from 16.25 dollars to 22.50
    • And even a reimbursement of 110 dollars a day, lost during the strike pickets.

    The agreement passed with large majorities in all the plants that voted on it. Victories, in trade union matters, are fundamental and contagious. “We have finally ended 40 years of concession bargaining. It’s the best contract of my entire life”, testifies an elderly GM union officer. The success against the Big Three of the automakers sparked a chain reaction. With a roar in the room, on Friday the 19th of April, the news of the victory in the vote, held at Volkswagen of Chattanooga, was welcomed, with 73% in favor of finally allowing the union to represent the 4,300 employees of the plant, after two attempts failed in the recent past.

    In Chicago there was a large representation of trade union delegations from various countries; obviously Mexico – around fifty workshops were in Spanish, because of the strong presence of Latino workers. There were also significant delegations from Japan, South Korea and Europe: Unite, from the United Kingdom, the secretary of the German ver.di in person, Yanira Wolf,together with various exponents of IG Metall and the Rosa Luxemburg Foundation. The Swedish IF Metall was there to talk about the strike at Tesla (did you know that that union has one and a half billion euros – you read that right – in strike funds?) Italy was represented by the CGT and, for the CGIL, a delegation from FIOM and your author, for the Fondazione Di Vittorio (the CGIL institute of economic and social research), to report in an international workshop on a series of experiences of struggle carried out by the CGIL, in recent years. 

    Chicago, Illinois – Michele De Palma, general secretary of the Italian metalworkers union., speaks at the 2024 Labor Notes conference. The conference brought together 4,700 union activists from across the United States and beyond.. Photo: Jim West

    The speech given by Michele De Palma, General Secretary of the metalworkers federation (FIOM-CGIL) aroused great interest, and enthusiasm. He spoke in the final plenary on Sunday morning, about our common struggles alongside the star of the whole event, the UAW’s Shawn Fain, who closed the conference. His rise to the presidency of the UAW, two years ago, was made possible thanks to the campaign of its most radical faction: the Unite All Workers for Democracy (UAWD). Their rejection of any bureaucratic and collaborationist drift, their promotion of militancy and democracy from below, and an offensive strategy, produced a foundational strategy that did not take long to produce its fruits. Starting with the contract for the Three Bigs Fain’s pose and prose are all a tribute to the class imagery of his people. And, in those rooms, he pronounces highly effective phrases, which warm the heart and generate a contagious enthusiasm. The concepts, already expressed in recent speeches reported on in the “Labor Notes” magazine sounded more or less like this: 

    “We are here to put an end to business unionism, endless concessions, union corruption and the shackles that have bound us. I have said many times that negotiating good contracts leads to good success, even on an organizational level. These are two things that go hand in hand. From this point of view, our strike was not only against the “Big Three”. It belonged to the entire working class. And it is proof of one thing: that the working class can win. It can change the world. We don’t win by playing defensively or by always just reacting to things. We don’t win by being nice to the bosses. We don’t win by telling our members what to do, what to say, or how to say it. We win by giving working class people the tools, inspiration and courage to stand up for themselves. From this point of view, I think, that the working class represents the arsenal of democracy, and that the workers are the liberators”.

    When Shawn Fain finished his remarks, paraphrased above, the big hall of the hotel was rocked by a chorus of applause and chants at the end of this heartfelt speech. In the end he proposed to organize a united general strike on May 1, 2028; date on which the UAW collective agreement with the automotive “Big Three” will expire.

    Yes; the data on unionization do not show any significant changes, union density remains a modest 10% only thanks to the strong contribution of public employees (33%) – and there could be serious repercussions if a Trump election were to result in an entirely pro-employer composition, within the crucial National Labor Relation Board (NLRB). But for now that audience of fierce and enthusiastic trade union activists enjoyed this moment of unexpected successes, after the many, too many disappointments of the past years.

    There is a beautiful sunrise in Chicago, we will soon see whether it is the sign of a new and lasting spring for the American trade union movement. Let us hope that these recent conquests will speak and reverberate here in Italy too for the work and the fight that awaits us. But here in Chicago, we have seen conference methods which, due to the organizational format and – above all – the content of the approaches, it would be useful for us to scrutinize by adopting the best spirit of comparison and mutual and emulative learning.

    Salvo Leonardi is Senior Researcher in industrial relations at the Di Vittorio Foundation, the National institute of historical, economic and social research of the Italian General Confederation of Labor (CGIL), the largest and left wing trade union confederation. He attended the Chicago’s conference and took part as speaker in one of its international workshop about solidarity across the world.  He wrote and translated the article from Italian.

    Israeli Human Rights Lawyer Attacked While Documenting Settler Raid on Gaza Aid Convoy

    Democracy Now!
    www.democracynow.org
    2024-05-16 13:13:40
    Aid agencies are running out of food in southern Gaza amid Israel’s ongoing offensive in Rafah and the shutdown of the two main border crossings in the south. Some 1.1 million Palestinians are on the brink of starvation, according to the United Nations, while a “full-blown famine” ...
    Original Article

    This is a rush transcript. Copy may not be in its final form.

    NERMEEN SHAIKH: Aid agencies are running out of food in southern Gaza amid Israel’s ongoing offensive in Rafah. The World Food Programme says it’s run out of stocks in Rafah and has suspended food aid distributions there for several days. No food has entered the two main border crossings in southern Gaza for more than a week, since the Israeli assault on Rafah began and Israeli forces seized control of and closed the border crossing with Egypt. Some 1.1 million Palestinians are on the brink of starvation, according to the U.N., while a full-blown famine is taking place in the north. The U.N. Office for the Coordination of Humanitarian Affairs said today, quote, “The impact is devastating for over 2 million people.”

    AMY GOODMAN: This comes just days after Israeli settlers blocked aid trucks headed to Gaza through the occupied West Bank from Jordan. Footage of the incident shows settlers raiding the aid trucks, throwing food into the road and setting fire to vehicles at the Tarqumiyah checkpoint near Hebron in the occupied West Bank. Palestinian truck drivers say they fear for their lives after the attack.

    ADEL AMER: [translated] We went to the checkpoint, and after the check, we were surprised to see settlers on the roundabout of the checkpoint. They damaged the cars. They tore the tires off the trucks. They threw the contents of the truck on the ground. We gathered some of the products and sent some of those products on to a bulldozer and sent them to sheep farms. Around 15 trucks were damaged. Their haul was damaged. Windows of the trucks were broken. Some drivers were beaten. Some of the products were thrown away, and the whole loss for Hebron is around $2 million.

    AMY GOODMAN: At a White House press briefing Monday, U.S. national security adviser Jake Sullivan was asked by reporters about the attack on the aid convoy.

    JAKE SULLIVAN: It is a total outrage that there are people who are attacking and looting these convoys coming from Jordan, going to Gaza to deliver humanitarian assistance. We are looking at the tools that we have to respond to this, and we are also raising our concerns at the highest level of the Israeli government. And it’s something that we make no bones about. This is completely and utterly unacceptable behavior.

    AMY GOODMAN: The attack on the aid convoy was the culmination of weeks of Israeli settlers attempting to block aid trucks from reaching Gaza.

    For more, we’re going to Tel Aviv to speak with Sapir Sluzker Amran, an Israeli human rights lawyer and peace activist who documented the attack on the aid convoy right near Hebron. She’s the co-director of Breaking Walls, an intersectional feminist grassroots movement.

    Welcome to Democracy Now!, Sapir. It’s so good to have you with us. If you can describe exactly what took place, how you ended up there when the Israeli settlers attacked the aid convoy, and what exactly they did to the convoy and to you?

    SAPIR SLUZKER AMRAN: Thanks, and thank you so much for having me. Before we get into details, just to say from Tel Aviv that we are calling for ceasefire and safe return of the hostages, and hope to see this war ending as soon as possible and not seeing another one.

    So, I came on Monday. It was after a few months where they’re organizing those kinds of actions, those looting actions. Settlers and their supporters, they are organizing in those WhatsApp groups, getting notifications from inside information, actually, to know where the trucks are going and coming from, and then trying to block them or to loot and destroy the entire food on the trucks. And when I came on Monday, it was to — I wasn’t sure. It was trying to document — it was after seeing those footages, those videos that they published a few months now, trying to organize groups. But people were afraid. And they should be afraid, because they’re coming with guns and knives and axes even. And the police and the IDF is totally on their side and not protecting us. But when I was there, I came to document and to understand a bit what’s going on.

    And then, after they had this, like, first round of looting the convoy there, they started to go to another crossing in order to see if there was more trucks there, because they got an inside information again that there might be other trucks a few minutes’ drive from that crossing. I was there with another activist, and we went to the drivers of the trucks to see if we can help. And they were very surprised. They didn’t understand why there were Jewish people, Israelis, that want to help them. It took them a minute to understand that we are Arabs, but not Palestinians, we are Arab Jews, and we are with them. So, we started to pack everything again on one of the trucks. And we almost finished, and then they came back, more people — I think there were around few dozens, and then it became almost 150 people. At that time, they did whatever they want.

    So, I want to be specific. This event, I got a message on WhatsApp that this event’s starting, and they’re asking people to come around 9:30 in the morning. They were there on their way. So they were there at 10 a.m. I came at 12:00. I left, though, for my own safety. Around 3 p.m., there were dozens of people, and people kept coming. So, it happened for hours. There were a few soldiers there without a supervisor. They didn’t know what to do. They were just going around, maybe two policemen, and that’s it. And what the settlers did is tearing up the entire food that was there. There were bags of rice, bags of sugar and instant noodles in bags. And they did it in a way that we cannot repair it. They did it in a way that they were tearing everything down, jumping on the instant noodles so we cannot save it. And, yeah, that was the situation.

    We saw a lot of families there. I think that the youngest person that was there was maybe 3 years old, a kid with his father, like it was like a fun day, a festival day, and more teenagers that were there. And they did whatever they want. They laughed, they enjoyed, and they said it was the best action that we had 'til now. It was in Tarqumiyah crossing. And I think many came because it's in the area of the settlers, so it was very easy for them just to be first and to hold those trucks.

    NERMEEN SHAIKH: So, Sapir, could you talk about what the settlers did specifically to you, what happened to you? And then explain who the settlers are and what their justification is for doing that, for disrupting the aid convoys and destroying all the aid. They say that the aid is helping Hamas, and they want to obstruct its delivery until the hostages are released. Who are the settlers? And do they have any connection to the government?

    SAPIR SLUZKER AMRAN: Yeah. So, I think, just to say, I’m not the story here. Yes, I will share that I was injured. One of the settlers — so, I was — I’m not sure how, but I couldn’t stand aside when I saw them running again, going on the trucks with sugar bags, going on the trucks with their knives and weapons and axes and all kinds of sharp objects and tearing down everything. And I couldn’t. And I started to run towards them and document it and tell them, “Please, stop. Stop. What are you doing? This is food. This is food. Like, you have to understand, inside of ’48, inside Israel, we have more than 2 million people that are under the poverty line. This is food. We have, an hour from now, people that are hungry. They can be your family that are hungry an hour from here.” And they didn’t care about it.

    So I went on the truck and tried to stop them. And I called and I screamed on the IDF. There were like very young soldiers. I told them, “Come! Come and help me! This is your role! This is not my role! Come and help me! I can’t do it on my own!” And my friend was documenting it and trying also to talk with them and trying to stop them while they were doing it. And they tried to prevent her to photograph. And she managed to do it anyway.

    So, when I was on the truck, yeah, one of the settlers, in front of an IDF that was right next to us, he kind of slapped me extremely hard, and then he was trying to escape. The police was there. The police took him. I told them, “I want to press charges.” They said, “No,” and they hid him so I couldn’t document him, even though I have his photo and the video. And then, after 10 minutes, he came back, like nothing was happened. So they took him only to protect him, not for something else.

    And I was the only one that the government, that the IDF, the police, asked for to see an ID. All that time, they didn’t ask anyone from them, from the settlers, to get out of this area, that it was like a parking lot — only us, only the two of us, just the two of us. And they were just sitting there or standing there while I was telling them, “You’re standing right here. You see someone with a knife. That person, a teenager, took a knife at me.” I told them, “You see him. At least take the knife. At least take the knife so, like, he won’t attack me.” And they didn’t care about it. They were just standing aside like there is nothing that they can do, like it’s normal, what’s happening.

    AMY GOODMAN: So, Sapir, we only have a few minutes left —

    SAPIR SLUZKER AMRAN: Yeah.

    AMY GOODMAN: — and we want to know: Who are these Israeli settlers? Who are the people that destroyed the aid truck?

    SAPIR SLUZKER AMRAN: Yeah, so, those are the people, settlers, that are, you know, living in the settlements. They’re Orthodox Jews. They’re from the national Zionist Jewish stream, Zionist stream. They have many supporters in government. They are the government. It’s not that they’re supporters.

    And we know that yesterday — I want to say something like that right now I can show you — I can add you right now, Amy, to a WhatsApp group, because they’re organizing right now to do it again. So, they have this information. No one is trying to stop them. I think maybe it’s not clear that nothing has changed from Monday. They are still doing it. I don’t know what is showing on the international media, what the Israeli government is publishing. But they are doing it right now, with their names, with their numbers, and they don’t care about presenting even theirselves and documenting theirselves, because they know that nothing is going to happen to them, no circumstances, no objects, and nothing will happen at all.

    So, they are connected to the government. We know that some of them are working with the government. We know that some of them — I wouldn’t be surprised if they’re funded from the government. We have MKs, members of the parliament, the Israeli parliament, that are supporting it and coming to those actions. We have someone that is a CEO of a right-wing organization that just got, a few months ago got — he has a photo with one of the MKs, the chairman of the Knesset, giving him a diploma to thank him for his service to Israel. OK? So, they are — last week, it was the mayor of one of the big cities in the south of Israel. They are the blood, and they are part of it. What you are doing is just, we can call it, privatization, privatization of the violence, which means that the government know. They hide because of the U.S. They have to pretend that they are obeying international law. But, in fact, they don’t want to. So they have these kids, they have these settlers, they have their supporters, that they are part of their political parties, and also they’re also funding them, to tell them, “Go to this crossing and handle it.”

    AMY GOODMAN: Sapir —

    SAPIR SLUZKER AMRAN: So, that’s why the police is not intervening, because the police belongs to Ben-Gvir and those kinds of people. So, yeah.

    AMY GOODMAN: Sapir Sluzker Amran, I want to thank you so much for being with us, Israeli human rights lawyer and peace activist, who went to the Tarqumiyah crossing in Hebron to document the attack on a Gaza-bound aid convoy by Israeli settlers. She’s also the co-director of Breaking Walls, an intersectional feminist grassroots movement.

    We had this in The Times of Israel: Israeli extremists mistook, on Wednesday, two days after the attack on the convoy she described — they mistook a regular commercial truck traveling in the West Bank for a convoy carrying humanitarian aid to Gaza and attacked the vehicle. The vigilantes set a fire in the road, dumped the truck’s contents onto the pavement and assaulted the Palestinian driver. Video from the scene showed the driver lying on the street bloodied.

    When we come back, we’ll talk with Human Rights Watch about their new report on Israeli forces attacking humanitarian aid convoys in Gaza. The group has also documented Russian forces executing surrendering Ukrainian soldiers. We’ll go to Kyiv to speak with the HRW representative, and we’ll look at ethnic cleansing in Sudan. Back in 20 seconds.

    [break]

    AMY GOODMAN: Voices of some the hundred university professors and faculty and their allies from higher education institutions across New York, gathering yesterday at Grand Central Station during rush hour to sing and read out a joint letter from faculty across a number of schools calling for an end to genocide in Gaza.

    The original content of this program is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.

    Headlines for May 16, 2024

    Democracy Now!
    www.democracynow.org
    2024-05-16 13:00:00
    Gazans Flee Israeli Attacks Across the Territory as Chaos Reigns in Besieged Territory, University Human Rights Network Concludes Israel Is Committing Genocide in Gaza, Israel’s Far-Right Leaders Dispute Future of Gaza, “Biden Is Making Jews the Face of the War Machine”: First Jewi...
    Original Article

    HeadlinesMay 16, 2024

    Watch Headlines

    Gazans Flee Israeli Attacks Across the Territory as Chaos Reigns in Besieged Territory

    May 16, 2024

    The International Rescue Committee is warning the scale of the crisis in southern Gaza “defies imagination” as Israel intensifies its attack on Rafah while key border crossings remain shut down. More than 600,000 Palestinians have fled Rafah despite having no safe place to go. Another 100,000 Palestinians have fled in the north. Overnight, Israel deployed an additional commando brigade to Rafah. This is a Palestinian woman in Rafah who is in mourning after Israel killed her husband and son.

    Afaf al-Halqawi: “My son was beautiful as a moon. He was a groom. He went inside to his bride, thank God. … There’s no safe place, not in Rafah, not in Khan Younis. They slaughtered Jabaliya, they slaughtered al-Nuseirat, and they slaughtered Rafah. Safety is only with God. May God have mercy on us.”

    On Wednesday, Israel shelled a clinic in Gaza City run by the U.N. aid agency UNRWA, killing at least 10 displaced Palestinians, including children. Earlier today, Israeli forces targeted residential buildings and an ambulance in Jabaliya, killing multiple Palestinians, including a pregnant woman. Separately, five Israeli soldiers were killed Wednesday in Jabaliya when they were shelled by an Israeli tank. Seven other Israeli troops were injured in what’s being described as a friendly fire incident.

    University Human Rights Network Concludes Israel Is Committing Genocide in Gaza

    May 16, 2024

    The University Network for Human Rights has concluded in a major report that Israel is committing genocidal acts in Gaza. The report was written in partnership with law school human rights clinics at Boston University, Cornell, Yale and the University of Pretoria.

    In The Hague, the International Court of Justice is hearing arguments today from South Africa in its genocide case against Israel. South Africa is requesting emergency measures over Israel’s escalating attack on Rafah.

    Israel’s Far-Right Leaders Dispute Future of Gaza

    May 16, 2024

    Israel’s Defense Minister Yoav Gallant has publicly challenged Israeli Prime Minister Benjamin Netanyahu over Israel’s future plans for Gaza. Gallant said he opposes Israeli military or civilian rule over the Gaza Strip.

    Yoav Gallant: “We must dismantle Hamas’s governing capabilities in Gaza. The key to this goal is military action and the establishment of a governing alternative in Gaza. In the absence of such an alternative, only two negative options remain: Hamas’s rule in Gaza or Israeli military rule in Gaza.”

    Gallant’s comments came a day after another member of Netanyahu’s government, National Security Minister Itamar Ben-Gvir, took part in a march calling for Israel to resettle Gaza and expel Palestinians living there.

    “Biden Is Making Jews the Face of the War Machine”: First Jewish Biden Appointee Resigns over Gaza

    May 16, 2024

    Another member of the Biden administration has resigned to protest the president’s policies on Gaza. Lily Greenberg Call has become the first known Jewish political appointee to resign over the war. She had been working as special assistant to the chief of staff at the Interior Department. In her resignation letter, she wrote, “I can no longer in good conscience continue to represent this administration amidst President Biden’s disastrous, continued support for Israel’s genocide in Gaza.” She went on to write, “Biden is making Jews the face of the American war machine. And that is so deeply wrong.”

    Greenberg Call’s views on Israel have shifted over the years. In 2019, as a college student at the University of California at Berkeley, she served as president of Bears for Israel, which is affiliated with AIPAC, the American Israel Public Affairs Committee.

    Israeli Historian Ilan Pappé Interrogated by U.S. Agents at Detroit Airport

    May 16, 2024

    The acclaimed Israeli historian Ilan Pappé has revealed he was interrogated for two hours by federal agents at an airport in Detroit after flying into the United States. The agents questioned him about his Arab and Muslim friends in the U.S., as well as his views on Hamas and if he thought Israel was committing genocide in Gaza. Pappé said he was allowed to enter the U.S., but only after agents copied the contents of his phone.

    Germany Lifts European Ban on British Palestinian Surgeon Ghassan Abu-Sittah

    May 16, 2024

    In Europe, Germany has lifted a travel ban on the renowned British Palestinian surgeon Ghassan Abu-Sittah which had prevented him from traveling around Europe to talk about what he witnessed in Gaza. In April, Germany initially barred Abu-Sittah from attending a Palestinian congress in Berlin that authorities later shut down.

    “Refuse to Accept Hell as Normal”: Amira Hass Delivers Graduation Speech as Students Keep Up Protests

    May 16, 2024

    Student-led protests across the U.S. are continuing. Graduating students have highlighted the plight of students in Gaza as they deliver end-of-year speeches, while many have waved Palestinian flags and displayed messages of solidarity as they took to the stage to receive their diplomas. At Barnard College here in New York, students wore red poppies on their gowns, each with the name of a slain Palestinian child, and refused to shake the hand of President Laura Rosenbury.

    Meanwhile, prominent Israeli journalist Amira Hass addressed Columbia Journalism School graduates on Wednesday.

    Amira Hass: “The journalism that I chose to practice is based on the refusal to see injustice as normal, the refusal to normalize it to a point that we do not see it. This is exactly what the students here in Columbia and in so many other campuses in the U.S. and now in Europe have been doing. Refuse to accept hell as normal.”

    New School students on Wednesday took over their university’s welcome center, renaming it the Lama Center in honor of Lama Jamous, a 9-year-old aspiring journalist from Gaza.

    Sonoma State President Placed on Leave After School Agrees to Academic Boycott of Israel

    May 16, 2024

    Image Credit: Sonoma State University

    In California, the president of Sonoma State University, Mike Lee, has been placed on leave after he announced that the school had agreed to an academic boycott of Israel following talks with student protesters. The chancellor of California State University has accused Lee of insubordination.

    Unions Representing UC and Harvard Student Workers Challenge Violent Crackdown on Gaza Protests

    May 16, 2024

    In Southern California, police raided an encampment at University of California, Irvine, arresting at least a dozen demonstrators. This comes as unionized student workers across the UC system have overwhelmingly voted to authorize a strike in response to the use of force in dismantling student encampments and violation of their labor rights. The UAW Local 4811 represents some 48,000 members.

    Meanwhile, the Harvard Graduate Students Union filed a federal complaint against Harvard for surveillance and retaliation against their protest.

    And a judge in Rhode Island has rejected trespassing charges against 41 Brown University protesters. The judge said, “I think this is a reflection of what nonviolent and peaceful resistance, frankly, is supposed to look like.”

    Prime Minister of Slovakia in Stable Condition After Assassination Attempt

    May 16, 2024

    The prime minister of Slovakia has survived an assassination attempt. Robert Fico is reportedly in stable but serious condition after being shot several times on Wednesday. A 71-year-old suspect has been detained in what authorities are describing as a “lone wolf” attack. Fico is a populist leader who is an ally of Hungary’s Prime Minister Viktor Orbán. Slovakia’s President Zuzana Čaputová said the shooting was an attack on democracy.

    President Zuzana Čaputová: “A physical attack on the prime minister is primarily an attack on a person, but it is also an attack on democracy. Any violence is unacceptable. The hateful rhetoric we witness in society leads to hateful acts. Please, let’s stop it.”

    Far-Right Populist Geert Wilders Forms Dutch Coalition But Agrees Not to Become Prime Minister

    May 16, 2024

    The Netherlands is set to see its most far-right government in decades after the populist leader Geert Wilders announced his anti-immigrant Party for Freedom is forming a coalition with three other parties, six months after their victory in parliamentary elections. But the Islamophobic Geert Wilders will not become the new prime minister, after agreeing to forfeit the leadership position as part of negotiations. Wilders is still expected to wield significant power over Dutch politics. A crackdown on asylum seekers is widely expected.

    Putin Backs Beijing Peace Plan for Ukraine as He Meets with Xi Jinping in China

    May 16, 2024

    Russian President Vladimir Putin and Chinese President Xi Jinping are meeting in Beijing as Russia wages a new offensive in northeast Ukraine. Last year, China put out a 12-point peace plan to end the war in Ukraine. Earlier today, Xi said China “hopes for the early return of Europe to peace and stability.” Xi and Putin also signed a joint statement to deepen their partnership on trade, as well as on nuclear and energy cooperation.

    France Declares State of Emergency in New Caledonia After 4 Killed in Clashes with Police

    May 16, 2024

    France has declared a state of emergency and is deploying its forces to New Caledonia amid mounting unrest in the Pacific archipelago. At least four people were killed in clashes this week. Tensions have been rising as Indigenous Kanak communities protest plans to allow French residents who have lived in New Caledonia for 10 years to vote in provincial elections.

    Kanak resident: “We feel oppressed. We are angry. Everything is taking place over there in France. And us, we are wondering: Are we being heard, the Kanak people?”

    Some 40% of the population of New Caledonia is Kanak, but the island remains under French rule since its colonization by France in the 19th century. Many young people seek full independence from France.

    Activists Say Javier Milei’s Rhetoric and Policies Led to Deadly Attack on Lesbians

    May 16, 2024

    In Argentina, LGBTQ and women’s rights activists are accusing the government of far-right populist Javier Milei of fomenting violence and hate after a man set fire to four lesbians, killing three and seriously injuring the fourth. In one of his first acts as president, Milei shut down the government office that deals with hate crimes and banned the use of gender-inclusive language in the military.

    Ex-Gambian Interior Minister Ousmane Sonko Convicted for Crimes Against Humanity

    May 16, 2024

    Image Credit: NAC/Wikimedia

    Human Rights Watch is hailing a “monumental victory” after a Swiss court convicted former Gambian Interior Minister Ousmane Sonko for crimes against humanity committed under the dictatorship of Yahya Jammeh. Sonko was sentenced to 20 years in prison for his role in torture, illegal detentions and unlawful killings between 2000 and 2016. He is the second ex-Gambian official convicted in Europe for international crimes committed in Gambia, after a former death squad member received a life sentence in Germany last year.

    SCOTUS Restores Louisiana Voting Map with Additional Black-Majority District

    May 16, 2024

    Image Credit: Democracy Docket

    In U.S. election news, the Supreme Court has restored, for now, a Louisiana congressional voting map that includes two Black-majority districts. The ruling upholds a map drawn in January which introduced the second Black district, and it overrules a federal court ruling that blocked that map in late April. Wednesday’s Supreme Court decision comes as a major win for Democrats, who are hoping to retake control of the House in November.

    Biden and Trump Agree to 2 Network Debates, Eschewing Debate Commission

    May 16, 2024

    President Biden and Donald Trump have agreed to two presidential debates. The first debate will be hosted by CNN on June 27 without a live audience. The second debate is scheduled for September 10, hosted by ABC News. The campaigns opted to arrange the debates directly with the networks instead of the Commission on Presidential Debates, which has set up every presidential debate since 1988. If the debates go ahead as planned, June’s event would be the earliest-ever presidential debate and come before either candidate is officially nominated at their parties’ conventions.

    The original content of this program is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License. Please attribute legal copies of this work to democracynow.org. Some of the work(s) that this program incorporates, however, may be separately licensed. For further information or additional permissions, contact us.

    Zero-Trust DNS

    Schneier
    www.schneier.com
    2024-05-16 12:03:58
    Microsoft is working on a promising-looking protocol to lock down DNS. ZTDNS aims to solve this decades-old problem by integrating the Windows DNS engine with the Windows Filtering Platform—the core component of the Windows Firewall—directly into client devices. Jake Williams, VP of rese...
    Original Article

    Microsoft is working on a promising-looking protocol to lock down DNS.

    ZTDNS aims to solve this decades-old problem by integrating the Windows DNS engine with the Windows Filtering Platform—the core component of the Windows Firewall—directly into client devices.

    Jake Williams, VP of research and development at consultancy Hunter Strategy, said the union of these previously disparate engines would allow updates to be made to the Windows firewall on a per-domain name basis. The result, he said, is a mechanism that allows organizations to, in essence, tell clients “only use our DNS server, that uses TLS, and will only resolve certain domains.” Microsoft calls this DNS server or servers the “protective DNS server.”

    By default, the firewall will deny resolutions to all domains except those enumerated in allow lists. A separate allow list will contain IP address subnets that clients need to run authorized software. Key to making this work at scale inside an organization with rapidly changing needs. Networking security expert Royce Williams (no relation to Jake Williams) called this a “sort of a bidirectional API for the firewall layer, so you can both trigger firewall actions (by input *to* the firewall), and trigger external actions based on firewall state (output *from* the firewall). So instead of having to reinvent the firewall wheel if you are an AV vendor or whatever, you just hook into WFP.”

    Tags: ,

    Posted on May 16, 2024 at 7:03 AM24 Comments

    Sidebar photo of Bruce Schneier by Joe MacInnis.

    Forgotten APL Influences (2016) [pdf]

    Hacker News
    pok.acm.org
    2024-05-16 11:19:01
    Comments...
    Original Article
    No preview for link for known binary extension (.pdf), Link: https://pok.acm.org/meetings/foils/McGrew18paper.pdf.

    What’s up with ChatGPT’s new sexy persona? | Arwa Mahdawi

    Guardian
    www.theguardian.com
    2024-05-16 11:15:05
    OpenAI’s updated chatbot GPT-4o is weirdly flirtatious, coquettish and sounds like Scarlett Johansson in Her. Why? “Any sufficiently advanced technology is indistinguishable from magic,” Arthur C Clarke famously said. And this could certainly be said of the impressive OpenAI update to ChatGPT, calle...
    Original Article

    “Any sufficiently advanced technology is indistinguishable from magic,” Arthur C Clarke famously said. And this could certainly be said of the impressive OpenAI update to ChatGPT, called GPT-4o, which was released on Monday. With the slight caveat that it felt a lot like the magician was a horny 12-year-old boy who had just watched the Spike Jonze movie Her.

    If you aren’t up to speed on GPT-4o (the o stands for “omni”) it’s basically an all-singing, all-dancing, all-seeing version of the original chatbot. You can now interact with it the same way you’d interact with a human, rather than via text-based questions. It can give you advice, it can rate your jokes, it can describe your surroundings, it can banter with you. It sounds human. “It feels like AI from the movies,” OpenAI CEO Sam Altman said in a blog post on Monday. “Getting to human-level response times and expressiveness turns out to be a big change.”

    It hasn’t gone unnoticed that when Altman says “AI from the movies”, he seems to be referring to the 2013 movie Her, which featured a lonely writer falling in love with an operating system (voiced by Scarlett Johansson) designed to meet his every need. In many of the demonstrations, the bot’s voice sounds a lot like Johansson. And after the OpenAI event on Monday, Altman tweeted with a single word: “her”.

    There’s nothing wrong with giving your chatbot a voice like Johansson in Her. What does feel a little weird, however, is making your chatbot weirdly flirtatious and coquettish. While the chatbot has a male voice in some of the demo videos (namely the one in which it helps a new dad practice dad jokes), a number of the demo videos, including one where she helps someone with interview prep, feature the Johansson-like voice sounding oddly seductive.

    “Am I the only one that gets the ick from how flirty this is?” technologist Nick St Pierre asked on Twitter/X, linking to the interview prep videos. Judging by the responses to his tweet, he wasn’t.

    While GPT-4o’s flirtatiousness was glossed over by a lot of male-authored articles about the release, Parmy Olson addressed it head-on in a piece for Bloomberg headlined Making ChatGPT ‘Sexy’ Might Not End Well for Humans.

    “What are the social and psychological consequences of regularly speaking to a flirty, fun and ultimately agreeable artificial voice on your phone, and then encountering a very different dynamic with men and women in real life?” Olson asks.

    OpenAI didn’t get back to Olson when she posed them that question. But they didn’t need to. We don’t have to hypothesize about the consequences of giving GPT-4o the ability to sound like a submissive young woman who caters to your every need because there’s already a ton of data on this. We’ve been having conversations about the social impact of female-sounding voice assistants like Apple’s Siri and Amazon’s Alexa for a very long time now.

    In 2018, for example, USC sociology professor Safiya Umoja Noble warned that the gender of assistants’ voices affects how we speak to them. Noble told New York Magazine that virtual assistants have produced a “rise of command-based speech at women’s voices. ‘Siri, find me [fill in the blank]’ is something that children, for example, may learn to do as they play with smart devices. This is a powerful socialization tool that teaches us about the role of women, girls, and people who are gendered female to respond on demand.”

    A highly influential 2019 Unesco report echoed Noble’s warning. “Because the speech of most voice assistants is female, it sends a signal that women are obliging, docile and eager-to-please helpers, available at the touch of a button or with a blunt voice command like ‘hey’ or ‘OK’,” the report said.

    What’s crucial to note here is that these voice assistants don’t just send a signal about gender norms, they send it at massive scale. The Unesco report explains, for example, that Apple’s Siri “made ‘her’ debut not as a genderless robot, but as a sassy young woman who deflected insults and liked to flirt and serve users with playful obedience … This technology was a flagship feature in the nearly 150m iPhones Apple sold from late 2011 and through 2012. This singular technology – developed behind closed doors by one company in one state in one country, with little input from women – shaped global expectations of what an AI assistant is and should be, in a mere 15 months.” And, indeed, you can draw a direct line from Siri’s personality to flirty GPT-4o.

    That 2019 Unesco report came with a call-to-action. “The world needs to pay much closer attention to how, when and whether AI technologies are gendered and, crucially, who is gendering them,” Saniye Gülser Corat, Unesco’s director for gender equality, said.

    Big tech has paid some lip service to this and has started offering more masculine voice options with their voice assistants. Still, the new and improved ‘sexy’ version of ChatGPT seems to make it clear that nobody at OpenAI seems particularly interested in paying attention to how AI technologies are gendered and the ramifications of this. This might be because it’s a male-dominated company which didn’t have a single woman on its board for a few months. (They appointed three women board members in March.) It might be because they have board members like Larry Summers: the economist and former Harvard president who, in 2005, famously downplayed discrimination and suggested that men outperform women in maths and sciences because of biological difference. (He later apologized.) Or it might just be because they can’t be bothered to think about things like gender; it simply doesn’t interest them.

    For all the ooh-ing and ahh-ing about how innovative ChatGPT is and how it’s going to change the world, it feels like nothing has changed when it comes to misogyny in tech. It’s frustrating that we are still having the same conversations about bias in digital technology that we’ve been having for more than a decade. It’s infuriating that some of the highest-paid people in the world, people who are regularly lauded as the greatest minds of their generation, are still seemingly oblivious to gender norms and their roles in perpetuating them. We’re constantly being told that OpenAI is building the future, but I don’t really know whether a sexy ChatGPT is progress.

    University Professors Are Losing Their Jobs Over “New McCarthyism” on Gaza

    Intercept
    theintercept.com
    2024-05-16 10:00:00
    As brutal police repression sweeps campus encampments, schools have been cutting ties with pro-Palestine faculty members without tenure. The post University Professors Are Losing Their Jobs Over “New McCarthyism” on Gaza appeared first on The Intercept....
    Original Article

    Many scholars committed to Palestinian liberation can no longer do their jobs. That’s because many of the professors most supportive of Palestine don’t have jobs anymore.

    This is nowhere truer than in the Gaza Strip — where all 12 universities have been reduced to rubble, and more than 90 professors have been reported killed during Israel’s assault on the territory. The gravity of what United Nations experts warn could amount to U.S.-backed “scholasticide” has no equivalent on American soil.

    Yet Israel’s attempted eradication of intellectual life in Gaza echoes far beyond the territory, with U.S. universities ensuring that some professors vocal in their support of Palestine can no longer do their jobs either.

    Since the beginning of Israel’s war on Gaza, academics in fields including politics, sociology, Japanese literature, public health, Latin American and Caribbean studies, Middle East and African studies, mathematics, education, and more have been fired, suspended, or removed from the classroom for pro-Palestine, anti-Israel speech.

    These educators have little in common. They live in different cities and states and hail from different countries. Some have been teaching in their institutions for decades, some were newly hired. Some taught at private universities, others public. They have varying degrees of job security, from a tenured professor to the most precarious adjunct contracts. And they are racially, ethnically, religiously, age, and gender diverse.

    What they share is that, in recent months, they have all staked out positions in favor of Palestinian freedom — positions that lead them to be targeted by pro-Israel groups.

    From campus to campus, professors have defended students’ right to protest, but when scholars themselves espouse support for Palestine and opposition to the Israeli state, professional consequences have frequently been grave.

    There’s no official tally of the number of academic workers who have lost jobs or faced suspension over support for Palestine, not least because higher education in this country is disarticulated, often privatized, and reliant on short-term contract labor. By and large, professors facing job loss and suspensions over Palestine have brought these allegations into public view by speaking out themselves. Scores of academics across the country are likely under investigation, and many stand to have their contracts quietly expire without renewals.

    The Intercept spoke with more than a dozen professors, both adjuncts and those with tenure, whose employment has been imperiled by their pro-Palestine speech. Of the professors I talked to, all were at one point under investigation since October 7; some of the probes closed without findings of wrongdoing. Several faced varying degrees of suspensions, and four of the professors lost their jobs or expect to lose them next week when the semester ends without the renewal of their contracts.

    The interviews, including those with campus labor activists and academic associations, revealed a pattern of politically motivated repression where campaigns by pro-Israel advocates can mar the careers of academics because of comments that express outrage at Israel’s ongoing occupation and its war in Gaza.

    “Of the cases that we’ve opened, none of them have been related to pro-Israel speech. All of them have been in support of the Palestinian cause.”

    “The bulk of our inquiries, even our cases, have to do with violations of due process related to non-reappointment, to dismissal, to tenure award, et cetera,” said Anita Levy, senior program officer with the American Association of University Professors. Levy told me that the nonprofit organization, which advocates for faculty rights and academic freedom, currently has opened five cases in recent months related to pro-Palestinian speech.

    “When we get five or six of these cases in a two-month period, where there are suspensions related to social media posts over a current event, shall we say, the war in Gaza, that is unusual,” she said. “Of the cases that we’ve opened, none of them have been related to pro-Israel speech. All of them have been in support of the Palestinian cause.”

    We are at the dawn of a “new McCarthyism,” Levy said. “This may be the tip of the iceberg.”

    Institutions are well positioned to eliminate political dissenters from their payrolls under the misleading banner of protecting Jewish people, primed by heightened Republican attacks on higher education.

    “This is beyond the new McCarthyism. This has to deal fundamentally with Islamophobia, anti-Muslim racism, anti-Arab racism, anti-Palestinian racism,” said Mohamed Abdou, who is a visiting professor in Middle Eastern, South Asian, and African studies at Columbia University — that is, until this semester ends.

    Columbia President Minouche Shafik announced that the university was cutting ties with Abdou during a congressional hearing last month about antisemitism on campus. Abdou was one of five professors named by the school administrator but the only one without the relative protection of tenure. His one-year contract ends this month.

    “What she effectively did was blacklist me globally,” Abdou told me of Shafik’s testimony. (Columbia did not respond to a request for comment.)

    Abdou said he was smeared for words in a Facebook post on October 11 that were taken dramatically out of context. The activist-scholar was framed in Congress and in the right-wing media as an antisemite and Hamas supporter. His lengthy post asks readers to think about a future for Palestine, and support for resistance, beyond the binary of a secularized, Eurocentric state formation, or “Hamas and Islamic Jihad’s neoconservative idea of Sharia.”

    “I’m against any form of authoritarianism,” Abdou — whose work focuses on Islam, anarchism, and settler colonialism since 1492 — told me.

    One extramural social media post has been weaponized to undo Abdou’s career, after 20 years of teaching in Canada, Egypt, and the U.S. in fields including queer studies and Indigenous studies, leaving the scholar with scant recourse and limited options. He is hardly alone.

    “Fired After 18 Years”

    Anti-Palestinian repression on U.S. campuses since October 7 has not been subtle. Students and faculty face far-reaching discriminatory censure and defamatory allegations for pro-Palestinian advocacy, as administrators jump to appease pro-Israel donors and conservative political interests.

    In the last months, school administrators called in riot cops to clear student encampments and arrest thousands at Columbia University, City College of New York, Emerson College, Emory University, New York University, the University of Austin at Texas, and more. It was brutal state violence against students not seen since the campus movement against the Vietnam War — justified this time by flimsy claims about student safety, undergirded by a conflation of anti-Zionism and antisemitism.

    There have been scenes of faculty solidarity. Last week, faculty members at the New School in New York, where I teach, launched the first faculty-led solidarity encampment, following the shuttering of the student encampment with mass arrests. In late April, dozens of professors and others from New York University formed a line around their protesting students as police were called in to raid their encampment; faculty and students were all arrested together. Footage capturing the arrests of Emory Philosophy Department Chair Noëlle McAfee and economics professor Caroline Fohlin, the latter who was slammed brutally to the ground by cops, was shared widely online.

    Yet once media attention moves away from encampment sweeps and violent arrests, many professors who have lost work will still be without their livelihoods or left facing precarious futures with their reputations unfairly besmirched.

    “I was fired after 18 years as a professor of Latin American and Caribbean studies at John Jay College of Criminal Justice,” Danny Shaw said. He was told last month by administrators at the college, which is part of the public City University of New York system, that he would not be reappointed to his longtime adjunct position. Shaw’s colleagues had moved to reappoint him but were overruled by John Jay President Karol Mason, according to an open letter from the economics department.

    “The non-reappointment of Danny Shaw is an unacceptable action,” Shaw’s colleagues in the economics department wrote in their open letter. “Danny Shaw is a valuable member of his department who has been teaching at John Jay since 2007. Professor Shaw is an excellent teacher who has received a Distinguished Teaching Award.”

    NEW YORK, NEW YORK - MAY 09: Cresa Pugh, new school professor of sociology, blocks of a police school safty van, holding arrested students outside the New School faculty's pro-Palestinian encampment on May 09, 2024 in New York City. The New School faculty set up the first faculty-led, pro-Palestinian encampment in memory of Refaat Alareer, a Palestinian professor, poet, and writer who was killed in an Israeli airstrike last December. (Photo by Michael Nigro/Sipa USA)(Sipa via AP Images)
    Professors block a police van holding arrested students outside the New School faculty’s pro-Palestinian encampment on May 9, 2024, in New York City. Photo: Michael Nigro/Sipa via AP Images

    The dismissal followed right-wing, pro-Israel online harassment, Shaw said, in response to his showing vocal support for Palestine and opposition to Israel following October 7 and the start of Israel’s bombardments.

    “I saw a genocide in motion, so I began to organize demonstrations and teach-ins and conferences,” Shaw told me.

    On his X account in mid-October, in the wake of stridently bellicose remarks from Israeli officials, Shaw wrote in a now-deleted post that Zionism “is beyond a mental illness; it’s a genocidal disease.” The target was unambiguously Zionist ideology and its adherents, not Jews for being Jewish. The speech is also clearly within the bounds of First Amendment protections. It was, of course, decried as antisemitic.

    The pattern is now familiar. Zionist groups like Canary Mission and Antisemitism.org, which have made a business of going after faculty and students online, single out those on campus with pro-Palestine views. Universities then face political and donor pressure to censure the targeted professors.

    Many academics now facing termination, suspension, or having their contracts not renewed told me their open support for Palestinian freedom was nothing new and had never been a significant issue before. “I’ve been doing Palestinian solidarity work since the 1990s when I was a teenager,” Shaw said.

    At the time John Jay cut ties with Shaw, CUNY was facing increasing pressure from the city and state, with the threat of funding loss tied to trumped-up claims of spiking antisemitism on campus. In late October, New York Gov. Kathy Hochul ordered an independent investigation into antisemitism at CUNY. (A spokesperson for John Jay College said the school can’t comment on personnel matters.)

    CUNY has ended its relationship with at least on other professor because of speech related to Israel’s war on Gaza. One, Lisa Hofmann-Kuroda, a scholar of Japanese literature formerly at CUNY’s Hunter College, told me in a statement that a student reported several of her pro-Palestine social media posts to the head of her department in November. Nothing in the posts, she noted, was antisemitic. “The only thing I have done,” she said, “is to criticize the state of Israel for its 75-year brutal occupation of Palestine and criticize Americans for their complicity or silence in this genocide.”

    Pro-Israel speech incurs consequences much less frequently, but it does happen. In one case, Arizona State University put postdoctoral research fellow Jonathan Yudelman on leave after a video of a pro-Israel rally went viral. In the video, shot near campus in May, Yudelman gets in the face of a woman in a hijab, who says her religious boundaries are being violated. Yudelman replies, “You disrespect my sense of humanity, bitch.” A statement released by the school last week said that Yudelman “is on leave from Arizona State University pending the outcome of an investigation” into the incident. The statement said that, prior to the event, “Yudelman had already resigned his position at ASU, effective June 30, and he was not scheduled to teach any additional courses.”

    Yudelman’s case is a rare exception to the rule that treats support for Palestine as a professional liability.

    Tenure in the Age of Unsafety

    What the late, legendary civil rights attorney Michael Ratner coined as “the Palestine exception to free speech” is not new, though its escalation in the months since October has been ferocious.

    “Repression of anti-Zionism has a long and ugly history in academe. It really started to pick up after 1967,” Palestinian American scholar and author Steven Salaita told me by email, referring to the period of the 1967 Arab–Israeli War, a time when support for Israel was growing in the U.S. “Too many people to remember have been negatively affected. But it’s worse now than I’ve ever seen it.”

    Salaita was fired for pro-Palestinian speech in 2014, a forerunner for the current repressive moment. After Salaita was let go from a tenured position in American Indian Studies at the University of Illinois over tweets criticizing Israel, a public records request on Salaita’s behalf revealed communications between the university and several wealthy donors threatening to withdraw financial support unless Salaita was fired. The university eventually settled a lawsuit by Salaita for $875,000.

    “I’d say that on the one hand my situation with the University of Illinois a decade ago is exactly like what so many of my colleagues and comrades currently suffer,” Salaita told me. “On the other hand, my situation was different insofar as I was fired from a tenured professorship, which is highly uncommon.”

    In recent years, right-wing culture warriors and administrators with their eyes on the bottom line have been trying to find ways to fire tenured professors. As political theorist Joshua Clover, a tenured professor at the University of California, Davis, pointed out, universities for the most part have only been able to achieve this by closing down whole departments on purported economic grounds. The attack of pro-Palestinian speech, though, offers a whole new avenue, under the guise of protecting Jewish students.

    Broad and vague charges of “making students feel unsafe” allow universities to scrutinize everything a professor does, inside or outside of the classroom. Clover, who has himself been targeted by Canary Mission for anti-Zionist speech, told me this enables “extramural speech to be treated as something relevant to people’s work situation.”

    “There’s nothing extramural anymore,” he said. “We’re all at work 24 hours a day, wherever we are.”

    It was extramural speech — an essay for a leftist publisher — that earned a suspension from teaching for Jodi Dean, a tenured political theorist at Hobart and William Smith Colleges in New York, where she has taught for 30 years. (She remains employed at the university.) Her essay was condemned for describing seeing images of the breach of the Gaza wall on October 7 as “exhilarating,” and the college president said in a letter that there “may be students on our campus who may feel threatened in or outside of the classroom.”

    “I have been here for 20 years and I haven’t seen anything like this,” Paul Passavant, a professor of politics at Hobart and William Smith, told Middle East Eye of Dean’s suspension. “​​It is a total violation of academic freedom. And it violates the integrity of the institution as an academic institution.”

    In response to requests for comment, a Hobart and William Smith spokesperson forwarded three letters from university leadership that had been sent out to the college community in mid-April.

    “Professor Dean has the right to express her views,” the school’s provost and dean of faculty Sarah Kirk wrote in an April 15 letter. “It is also true that Hobart and William Smith has the obligation under federal anti-discrimination laws, including Title VI, to investigate and take prompt action where the possibility exists that there is a hostile environment based on national origin, shared ancestry, or other protected classes that may interfere with a student’s ability to learn and enjoy the benefits of an education.” The letters all say that Dean has been “relieved” of classroom duties while she is under investigation by the school.

    Activist and scholar Amin Husain likewise was punished for extramural speech. He had called for Palestinian liberation for many years, but he was only suspended from his adjunct position at New York University in January of this year.

    “I’ve been teaching for seven or eight years. Never one complaint.”

    Husain told me that the university’s human resources department questioned him not only about his anti-Zionist statements, but also about social media content posted by an abolitionist art collective, Decolonize This Place, that he is affiliated with. None of the collective’s posts were attributed to Husain specifically.

    “I’ve been teaching for seven or eight years. Never one complaint,” Husain told me. He added that his suspension was not the result of a student complaint but evidence taken from “doxing outlets.” While he is technically suspended, Husain is an adjunct with a contract ending this month. (NYU did not respond to a request for comment.)

    “I’m never going to be hired by NYU,” he told me. Of the university, he said, “You destroyed my reputation, and you never even did the due diligence.”

    A letter of support for Husain, signed by over 2,000 artists, writers, academics, and students, said, “These attacks on speech (and speakers) reflect the ideology behind the logic of destruction inflicted on the cultural infrastructure of Palestine itself.”

    AUSTIN, TEXAS - MAY 05: Professor Craig Campbell speaks alongside gathered faculty on the South Lawn at the University of Texas at Austin on May 05, 2024 in Austin, Texas. During a rescheduled May Day rally, students and faculty gathered on the South Lawn to continue calling upon the university to fully divest from Israel.  (Photo by Brandon Bell/Getty Images)
    Professor Craig Campbell speaks alongside gathered faculty to demand that the University of Texas at Austin divest from Israel, on May 5, 2024, in Austin, Texas. Photo: Brandon Bell/Getty Images

    “Now Is the Time”

    The issue of academic freedom on Palestine is inseparable from the labor struggles that have been rocking universities over the past decade.

    “Until recently, labor unions in this country have been incredibly weak, the impact of which is emboldened university leaders who are enacting increasingly repressive policies on their campuses,” Molly Ragan, a union organizer with UAW Local 7902, who teaches at the Parsons School of Design, part of the New School university. “What I’ve learned in my two years as a UAW staff organizer working with faculty and student workers in NYC is that the labor movement and pro-Palestine movement go hand in hand.”

    Alongside the New School’s Students for Justice in Palestine chapter, two student worker unions, both unionized with the UAW, organized the student-led encampment on campus. Two weeks ago, that protest camp was cleared out in a surprise police raid involving over 40 arrests.

    Ragan noted that labor involvement aimed to provide “a legal shield for the encampment because any retaliation is a violation of our basic Section 7 right to concerted activity under the NLRA” — a reference to the National Labor Relations Act’s protection of workplace collective action. On Monday, ACT-UAW Local 7902 filed an unfair labor practice charge against the school over the arrests on campus and treatment of the encampment participants.

    The importance of supporting scholars who speak out for Palestine, however, goes far beyond free speech and worker protections. Israel’s occupation and its ongoing brutal war are constant reminders of the more salient issues at work.

    “If silence is the desired outcome, then Zionist organizations are failing miserably.”

    Despite continuous police raids, the protest camps are spreading. Nearly 200 campuses nationwide established encampments in the last month to demand divestment from Israel, its military apparatus, and the corporations that benefit from it.

    “I don’t think the repression will work, not if its ultimate goal is to keep people quiet. If the goal is punishment in and of itself, then the tactic is effective,” Salaita, the scholar, told me. “But if silence is the desired outcome, then Zionist organizations are failing miserably, and will continue to fail miserably. Nobody’s going to stop talking about Palestine at this point.”

    Clover, the Davis professor, echoed the sentiment. “If you’re going to be fired for standing up for Palestine, now is the time to do it anyway,” Clover said. “Now is the time to do it in the most serious and principled ways.”

    Nowhere is this principled defiance better exemplified than among the Palestinian scholars who have lost the most.

    “We will never tire, be frightened, or threatened to stop advocating for justice and peace and to stop the ongoing slaughter and genocide in Palestine,” Ahmed Alhussaina, the vice president of Israa University, one of Gaza’s most celebrated institutions of higher education and research, told me by email.

    “It’s really a shame to witness such a disgrace in the American political system,” said Alhussaina. “There is a McCarthyite campaign to silence the Palestinian voice in all American universities, large and small, but there is broad determination and support for Gaza and Palestine in all universities, and it will be difficult to contain this youth tide.”

    Alhussaina, who has lost 102 relatives to Israel’s onslaught, fled Gaza in November. At the start of the war, the Israeli military seized his university and turned it into a barracks and a detention center, before destroying it in a massive, controlled explosion.

    Best podcasts of the week: The stone cold truth about the scandal that rocked curling

    Guardian
    www.theguardian.com
    2024-05-16 09:45:21
    How can one broom tear apart a Canadian curling community? John Cullen investigates in Broomgate. Plus: five of the best post-apocalyptic podcasts • Don’t get Hear Here delivered to your inbox? Sign up here BroomgateWidely available, episodes weeklyNever before has a broom been responsible for so mu...
    Original Article

    Picks of the week

    Broomgate
    Widely available, episodes weekly
    Never before has a broom been responsible for so much scandal – in 2015, the Canadian curling community was rocked by a team that used one instead of two. “To not have the other person out front cleaning in a frosty situation doesn’t make sense,” said one shocked commentator. The full story has never been told, so comedian and curling geek John Cullen investigates the switch to the “super broom” that caused a furore. Hannah Verdier

    This Is History Presents … The Iron King
    Widely available, episodes weekly
    He was handsome, but he was murderous: Philip the Fair of France is the subject of this spin-off from the hit series. Hoot of a medieval expert Danièle Cybulskie brings the graphic details on a period of history that saw the king involved in adultery, vicious murders and a battle for succession. HV

    The Girlfriends
    Widely available, episodes weekly
    Amateur sleuths Carole Fisher, Mindy Shapiro and Alayne Katz brought solidarity to crime podcasting when they investigated the murder of Gail Katz. Now they’re back to ask what happened to a woman whose body was found and mistaken for Katz, displaying the same beautiful loyalty to each other and the victim. HV

    Team GB swimmer Tom Dean, host of Tom Dean Medal Machine.
    Team GB swimmer Tom Dean, host of Tom Dean Medal Machine. Photograph: Dave Hunt/EPA

    Tom Dean Medal Machine
    Widely available, episodes weekly
    Team GB swimmer Tom Dean is going for a record-breaking five medals at the Paris Olympics and in this second series he continues to speak to people who can inspire him. That sounds worthy but it isn’t. Steve Backshall is the first guest, talking about his wife Helen Glover’s Olympic rowing hopes, his own challenges and the importance of clean water. HV

    The Six Billion Dollar Gold Scam
    BBC Sounds, all episodes out Sun
    The gripping story of this new series begins in 1995, deep in the Indonesian jungle, where Canadian mining company Bre-X claim to have struck gold. Then the whole thing is revealed as a scam, the company’s chief geologist mysteriously dies, and the investors lose millions. Host Suzanne Wilton is determined to find out what went down in the jungle. Ellen E Jones

    There’s a podcast for that

    Los Angeles, the setting for zombie apocalypse show We’re Alive.
    Los Angeles, the setting for zombie apocalypse show We’re Alive. Photograph: Stefani Reynolds/AFP/Getty Images

    This week, Ella Braidwood chooses five of the best post-apocalyptic podcasts, from a drama about zombies in LA to a cult queer horror show.

    We’re Alive
    This audio drama originally ran between 2009 and 2014, and was highly rated for its quality sound, rich storytelling and tense moments over the course of four seasons. The podcast follows US soldier Michael (Jim Gleason) and his fellow reservists Saul (Nate Geez) and Angel (Shane Salk) as they fight to survive a zombie apocalypse in downtown LA, fleeing to “The Tower” in the hope of finding safety. Its producers have released several dystopian spin-offs, which have also been well-received: Lockdown (2016), Goldrush (2019), and Descendants (2022-2023).

    Hello from the Hallowoods
    Described as a queer horror podcast, this ongoing series has gained a loyal fanbase since its beginnings in 2020 and returned for season four earlier this year. The drama follows the residents of a forest (“The Hallowoods”) at the end of the world. Serious subjects are explored – including grief, isolation and religious trauma – but there is plenty of joy, too, and the series has been praised for its heartfelt LGBTQ+ representation. Sound effects range from eerie to calming, with its writer, William A Wellman, providing the soothing voice of the podcast’s narrator-character Nikignik.

    Impact Winter
    Written, directed and executive produced by Travis Beacham, co-writer of Pacific Rim, this audio drama has a solid cast and crew behind it: it’s also executive produced by some of the team behind The Walking Dead, and its stars include Holliday Grainger and Bella Ramsey. The show is set in the near future, some years after a comet struck Earth. With the sun blotted out, survivors band together underground, with a young woman named Darcy (Grainger) leading the fight against the vampires outside. It’s a very British drama, complete with transmissions from a fictional Home Office and the word “blighter”.

    Rapture 518

    This Canadian audio drama opens with Dr Sarah Penn, a resident physician, as she broadcasts from room 518 of an apartment building called Rapture. With the world engulfed by a mysterious pandemic, those unfortunate enough to have been infected have turned into flesh-eating sociopaths. As such, Penn’s transmission comes from a place that she can only describe as the “end of the world”. Episodes are relatively short, making for bite-size chapters, and while the audio is relatively minimalistic it adds to the dystopian feel. The creator of the show remains anonymous, but they have a heartwarming presence online, personally responding to reviewers and Reddit threads.

    skip past newsletter promotion

    The Phenomenon
    Launched in 2017, The Phenomenon ran for four seasons and is based on RK Katic’s book of the same name about a supernatural threat that has left humanity on the brink of extinction. Survivors must stick to three rules to stay alive: “Do not look outside. Do not look at the sky. Do not make noise.” The first three seasons of the podcast, written by Jared J Smith, follows survivors from the initial cataclysmic incident to an alien invasion. The fourth season is set sometime later, once “the monsters” have gone, and sees a different writer taking on each episode. The high quality audio and sound effects deserve a shoutout.

    Why not try …

    • Journalist Becky Milligan unpicks the unsolved and very suspicious murder of a Bulgarian monarch in The Butterfly King.

    • “Creativity, spirituality and psychology” are the anchors of US Office actor Rainn Wilson’s wonderfully woo podcast, Soul Boom.

    If you want to read the complete version of the newsletter please subscribe to receive Hear Here in your inbox every Thursday

    Lorelei and the Laser Eyes review – eerie visuals and a thrilling story

    Guardian
    www.theguardian.com
    2024-05-16 09:30:03
    Annapurna Interactive; PC, SwitchThis compulsive atavistic mystery is told through bewildering yet tantalising non-linear narrative strands that the player must tease apart It is both a pleasure and a relief to discover that while the titans of the mainstream games industry are tearing themselves a...
    Original Article

    It is both a pleasure and a relief to discover that while the titans of the mainstream games industry are tearing themselves apart in their unquenchable thirst for shareholder value, there are still smaller companies out there making brilliant, original games. This month, we’ve already seen Crow Country and Animal Well, and now here is the latest highly stylised puzzler from Swedish studio Simogo, previously responsible for eerily folkloric Year Walk and groundbreaking audio-textual adventure Device 6. It is, in short, one of the most compulsive mystery games I’ve played for years.

    The set up for Lorelei and the Laser Eyes is classic adventure territory. A woman is invited to an abandoned hotel in Siracuse, Italy, by an eccentric artist who says he needs her support to complete an ambitious, perhaps even revolutionary project. But what is really going on in this labyrinthine building, and what has happened to the family that owned it for generations? The answers lie behind an array of locked door puzzles, the solutions hidden in odd movie posters, notes and strange phone calls. There are artefacts connected to an avant garde film director, a dadaist artist, a stage magician; there are secret rooms and hidden passages, and at the heart of it all is a time-spanning atavistic mystery told through multilayered narrative strands that the player must tease apart in a brilliantly non-linear fashion.

    Lorelei and the Laser Eyes
    Secret rooms and hidden passages … Lorelei and the Laser Eyes. Photograph: Annapurna Interactive

    Confused? You will be. Combining the original Resident Evil with the excellent smartphone series The Room, Lorelei and the Laser Eyes is a vast puzzle box, with every room containing some clue or question to tantalise you with the promise of new revelations. Can’t solve one picture clue involving weird red paintings? Fine, try that locked safe you found in a different room or dark passage – try that statue clearly missing a key component. Answers require logic and memory, as well as a knowledge of roman numerals, zodiac signs and strobogrammatic numbers. It is obtuse, often bewildering stuff.

    Beautifully matching the noirish feel of the story, with its sinister men and forlorn heiresses, are the expressionistic, almost monochrome visuals. Dizzying camera angles turn rooms into crooked fairground funhouse rides, shadows jut into each scene like daggers. It’s never clear what time period you’re in, although time is a major theme throughout – key dates in the family’s history crop up again and again, as history folds in on itself. All too often, any game that even hints at surrealism is written off as “Lynchian” but Lorelei has much more in common with Argento or Jodorowsky in its use of repeated symbols, uncanny threats and sickly, sensual aesthetics.

    Right at the start, players are advised to grab a notebook and pen – and yes, you will need them. Instructions are kept to a minimum and though there are plenty of clues to gather and continually re-examine (every note, image or object you discover is stored in your character inventory so you can keep going back and checking them), the narrative and structure are both utterly oblique. One moment you’re analysing CCTV footage, the next you’re consulting a shadowy fortune teller; ghosts wander the halls, and at points, the fourth wall is smashed to spectacular effect. I filled pages of my notepad, and for the first time in many years, I entirely mapped out the environment by hand on the A3 graph paper I usually use to plan my own novels. It was such a pleasurable experience, to be allowed this responsibility by the developer. It took me back to the era of Scott Adams, Lucasfilm and Sierra On-Line, when players were treated as co-authors (and co-cartographers) of the narrative experience; when you’d always have an inventory of seemingly useless objects, though all would at some point become necessary.

    Lorelei and the Laser Eyes is a riveting puzzle game, which uses its eerie visuals and elusive story as an intrinsic element of the experience rather than a mere design affectation. It is a game that asks subtle questions about the nature of creativity and play, and later it takes a breathtakingly meta turn that will thrill those who remember Kojima’s tricks in the Metal Gear Solid series. It is also a meditation on the troubled relationship between art and commerce, and quite frankly, there could not be a more timely concern for a video game to explore.

    ‘Most Thorough Legal Analysis’ Yet Concludes Israel Committing Genocide in Gaza

    Portside
    portside.org
    2024-05-16 07:40:26
    ‘Most Thorough Legal Analysis’ Yet Concludes Israel Committing Genocide in Gaza Mark Brody Thu, 05/16/2024 - 02:40 ...
    Original Article

    A woman at a grave at the Rafah camp in the southern Gaza Strip on April 10, the first day of Eid al-Fitr.,Haitham Imad/European Pressphoto Agency

    The University Network for Human Rights on Wednesday released and sent to United Nations offices a 105-page report that it called "the most thorough legal analysis" yet to find "Israel is committing genocide" against Palestinians in the Gaza Strip.

    The network partnered with the International Human Rights Clinic at Boston University School of Law, the International Human Rights Clinic at Cornell Law School, the Center for Human Rights at the University of Pretoria, and the Lowenstein Human Rights Project at Yale Law School for the analysis, which draws from "a diverse range of credible sources" and the territory's history.

    "After reviewing the facts established by independent human rights monitors, journalists, and United Nations agencies, we conclude that Israel's actions in and regarding Gaza since October 7, 2023, violate the Genocide Convention," the report states. "Israel has committed genocidal acts of killing, causing serious harm to, and inflicting conditions of life calculated to bring about the physical destruction of Palestinians in Gaza, a protected group that forms a substantial part of the Palestinian people."

    As of May 1, Israel's assault had killed "more than 5% of Gaza's population, with over 2% of Gaza's children killed or injured," the analysis notes. In recent days, Israeli forces have ramped up their attack on Rafah—where over a million people from other parts of the besieged enclave sought refuge—and the total death toll has risen to 35,233, according to Gaza health officials, with another 79,141 Palestinians injured.

    "Israel's military operation has destroyed up to 70% of homes in Gaza, and has decimated civilian infrastructure, including hospitals, schools, universities, U.N. facilities, and cultural and religious heritage sites," the document says, noting the "staggering" number of forced displacements. "Civilians in Gaza face catastrophic levels of hunger and deprivation due to Israel's restriction on, and failure to ensure adequate access to, basic essentials of life, including food, water, medicine, and fuel."

    "Israel's genocidal acts in Gaza have been motivated by the requisite genocidal intent, as evidenced in this report by the statements of Israeli leaders, the character of the state and its military forces' conduct against and relating to Palestinians in Gaza, and the direct nexus between them," the publication continues, pointing to comments from "officials at all levels of Israeli government, up to and including" Prime Minister Benjamin Netanyahu.

    Israel has faced mounting allegations of genocide since launching its retaliation for the Hamas-led October 7 attack—including an ongoing South Africa-led case at the International Court of Justice (ICJ), which found in January that the country is "plausibly" committing genocide.

    Bolstering the ICJ's conclusion, the Wednesday report declares that "Israel's violations of the international legal prohibition of genocide amount to grave breaches of peremptory norms of international law that must cease immediately."

    "These violations give rise to obligations by all other states: to refrain from recognizing Israel’s breaches as legal or taking any actions that may amount to complicity in these breaches; and to take positive steps to suppress, prevent, and punish the commission by Israel of further genocidal acts against the Palestinian people in Gaza," the document adds.

    The United States has long provided Israel with billions of dollars in military aid and diplomatic support—which have soared since October 7, despite growing pressure on U.S. President Joe Biden to cut off such assistance. The Democrat has incrementally increased his criticism of the Israeli assault in recent weeks, angering far-right leaders in both countries.

    The new legal analysis—which was sent to the U.N.'s Office of the High Commissioner for Human Rights, Office on Genocide Prevention and the Responsibility to Protect, and the Independent International Commission of Inquiry on the Occupied Palestinian Territory, including East Jerusalem, and Israel—came on the same day that 20 human rights groups issued a joint statement.

    The rights organizations—including Amnesty International, Mercy Corps, and Oxfam—called on world leaders "to urgently act in bringing to an end, and pursue accountability for," Israel's grave breaches of international humanitarian law in Gaza.

    Both documents were released on Nakba Day, which commemorates the ethnic cleansing of hundreds of thousands of Palestinians during the creation of the state of Israel in 1948. Some experts and campaigners contend that the Nakba—Arabic for catastrophe—continues today.

    We’re in a Pivotal Moment in American History. We Cannot Retreat

    Portside
    portside.org
    2024-05-16 07:19:59
    We’re in a Pivotal Moment in American History. We Cannot Retreat Mark Brody Thu, 05/16/2024 - 02:19 ...
    Original Article

    In 1776, Americans, living in a British colony, put their lives on the line and fought for independence from the king of England. They wrote the strongest democratic constitution that had ever been written as they created a new nation. That was a pivotal moment in American history.

    In 1861, civil war broke out in the United States and more than 600,000 Americans died in the war between the states. Slavery was abolished. Over the ensuing decades, racist forces regained power and established an apartheid form of government throughout the old confederacy. That was a pivotal moment in American history.

    In 1929, Wall Street collapsed. The United States and much of the world experienced the Great Depression. Unemployment rose to 25% and millions of Americans descended into economic desperation. In 1932, Franklin Delano Roosevelt was elected president and the federal government’s role in addressing the needs of working people was transformed. That was a pivotal moment in American history.

    In 1941, Japan attacked Pearl Harbor and an unprepared United States was forced to mobilize and fight a world war on two fronts: Hitler in Europe and Japan in Asia. The future of democracy and the prevention of barbarism in the world was at stake. That was a pivotal moment in American history.

    Today, in 2024, our country once again faces a pivotal moment in American history. The crises facing us are enormous. The consequences if we fail are unthinkable.

    As the nation moves rapidly toward oligarchy, the billionaire class exerts enormous influence over the economic and political life of the nation. While the rich become much richer, 60% of Americans live paycheck to paycheck, and real, inflation-adjusted wages for the average US worker have actually declined over the last 50 years. Never before have the 1% done so well, or enjoyed so much power.

    Our political system is corrupt. Thanks to the disastrous Citizens United supreme court decision, billionaires and their Super Pacs are able to spend hundreds of millions to elect or defeat candidates they target. As a result, more than 90% of House elections and more than 80% of Senate elections are won by the candidate who spends the most money.

    Our life expectancy and birth rate are in decline. Despite spending far more per capita on a broken healthcare system, the average American now lives 77.5 years – 18 months less than in 2019 – and the lowest of any wealthy nation on earth. Further, our total births last year fell to 3.59 million, the lowest level ever recorded.

    The climate crisis threatens the very future of the planet. The last 10 years have been the 10 warmest years on record. 2023 was by far the hottest year in recorded history and 2024 is on track to be even hotter. Unless there is a huge reduction in carbon emissions we will continue to see more drought, more flooding, more forest fires, more extreme weather disturbances, more mass migrations and more deaths as a result of the climate crisis.

    Artificial intelligence and robotics are radically transforming our society, causing enormous anxiety among workers. Most of the jobs we have today will likely not be here in 15 years. Will the increased productivity that AI brings simply make corporations wealthier as they discard their employees, or will workers benefit? The wellbeing of tens of millions depends upon that answer.

    The basic human rights that women have struggled to win are under severe attack. Since the supreme court’s disastrous decision overturning Roe v Wade, 14 states have passed near-total abortion bans, some with no exceptions for victims of rape or incest. Will the war against women continue? Will women once again, be reduced to second-class citizenship?

    The US now spends almost 1tn a year on the military, more than the next 10 countries combined. This is more than all federal funding for food, housing and education. Tens of billions of those dollars are currently supporting the horrific war in Gaza waged by the rightwing extremist Israeli government of Netanyahu.

    So. That’s where we are, and it’s not a pretty picture. People feel hopeless. They are exhausted. They are worried about the kind of future that awaits their kids and grandkids.

    We are in the midst of another pivotal moment in American history. How do we respond?

    First, we cannot simply turn away from the painful and complex realities that we face and bury our heads in the sand. We cannot stop reading the news or turn off the TV. The world is what it is. It is a mess. And the situation is not going to improve unless we do the hard work required.

    Second, we must be actively involved in the 2024 national elections – the most consequential in our lifetimes.

    Yes. I know. Biden is not popular and many progressives, including me, strongly disagree with his policies regarding Israel and this disastrous war in Gaza.

    But, let’s be clear. Biden is not running against God. He is running against Donald Trump, the most dangerous president in American history whose second term, if he is re-elected, will be worse than his first. And, on his worst day, Biden is a thousand times better than Trump.

    Are you concerned about the extreme income and wealth inequality we are experiencing, and the decline of the middle class? Trump wants to give huge tax breaks to billionaires and, as president, appointed viciously anti-union officials to high office. Biden, on the other hand, is the first president to ever walk a picket line – in support of striking UAW workers. He has helped create millions of decent paying jobs rebuilding our crumbling infrastructure and investing in manufacturing. Biden has also forgiven the debts of millions of struggling young people.

    Are you concerned about the right of women to control their own bodies? Trump brags about how he appointed three supreme court justices who helped overturn Roe v Wade. Biden is solidly pro-choice.

    Are you concerned about the climate crisis? Donald Trump thinks climate change is a “hoax”. A Trump victory will tell the entire world to continue their support for fossil fuels, and the planet we leave our kids and future generations will be increasingly unhealthy. Biden, on the other hand, has helped invest more money into sustainable energy and energy efficiency than any president in history.

    And if you have problems with Biden’s position on Israel and the war in Gaza, Trump’s position is far worse. Biden has at least restricted some powerful bombs from going to the Israel and has been critical of Netanyahu. Trump and his Republican colleagues are “all in” for the massive destruction of the Palestinian people.

    Oh. And there’s one other thing. And that’s the small matter of retaining our democracy. Biden is a traditional American politician who believes in democracy, free elections and the right of dissent. That’s not what Trump believes. He and his supporters have spent the last four years undermining faith in the rule of law and our democratic form of government. He is weighing pardons for more than 800 of his supporters who attacked the Capitol in the January 6 insurrection. And his advisers are drawing up plans to invoke the Insurrection Act to allow him to deploy the military against civil demonstrations.

    Clearly, our job is not just to re-elect Biden. It’s much more than that. We must defend the many progressives that we have elected to the House, some of whom who face significant financial opposition from Aipac and other special interest Pacs. And we must elect more strong progressive candidates who are on the ballot to the House, and state and local governments.

    We must work in coalition with all those who understand that we must do everything possible to defeat Donald Trump and his extreme rightwing Republican party, not just because he is “worse”, but because nothing less than the future of our democracy is at stake in this election.

    Further, we must demand that Biden and the Democrats begin campaigning on a truly progressive agenda that addresses the needs of the working families of our country.

    Yes. Healthcare is a human right.

    Yes. The billionaire class must start paying their fair share of taxes.

    Yes. We must raise the minimum wage to a living wage and make it easier for workers to join unions.

    Yes. We must seriously address the housing crisis, which exists in almost every state in the country.

    Yes. We must strengthen public education in our country and make higher education available to all regardless of income.

    Bottom line: we must have the guts to take on and defeat a powerful and greedy ruling class and create a government which works for all, not just the few. The path forward is not easy. But now is not the time for despair or cynicism.

    During this pivotal moment, we must do what Americans have always done when change is needed: we must stand together, organize and fight for the country we know we can become.

    • Bernie Sanders is a US senator, and chairman of the health education labor and pensions committee. He represents the state of Vermont and is the longest-serving independent in the history of Congress

    My Sony HB-F1XV

    Hacker News
    thefoggiest.dev
    2024-05-16 07:03:07
    Comments...
    Original Article

    My Sony HB-F1XV

    May 16, 2024

    My newest retro computer, and the one I use most often, is my glorious 1989 Sony HB-F1XV MSX2+

    My Sony HB-F1XV

    My Sony HB-F1XV

    The Sony HB-F1XV is an MSX2+ computer, released purely for the Japanese market. In October 1989, it was the last MSX built and marketed by Sony. Originally, it had 64 kB RAM, 16 kB static RAM with MSX-JE (連文節変換) and 128 kB Video RAM, a Zilog Z80A CPU clocked at 3.5 MHz, a Yamaha V9958 video chip capable of displaying 19,268 colours simultaneously and both a 4 channel YM2149 (PSG) and a 9 channel YM2413 (OPLL) FM audio chip. The machine has RGB video and RCA audio and video output connectors. A hardware pause button, a speed-controller slider for slow-motion and a ren-sha-turbo speed adjustable auto-fire for both joysticks and the space bar are nice features for playing games. To the right of the space bar, there is a Kanji button that allows the user to select either Latin or Kanji characters.

    I own a Mitsubishi ML-FX1 MSX1 and a Philips VG8235 MSX2 and have owned a Philips NMS 8250 as well, but none were as great for gaming as my Sony HB-F1XV, which I bought in August 2020 via the trading forum on msx.org. The person who sold it to me had upgraded its RAM to 512 kB, had replaced the clock battery and its holder, and had put in new capacitors and a new PC disk drive. In the spring of 2021, I had a switch installed that clocks the CPU at either 7MHz or the original 3.5 MHz and had the worn-out keyboard membrane replaced.

    Design

    The HB-F1XV has a wedge-shaped design that was a popular choice for home computer manufacturers. Amigas, Atari STs, Acorns and many MSX computers all had the user bend their wrists a little extra when typing on the tilted internal keyboards. Ergonomics were perhaps considered less important than for users to be able to correctly identify the keys.

    Sony HB-F1XV back

    At its back, from left to right, are RGB out and RCA audio and video out ports, a channel selector switch and the RF output port it is for, a Centronics compatible printer port, a standard MSX tape port, the second cartridge slot, an integrated power cable, a power switch and at the lower rightmost end, a ground terminal for good measure.

    Sony HB-F1XV right

    On the right side of the HB-F1XV there’s a 720 kB DS/DD floppy drive and two standard Atari joystick ports. Behind the Sony disk drive front design is the PC disk drive that replaced the original floppy drive.

    Sony HB-F1XV left

    On the left side, there is the CPU speed select switch that I had built in. It has a little LED that will light up yellow when the CPU is racing along at 7Mhz. Sometimes, especially when reading from or writing to floppies, the CPU will be put back to 3.5Mhz to prevent disk errors, in which case the LED is turned off for a moment.

    The HB-F1XV, being exclusively for the Japanese market, requires a 100V power socket. My house only has 240V sockets, so I needed to buy a converter. I found one that Japanese citizens use when they go abroad and had it imported.

    Standard

    MSX2+ was the third generation of the MSX standard. The standard was meant as a way to have software and hardware manufacturers have an increased market potential without having to port every product to a dozen incompatible platforms, as was the case before. The successive generations, MSX, MSX2, MSX2+ and MSX TurboR, each improved on the last one with better memory architecture, graphics, or CPU, but remained backwards compatible in both hardware and software. MSX computers were mostly popular in Japan, Korea, Spain, the Netherlands and South America.

    Sony HB-F1XV box

    The MSX platform was designed as a modular standard. Internally, manufacturers could, and would, plug RAM and ROM modules wherever they wanted, logically speaking, which meant software was often at a loss finding it. The upside, however, is that, while the MSX2+ with all its colours and even the MSX TurboR with its 16-bit RISC CPU were not what MSX standard owner ASCII Corporation had envisioned as MSX3, it is the platform’s modularity which allows us now to create that MSX3 from any MSX computer.

    Normally, I have both cartridge slots occupied. The first slot holds a GR8NET cartridge that has another 1MB of RAM, a Micro-SD card reader, an Ethernet port and a 3.5mm audio jack to make life easier. The second cartridge slot has a Modulon slot expander with a WozBlaster Reloaded OPL4 audio cartridge with 2 MB of sample RAM and 24 channels of 16-bit 44.1 kHz audio and a PowerGraph Lite v9990 video cartridge for screen resolutions up to 1024×424 pixels and a maximum of 32,768 colours simultaneously. Both are modern implementations of almost time-correct hardware and, except for the CPU, what many think of as a baseline for MSX3.

    Myths & Dragons (KAI Magazione, 2018)

    “Myths and Dragons” by KAI Magazine (2018) uses both the OPL4 and the V9990 when selected in the game’s menu

    I’ve used RGB to HDMI converters with flat screens in the past, but these analogue games need pixel perfect timing, so I bought a Philips VS0080 monitor, the same one that Philips sold in beige to C64 and Amiga owners as “dedicated” apparel for their platform. During the eighties, games for MSX were normally developed on more powerful machines like the Atari ST, but they were tested on actual MSX machines by the developers themselves, who, during testing, became so good at their own games that they felt they had to make them more difficult. This is one of the reasons why games from that time are so much more challenging than modern games.

    Software

    As visible in the picture above, my Sony HB-F1XV has a big flashy sticker above the first cartridge slot. Here it is in close-up:

    Sony HB-F1XV sticker

    The big red text on the left means “creative tools” and underneath it says “3 disks”. The diagonal texts mean, from left to right:

    • Music Software – F1 Synthesizer
    • Graphics software – (?) animation graphics editor ver2.0
    • (?) Twenty lines Word Processor – (?) version

    These texts refer to three disks that originally came with the machine. The first two disks held software to create music and animated graphics. The word processor made use of the machine’s capability to write Kanji characters. This machine was meant to create, not just to consume.

    Sony HB-F1XV Graphics suite

    Sadly, I don’t read Japanese, and PCs are much more convenient for creating content, so to me this is mostly a games console, except I’m typing this text on my Sony.

    I could go on about this machine forever, but I need to stop here. One final thought, though. Look at the picture with the full setup. With all those expansions and cables extruding from them, it looks like the Sony is on life support, and perhaps you’d think that, without those expansions, how lively would this geriatric machine really be? You’d be wrong. Just the other day, I was playing Konami’s Road Fighter from the original cartridge from 1985. For a game to be exhilarating, addictive and fun, it doesn’t need all those colours and all those audio channels. It just needs to be a good game. And thanks to its backward compatibility, the Sony’s potential library is huge.

    She Campaigned for a Texas School Board Seat as a GOP Hard-Liner. Now She’s Rejecting Her Party’s Extremism.

    Portside
    portside.org
    2024-05-16 06:48:34
    She Campaigned for a Texas School Board Seat as a GOP Hard-Liner. Now She’s Rejecting Her Party’s Extremism. Mark Brody Thu, 05/16/2024 - 01:48 ...
    Original Article

    Weeks after winning a school board seat in her deeply red Texas county, Courtney Gore immersed herself in the district’s curriculum, spending her nights and weekends poring over hundreds of pages of lesson plans that she had fanned out on the coffee table in her living room and even across her bed. She was searching for evidence of the sweeping national movement she had warned on the campaign trail was indoctrinating schoolchildren.

    Gore, the co-host of a far-right online talk show, had promised that she would be a strong Republican voice on the nonpartisan school board. Citing “small town, conservative Christian values,” she pledged to inspect educational materials for inappropriate messages about sexuality and race and remove them from every campus in the 7,700-student Granbury Independent School District, an hour southwest of Fort Worth. “Over the years our American Education System has been hijacked by Leftists looking to indoctrinate our kids into the ‘progressive’ way of thinking, and yes, they’ve tried to do this in Granbury ISD,” she wrote in a September 2021 Facebook post, two months before the election. “I cannot sit by and watch their twisted worldview infiltrate Granbury ISD.”

    But after taking office and examining hundreds of pages of curriculum, Gore was shocked by what she found — and didn’t find.

    The pervasive indoctrination she had railed against simply did not exist. Children were not being sexualized, and she could find no examples of critical race theory, an advanced academic concept that examines systemic racism. She’d examined curriculum related to social-emotional learning, which has come under attack by Christian conservatives who say it encourages children to question gender roles and prioritizes feelings over biblical teachings. Instead, Gore found the materials taught children “how to be a good friend, a good human.”

    Gore rushed to share the news with the hard-liners who had encouraged her to run for the seat. She expected them to be as relieved and excited as she had been. But she said they were indifferent, even dismissive, because “it didn’t fit the narrative that they were trying to push.”

    So, in the spring of 2022, Gore went public with a series of Facebook posts. She told residents that her backers were using divisive rhetoric to manipulate the community’s emotions. They were interested not in improving public education but rather in sowing distrust, Gore said.

    “I’m over the political agenda, hypocrisy bs,” Gore wrote. “I took part in it myself. I refuse to participate in it any longer. It’s not serving our party. We have to do better.”

    After Gore reviewed hundreds of pages of the school curriculum, she was shocked that the pervasive indoctrination she had railed against as a candidate did not exist. She has since helped form a group that supports Republican candidates who have been alienated by the local GOP’s far-right faction. Credit:Shelby Tauber for ProPublica and The Texas Tribune

    Gore’s open defiance of far-right GOP orthodoxy represents an unusual sign of independence in a state and in a party that experts say increasingly punish those deemed disloyal. It particularly stands out at a time when Republican leaders are publicly attacking elected officials who do not support direct funding to private schools.

    “It’s a rare event to see this kind of political leap, especially in a world that’s so polarized,” said University of Houston political scientist Brandon Rottinghaus. “You rarely see these kinds of changes because the people who are vetted to run tend to be true believers. They tend not to be people who are necessarily thinking about the holistic problem.”

    “With the presence of Donald Trump, fealty to cause has amplified, so this kind of action is much more meaningful and much more visible than it was a decade ago,” Rottinghaus said about Gore.

    In March, Texas Gov. Greg Abbott, a Republican, was victorious in unseating five lawmakers in his own party and forcing another three into runoff elections after they voted against voucher legislation that would allow the use of public dollars for students to attend private and religious schools. His efforts sent a message that those who did not unflinchingly support his priorities would face grave political repercussions.

    Gore was part of a similar movement of hard-liners who pushed out the Republican Hood County elections administrator in 2021 after determining that she was not conservative enough for the nonpartisan position. Now Gore and other disillusioned local Republicans have formed a group pushing against an “ultra-right” faction of the party that it says has become obsessed with “administering purity tests” and stoking divisive politics.

    The former teacher and mother of four was influenced by such politics when she decided to run for office. She was motivated to seek a school board seat after a steady stream of reports from the right-wing media she consumed and her social media feeds pointed to what she saw as inappropriate teachings in public schools. She, too, had been outraged by school mask mandates and vaccine requirements during the throes of the COVID-19 pandemic.

    But Gore said she feels that she was unwittingly part of a statewide effort to weaken local support of public schools and lay the groundwork for a voucher system.

    And she said that unless she and others sound the alarm, residents won’t realize what is happening until it is too late.

    “I feel like if I don’t speak out, then I’m complicit,” Gore said. “I refuse to be complicit in something that’s going to hurt children.”

    Because of that outspokenness, Gore is facing backlash from the same people who supported her race. She has been threatened at raucous school board meetings and shunned by people she once considered friends.

    School marshals escort her and her fellow board members to their cars to ensure no one accosts them.

    Gore has faced backlash and threats since speaking out against the people who supported her school board race. School marshals now escort her and other board members to their cars after meetings. Credit:Shelby Tauber for ProPublica and The Texas Tribune

    When things get particularly heated, a fellow trustee follows her in his car to make sure she gets home safely.

    “None of It Was Adding Up”

    Before Gore decided to seek office for the first time, prominent GOP operatives had been pushing for like-minded allies to take over school boards, framing the effort as necessary to maintain conservative Christian values.

    In May 2021, former Trump adviser Steve Bannon told followers on his podcast that school boards were the road back to power for conservatives following the 2020 presidential election. Two months later, North Texas-based influential pastor Rafael Cruz, the father of U.S. Sen. Ted Cruz, amplified that message on social media, saying that getting candidates on school boards was critical.

    “We need to make sure that strong, principled Americans, those who uphold our Judeo-Christian principles that have made America the greatest country in the world, are elected to school boards,” Rafael Cruz said in a July 2021 video posted to his Facebook page. “Because I’ll tell you the left is controlling the school boards in America.”

    Those messages reached Granbury, where former Republican state Rep. Mike Lang and political consultant Nate Criswell asked Gore to run for the school board. Gore recalls hearing Cruz give a fiery speech while she was campaigning. In the speech, which reinforced her decision to run, she said Cruz boasted about flipping the school board in Southlake, Texas, by getting the churches involved in helping to install Christian candidates.

    “When you put in the minds of parents that there is an agenda to indoctrinate their children … and the only answer is to get conservative Christian people elected to the school board,” Gore said, “it’s a very powerful message”

    Gore, now 43, first became involved in local politics in 2016 when she campaigned door-to-door for Lang, a former constable who successfully ran for the Texas Legislature. She then served on a leadership committee for the Hood County GOP.

    After Lang decided not to run for reelection in 2020, he asked Gore to join the “Blue Shark” show, a web-based program he founded and co-hosted with Criswell that produced videos taking aim at local politicians and officials considered insufficiently conservative. Criswell later ran campaigns for Gore and Melanie Graft, another school board candidate who previously tried to remove LGBTQ-themed books from the children’s section of the county library.

    Soon after the women won their elections, the Granbury school district descended into a high-profile fight over school library books.

    Administrators pulled 130 library books from the shelves after Matt Krause, a Republican representative from Fort Worth, published a list of 850 titles that he said touched on themes of sexual orientation and race. At the time, ProPublica, The Texas Tribune and NBC News obtained audio of the district’s superintendent, Jeremy Glenn, making clear to librarians that he had concerns about books with LGBTQ themes, including those that did not contain descriptions of sex. After the reporting, the Department of Education opened a civil rights investigation, which is ongoing, into whether the district violated federal laws that prohibit discrimination based on sexual orientation and gender.

    A volunteer review committee of parents and district employees eventually recommended returning nearly all of the books to the shelves.

    Hard-liners wanted additional titles removed, claiming that the district was allowing “pornography,” without offering evidence to support the assertion. But Gore backed the committee’s findings, saying she was satisfied with the handful of books the district had removed for explicit content. Glenn, too, drew the ire of his onetime allies after he also supported the committee’s recommendation. Lang and Criswell have since called for his ouster. Glenn declined an interview request through a district spokesperson.

    The book debate, along with a series of other fissures, contributed to Gore’s growing belief that her former colleagues were more interested in misleading residents than in improving educational outcomes.

    In early 2022, leaders of the rapidly growing district announced plans to ask voters for $394 million in bonds to build a new high school and renovate existing campuses. School board members established a community advisory committee that would counsel the district.

    Gore chose Criswell as her representative on the committee. She thought that once Criswell saw the district’s needs firsthand, he would support the bonds. But the opposite happened. Criswell urged voters to reject the measure, claiming some parts, such as providing full-day pre-K programs for all students, were “communist in nature.”

    Gore said Criswell directed her and Graft, who did not respond to requests for comment, to post messages on social media against the bonds. When Gore pushed back, she said Criswell accused her of betraying the party. (The bonds ultimately lost by a wide margin.)

    According to Gore, Criswell also pressured her to stop speaking with all of her fellow school board members, except for Graft. “They’re just lying to you. They’re not your friends,” she recalled him saying.

    “I was like, how am I supposed to do my job as a board member if I’m not talking to anybody?” Gore said. “None of it was adding up.”

    Criswell, who has previously said that he supports public schools, declined to answer detailed questions. Lang did not respond to requests to comment. In April 2022, Gore rescinded her nomination of Criswell to the bond advisory board. She felt that he and Lang were misleading voters about the bond and its cost to taxpayers.

    “Mike Lang would call them snowballs,” she said. “You just get as many little snowballs as you can so you’re attacking from multiple fronts. And then you see which ones start to stick and gather speed and get bigger and bigger.”

    In June 2022, Lang and Criswell directed one of their snowballs in Gore’s direction, taking a veiled shot at the former co-host of their show. In a video, Criswell praised Graft for continuing the fight to remove books from the school district’s libraries, saying she was “the only one that acts as the buffer right now on that board. Which is sad, because, you know, we’ve had other people elected in recent elections that just haven’t lived up to the expectations.”

    Three days later, Gore fired back.

    “I refuse to be someone’s puppet,” she wrote in a June 8 Facebook post. “I refuse to be told what to do, what to say or how to vote. I refuse to participate in any agenda that will dismantle or abolish public education.”

    Once Gore was elected to the school board, she began to believe that her former allies were more interested in misleading residents than in improving educational outcomes. Credit:Shelby Tauber for ProPublica and The Texas Tribune

    “Extremism IS the Problem”

    A week after that post, Gore watched the livestream of a Granbury school board meeting on her laptop from a hotel room along Mexico’s Caribbean coast while on an anniversary trip with her husband.

    Emotions ran high as about a dozen residents complained that board members had not removed enough books from the library. Some argued that the school board was stifling dissent from Graft by requiring the consent of two board members to place an item on the agenda.

    During the meeting, Cliff Criswell, the grandfather of Nate Criswell, took the microphone, carrying what police would later describe as a black handgun in a leather holster. He accused board members of allowing pornography in school libraries and of trying to “rip apart” Graft, whom he had previously described as “the only conservative on the board.”

    “We have profile sheets” on all the trustees except for Graft, Cliff Criswell shouted. “We know what you do. We know where you live.”

    Gore was shocked. Panicked, she started calling family members. “My grandmother was home with our children,” she recalled in an interview. “My brother came over and slept on my front porch to make sure nobody showed up at our house in the middle of the night. I mean, my kids were terrified after that.”

    Later that night, Gore addressed the incident on Facebook.

    “Tonight, threats were made against me, every board member (except one) and our superintendent. We were individually called out by name, told we had profile sheets made on each of us and that we would be dealt with accordingly. THIS IS NOT OK. I take threats against myself and my family seriously, especially with all of the violence in today’s world. Will we be dealing with school board shootings next?!? WE MUST DO BETTER!”

    In response to a commenter’s message of support, Gore wrote, “extremism IS the problem.”

    According to a Granbury police report, an off-duty officer spotted a black pistol in a holster in Cliff Criswell’s waistband and alerted school and city police. Possession of an unauthorized firearm at a school board meeting is a third-degree felony under state law, but because officers didn’t conclusively identify the weapon that night, and because Cliff Criswell declined to cooperate, prosecutors were unable to file charges, said Granbury police Deputy Chief Cliff Andrews. Cliff Criswell could not be reached for comment.

    “Had we identified the gun at the very moment, yes, absolutely, we could have filed charges on it,” Andrews said. “We made a simple mistake.”

    The incident forced the district to adopt tighter security measures, including clearly posting signs prohibiting firearms and bringing in additional officers during board meetings anytime administrators expect that certain topics could lead to heated exchanges.

    “That was the moment I saw how crazy it was, how unhinged it had become and how far some people were willing to go to prove their points,” Gore said.

    Gore installed “private property” signs on the gates surrounding her home after a school board meeting where Cliff Criswell, an angry resident, made threatening remarks against her and her fellow school board members. “We know what you do. We know where you live,” he had said. Credit:Shelby Tauber for ProPublica and The Texas Tribune

    Yet rhetoric over the school district only ratcheted up in the ensuing months.

    That fall, Hood County’s far-right leaders backed the school board candidacy of Karen Lowery, who in May 2022 was one of two women who filed a criminal complaint against district librarians claiming they were providing pornography to children. A Hood County constable has declined to answer questions about the status of the complaint.

    Lowery, who had served on the committee that reviewed library books but opposed returning them to the shelves, also received a key endorsement from Rafael Cruz. She went on to win her election in November 2022.

    Her victory helped resurface the district’s book battles as she pressed to remove more titles. Then, in August 2023, Lowery snuck into a high school library during a charity event and began inspecting books using the light of her cellphone, according to a district report.

    School board members met to discuss censuring Lowery at an Aug. 23 public meeting for violating a policy that requires them to get permission from principals when entering a campus and for not being truthful when confronted by an administrator. Lowery claimed she had disclosed her visit to the library beforehand as required. She did not respond to calls or emails seeking comment. A district spokesperson said he was unable to pass along an interview request because Lowery has requested to only be contacted through her board email.

    The board voted to censure Lowery, who opposed the symbolic measure along with Graft.

    “It is clear that the actions Mrs. Lowery took, as evidenced by the community and the outcry that we have heard tonight, has broken some of that trust with our staff, parents and community members,” said Gore, who motioned to censure Lowery. “The only people that pay the price for this, no matter what happens tonight, are the kids of this district.”

    Old Foe, New Friend

    By November 2023, the battle lines over school vouchers were hardening in Granbury, and at the state Capitol in Austin.

    Abbott had begun waging war against Republicans who had not supported voucher efforts and contributed to their failure during the last legislative session. One lawmaker who escaped Abbott’s wrath was Shelby Slawson, a Republican who represents Hood County. Unlike some of those now being targeted, Slawson had bucked a request spearheaded by Gore and supported by the school board majority that urged lawmakers to vote against a measure that would send public dollars to private schools. Slawson did not respond to questions regarding her decision to vote in favor of vouchers despite the local school district’s opposition to the legislation.

    Meanwhile, Granbury was facing a tough election. The school district was asking voters to approve a $151 million bond measure to build a new elementary school in the rapidly growing and overcrowded district, as well as provide security updates and renovations to aging campuses. The balance of the school board was also at stake in the same election.

    Bond opponents formed the Granbury Families political action committee. In advertising materials, the group cited library books as one of the principal reasons residents had lost trust in the board. “Our community has lost faith in the board’s ability to conduct business,” the group claimed. “Not another penny until GISD gets new leadership.”

    Nate Criswell, Gore’s former co-host and campaign manager, loaned the PAC $1,750, according to campaign finance reports filed with the district. The loan constituted about 40% of the PAC’s funding ahead of the November election.

    Although a majority of the state’s school districts with bond measures scored victories, Granbury’s tax measure failed once again. (Voters rejected another bond measure this month.) Hard-line conservatives celebrated the loss, pointing to anger over the library books issue.

    But even as they celebrated, the November election delivered a setback to those who wanted to take over the school board. The two candidates supported by hard-line conservatives lost by wide margins, denying the county’s far-right faction the majority on the board. Among the winners in that election was Nancy Alana, the school board member whom Gore ousted two years earlier. This time around Gore endorsed Alana, and the two former opponents have since become friends and allies.

    “She let everybody know that she had been misled and that she has seen for herself the good things that are happening in our school district,” Alana said. “That the school board can be trusted. That the administrators can be trusted. And she has spoken out on that. And that has made a big difference. And she is very well thought of in our community because of her willingness to step up and say, ‘I was wrong.’”

    Jeremy Schwartz is an investigative reporter for the ProPublica-Texas Tribune Investigative Initiative. He’s been a watchdog reporter in Texas for nearly a decade for the Austin American-Statesman and USA Today Network.

    ProPublica is a nonprofit newsroom that investigates abuses of power. Sign up to receive our biggest stories as soon as they’re published.

    This article is co-published with The Texas Tribune, a nonprofit, nonpartisan local newsroom that informs and engages with Texans. Sign up for The Brief Weekly to get up to speed on their essential coverage of Texas issues.

    Detailing Israeli Attacks on Known Aid Worker Locations

    Portside
    portside.org
    2024-05-16 06:29:43
    Detailing Israeli Attacks on Known Aid Worker Locations Mark Brody Thu, 05/16/2024 - 01:29 ...
    Original Article

    Israeli forces have carried out at least eight strikes on aid workers’ convoys and premises in Gaza since October 2023, even though aid groups had provided their coordinates to the Israeli authorities to ensure their protection, Human Rights Watch said today. Israeli authorities did not issue advance warnings to any of the aid organizations before the strikes, which killed or injured at least 31 aid workers and those with them. More than 250 aid workers have been killed in Gaza since the October 7 assault in Israel, according to the UN.

    One attack on January 18, 2024, injured three people who were staying in a joint guest house belonging to two aid organizations and was most likely carried out with a US-made munition, according to one of the organizations and to a report by UN investigators who visited the site after the attack, which Human Rights Watch reviewed. One of the aid organizations, Medical Aid for Palestinians (MAP), said UN inspectors concluded that the bomb was delivered by an F-16 aircraft. F-16 aircraft use British made components according to campaigners.

    The eight incidents reveal fundamental flaws with the so-called deconfliction system, meant to protect aid workers and allow them to safely deliver life-saving humanitarian assistance in Gaza.

    “Israel’s killing of seven World Central Kitchen aid workers was shocking and should never have happened under international law,” said Belkis Wille, associate crisis, conflict, and arms director at Human Rights Watch. “Israel’s allies need to recognize that these attacks that have killed aid workers have happened over and over again, and they need to stop.”

    Israel’s attack on April 1 on the World Central Kitchen convoy, which killed seven workers, far from being an isolated “mistake,” is just one of at least eight incidents that Human Rights Watch identified in which aid organizations and UN agencies had communicated with Israeli authorities the GPS coordinates of an aid convoy or premises and yet Israeli forces attacked the convoy or shelter without any warning.

    In these eight incidents, Israeli forces killed at least 15 people, including 2 children, and injured at least 16 others. Five of these attacks were the subject of a recent New York Times investigation that included visual evidence and internal communications between aid organizations and the Israeli military.

    The other seven attacks are:

    • Attack on a Médecins Sans Frontières (MSF or Doctors without Borders) convoy, November 18, 2023
    • Attack on a guest house of the United Nations Relief and Works Agency for Palestine Refugees in the Near East (UNRWA), December 9, 2023
    • Attack on an MSF shelter, January 8, 2024
    • Attack on an International Rescue Committee (IRC) and Medical Aid for Palestinians (MAP) guest house, January 18, 2024
    • Attack on an UNRWA convoy, February 5, 2024
    • Attack on an MSF guest house, February 20, 2024
    • Attack on a home sheltering an American Near East Refugee Aid Organization (Anera) employee, March 8, 2024

    As of April 30, the UN reported that 254 aid workers had been killed in Gaza since October 7, 2023, with UNRWA personnel accounting for 188 of these fatalities. On May 13, a UN vehicle was hit on the way to a hospital in Gaza, killing at least one UN staff member and injuring at least one more. According to UNRWA, 169 of its facilities have been affected by the hostilities in 368 incidents and at least 429 displaced people have been killed in UNRWA shelters. Israeli forces have, according to the UN, also shot at and shelled people congregating to collect aid, killing and injuring hundreds. These attacks are having a chilling effect on efforts to provide lifesaving aid in Gaza.

    Aid workers have also been unable to leave Gaza, since Israeli forces seized control of and closed the Rafah Crossing on May 7.

    During a recent trip to Cairo and northern Sinai, near the border between Egypt and Gaza, Human Rights Watch met with staff from 11 humanitarian organizations and UN aid agencies operating in Gaza who said that Israeli attacks on aid workers had forced them to take various measures that for some included suspending activities for a period of time, reducing their staff inside Gaza, or severely restricting their aid activities in other ways.

    “I can’t risk sending more staff into Gaza because I cannot rely on deconfliction as a way of keeping them safe,” a senior employee from one of the organizations whose guest house was attacked told Human Rights Watch. He said this was a key factor in limiting the organization’s ability to provide medical services. “You can build docks and send shipments, but without a safe operating environment, you will have a pile up of shipments that people aren’t able to deploy safely to help people.”

    This pattern of attacks despite proper notification of Israeli authorities raises serious questions about Israel’s commitment and capacity to comply with international humanitarian law, which some countries, including the UK, rely on to continue to license arms exports that end up in Israel.

    Human Rights Watch has found that Israeli authorities are using starvation as a method of warfare in Gaza. Pursuant to a policy set out by Israeli officials and carried out by Israeli forces, the Israeli authorities are deliberately blocking the delivery of water, food, and fuel, willfully impeding humanitarian assistance, apparently razing agricultural areas, and depriving the civilian population of objects indispensable to its survival. Children in Gaza have been dying from starvation-related complications.

    Israel has not responded to a Human Rights Watch letter sent on May 1, requesting specific information about the attacks on aid workers documented in this report.

    The laws of war prohibit attacks that target civilians and civilian objects, that do not discriminate between civilians and combatants, or that are expected to cause harm to civilians or civilian objects that is disproportionate to any anticipated military advantage. Indiscriminate attacks include attacks that are not directed at a specific military target or use a method or means of combat whose effects cannot be limited as required.

    Warring parties must take all feasible precautions to minimize harm to civilians, including by providing effective advance warnings of attacks unless circumstances do not permit, and by sparing civilians under their control from the effects of attacks. Serious violations of the laws of war committed by individuals with criminal intent – that is, deliberately or recklessly – are war crimes.

    Israel should make public the findings of investigations into attacks that have killed and injured aid workers, and into all other attacks that caused civilian casualties. The Israeli military’s long track record of failing to credibly investigate alleged war crimes underscores the importance of the International Criminal Court’s (ICC) inquiry into serious crimes committed by all parties to the conflict.

    Israeli and Palestinian officials should cooperate with the ICC in their work, Human Rights Watch said. Israel should also provide the Independent International Commission of Inquiry on the Occupied Palestinian Territory, including East Jerusalem, and Israel access to Gaza to conduct its investigations.

    Given the pattern of attacks on aid groups that have provided Israeli authorities with proper information about their locations, a group of recognized international experts should conduct an independent review of the humanitarian deconfliction process. Israel should give these experts full access to its processes, including the coordination and communications that occur before, during, and after such attacks as well as information regarding any alleged military target in the vicinity and any precautionary measures taken to mitigate harm.

    Israel’s allies, including the United States and United Kingdom – both states sending the weapons parts apparently used in at least one of the documented attacks – should suspend military assistance and arms sales to Israel so long as its forces commit systematic and widespread laws-of-war violations against Palestinian civilians with impunity. Governments that continue to provide arms to the Israeli government risk complicity in war crimes.

    They should also use their leverage, including through targeted sanctions, to press Israeli authorities to cease committing grave abuses and enable the provision of humanitarian aid and basic services in Gaza, in accordance with Israel’s obligations under international law and recent International Court of Justice (ICJ) orders to Israel in the case brought by South Africa concerning alleged violations of the Genocide Convention.

    “On one hand, Israel is blocking access to critical lifesaving humanitarian provisions and on the other, attacking convoys that are delivering some of the small amount that they are allowing in,” Wille said. “Israeli forces should immediately end their attacks on aid organizations, and there should be accountability for these crimes.”

    Attack on the World Central Kitchen Workers

    On April 1, just before 11 p.m., Israeli forces carried out a drone strike with three missiles targeting a convoy of three World Central Kitchen (WCK) vehicles, two marked with the organization’s logo on the roof, in central Gaza, all carrying civilians, that were escorting eight aid trucks. The attack killed seven aid workers. The convoy had just left a food warehouse in Deir al-Balah and was traveling a route that the organization said they had agreed upon with the Israeli military. The attack was reportedly carried out by an Israeli-made Hermes 450 drone.

    After the attack, WCK paused its operations in Gaza for several weeks, as did American Near East Refugee Aid  (Anera). At the time, the two groups had together been providing an average of 300,000 meals across Gaza daily. Photographs of the damaged vehicles were initially verified by the independent investigative collective Bellingcat and later independently verified by Human Rights Watch researchers.

    A preliminary Israeli investigation into the attack found that Israeli forces’ conduct was “contrary to the Standard Operating Procedures” and had occurred because of “a grave mistake,” including a lack of coordination between different levels of the army and the mistaken identity of a man in one of the vehicles, according to the Israeli armed forces. The preliminary investigation also found that the two additional drone missiles were fired against army protocol.

    In its response, WCK reiterated its call for an independent commission to investigate the incident because, it said, the “[Israeli Defense Forces] cannot credibly investigate its own failure in Gaza.” WCK resumed its operations in late April because, it said, “The humanitarian situation in Gaza remains dire,” but said it had still received “no concrete assurances” that the Israeli military’s operational procedures had changed.

    This incident elicited widespread condemnation, including from leaders of countries whose citizens were killed in the attack, including United States President Joe Biden, United Kingdom Prime Minister Rishi SunakAustralian Prime Minister Anthony Albanese, and Canadian Prime Minister Justin Trudeau.

    Attack on a Médecins Sans Frontières (MSF) Convoy, November 18

    On November 18, 2023, armed forces attacked a convoy of five marked MSF vehicles, killing two people, witnesses said. The group had been trying to evacuate 137 civilians from its guesthouse near al-Shifa Hospital in Rimal, northern Gaza, where they had been trapped for a week, to southern Gaza. MSF said that it had coordinated the convoy’s movement with the Israeli armed forces and followed the route prescribed by the army. Once the convoy reached a crowded checkpoint near Wadi Gaza, Israeli soldiers did not allow the vehicles to clear the checkpoint for hours.

    When gunfire rang out near the checkpoint, MSF staff, who were still waiting to go through the checkpoint, decided to return to the guest house, 7.5 kilometers to the north. They said they maintained contact with the Israeli Coordination and Liaison Administration (CLA), the military unit responsible for the coordination of access to and from Gaza in connection with the facilitation of civilian and humanitarian needs, throughout their travel back and informed them that the convoy had to return to their guest house.

    As they were approaching their office, between 3:30 and 4 p.m., MSF said that the Israeli army attacked the convoy, hitting two of the vehicles. The organization quoted one staff member as saying: “I was terrified when I saw that the snipers and the tanks were pointing their weapons at us, especially at the fourth and the fifth van [in the convoy].” MSF said that the staff there during the incident saw no military targets in the area. The organization has requested an explanation from Israeli authorities, but has received no response, a representative told Human Rights Watch.

    “This incident shows just how ineffective the coordination mechanisms put in place by Israeli authorities have been,” said the representative of MSF. In this instance, “The latter appeared to have little or no influence on the operational troops on the ground, including to let the vehicles pass through the checkpoint.”

    This failed coordination with the CLA has been cited in previous UN reporting.

    Attack on a Guest House of the United Nations Relief and Works Agency for Palestine Refugees in the Near East (UNRWA), December 9

    On December 9, the Israeli navy fired 20mm cannon rounds at an UNRWA guest house consisting of two buildings in Rafah, Gaza’s southernmost governorate, the agency told Human Rights Watch. The rounds damaged the west side of both buildings. The attack occurred late in the evening, while 10 staff were asleep inside. The agency said it had shared the coordinates of the guest house with Israeli authorities on a regular basis prior to the attack, including on the date of the attack, and was not aware of any military targets in the area at the time. UNRWA told Human Rights Watch that it had received no warning of the attack. Following the attack, the deputy commander of the Israeli Southern Command told UNRWA that the attack had been carried out in error, UNRWA told Human Rights Watch.

    Attack on an MSF Shelter, January 8

    On January 8, an Israeli projectile pierced the side of a building in which over 100 MSF staff and their families were sheltering in Khan Yunis, MSF said. The strike killed the 5-year-old daughter of an MSF worker and injured four people. At the time, the staff saw no military targets in the area and received no warning of the attack, which took place in an area under no evacuation order, the organization told Human Rights Watch. The organization said it had shared the coordinates of the building with Israeli authorities on a regular basis, saying it was being used as an MSF shelter.

    MSF published a video in which Léo Cans, the MSF head of mission for Palestine, described the attack and showed two parallel holes in the wall that munitions had passed through, he said. The video also included two photographs of remnants lying on the grass, allegedly outside the building. Human Rights Watch could not confirm the location of these remnants but was not able to find them online prior to January 8. The New York Times analyzed the photographs and reported that they showed the remnants of an Israeli 120mm tank shell with Hebrew markings outside the shelter. Human Rights Watch independently verified the type of remnants. 

    The Israeli military denied to the New York Times that it had struck the building. However, MSF said that Israeli authorities later told the organization that the damage to the guest house had been collateral in an attack on a “terror” target.

    Attack on an International Rescue Committee (IRC) and Medical Aid for Palestinians (MAP) Guest House, January 18

    On January 18, an Israeli air attack hit the perimeter wall around a guest house being used by both the IRC and MAP north of Khan Younis, where 12 people, including 4 doctors, were staying at the time, according to the 2 organizations. No one was killed in the strike but three people suffered light injuries, MAP told Human Rights Watch.

    Satellite analysis shows the attack left a roughly 15-meter-wide crater in the sandy ground, destroyed the wall marking the perimeter of the property, and significantly damaged the house. MAP confirmed to Human Rights Watch that the organization had shared the coordinates of the guest house with the Israeli authorities and with the UN twice in late 2023 to ensure it did not come under attack. The building stands alone, with no other buildings or structures around it, and MAP said they knew of no military targets in the area at the time of the attack and received no warnings.

    Human Rights Watch reviewed a report of an on-site independent assessment by a multi-agency UN team after the attack, which concluded that the damage was the result of an airstrike, most likely involving a US-made guided GBU-32 air-dropped bomb. MAP said inspectors concluded that the bomb was delivered by an F-16 aircraft. The organizations said that, since the attack, Israel has provided six different and often contradictory explanations as to whether and why the attack took place, but they said the explanations had not provided clarity or accountability.

    Attack on an UNRWA Convoy, February 5

    On February 5, Israeli naval gunfire hit an UNRWA aid truck, the agency said. The attack occurred while a convoy of 10 trucks flanked by marked UN vehicles were parked on a road in western Nuseirat, waiting at a previously agreed holding point for permission from the Israeli military to proceed to an Israeli checkpoint. The shelling damaged the last truck in the convoy. No one was injured. UNRWA said it had coordinated with Israeli authorities the planned movement of trucks prior to the attack, including reporting to Israeli authorities when the convoy had reached the holding point and when aid workers in the convoy began to hear naval gunfire in proximity to the stationary convoy.

    On February 5, 2024, Israeli naval gunfire hit an UNRWA aid truck carrying food.

    On February 5, 2024, Israeli naval gunfire hit an UNRWA aid truck carrying food. © 2024 UNRWA

    Because of this incident, UNRWA and its partners had to pause assistance activities to northern Gaza, affecting 200,000 people, for 19 days, a UNRWA representative said. Since March 24, the Israeli government has restricted access to northern Gaza for UNRWA , refusing to allow UNRWA to provide food assistance to the north, despite UNRWA’s mandate. Israeli authorities have taken other steps that have undermined the ability of UNRWA to distribute aid in Gaza, which has contributed to the dire humanitarian situation, given that UNRWA has maintained  the largest humanitarian aid operation in Gaza.

    The Israeli military told CNN the same day that it was looking into the incident. An UNRWA official told Human Rights Watch that Israeli authorities have since acknowledged the attack and said they have put in place “prevention measures to prevent another such occurrence.”

    Attack on an MSF Guest House, February 20

    Just after 8 p.m. on February 20, an Israeli tank fired a medium- to large-caliber weapon at a multi-story apartment building in al-Mawasi neighborhood of Khan Younis housing only MSF staff and their families, 64 people in all. The attack killed two people and injured seven others. MSF said that the weapon was an Israeli tank shell. It said that staff saw no military objects in the area at the time and received no warning.

    On February 20, 2024, an Israeli tank fired a medium- to large-caliber weapon at a multi-story apartment building in al-Mawasi neighborhood of Khan Younis in Gaza.  The building housed only Médecins Sans Frontières (MSF) staff and their families, killing two people and injuring seven more.

    On February 20, 2024, an Israeli tank fired a medium- to large-caliber weapon at a multi-story apartment building in al-Mawasi neighborhood of Khan Younis in Gaza.  The building housed only Médecins Sans Frontières (MSF) staff and their families, killing two people and injuring seven more. © 2024 Mohammed Abed/MSF

    Photographs and videos included in a Sky News report on the attack and reviewed by Human Rights Watch confirm that a large MSF flag was draped on the outside of the building at the time of the attack. The images and satellite imagery also show that the building is secluded, with the nearest buildings approximately 50 meters away.

    MSF said that armed forces fired additional rounds at the building’s exterior and the interior of the ground floor. It told Human Rights Watch that an independent investigation, which was corroborated by witness accounts, confirmed that there had been an Israeli tank in the area at the time of the incident. The investigation found that the projectile causing the explosion was fired by an Israeli Merkava tank. The small-caliber bullet impacts on the building are consistent with the secondary armament of Merkava tanks, it also concluded. Human Rights Watch verified a photograph posted on X (formerly known as Twitter) by MSF on February 22, showing damage to the exterior of the building.

    MSF said that the organization had shared the coordinates of the building with the Israeli authorities prior to the attack. It received no warning. MSF said that, after the attack, Israeli authorities reconfirmed that they had received the coordinates of the building.

    In response to the attack, the Israeli army told Sky News the tank opened fire on the building because it had been “identified as a building where terror activity is occurring.” It committed to an examination by the Israeli Army's General Staff's Fact Finding and Assessment Mechanism, a permanent “independent” body established in 2014 to examine “exceptional incidents” that take place during military operations. No results have been made public.

    “These killings underscore the grim reality that nowhere in Gaza is safe, that promises of safe areas are empty and deconfliction mechanisms unreliable,” Meinie Nicolai, MSF general director, told Sky News after the incident.

    Attack on a Home Sheltering an American Near East Refugee Aid (Anera) Employee, March 8 

    On October 13, Doaa Shawwa, her husband Mousa Shawwa, and their children Dima, 13, and Karim, 6, fled their home in Tal al-Hawa and moved into the second-floor apartment of a friend in al-Zuwaida, in a building with three apartments further south. The attack killed at least three people and injured at least three more. Doaa told Human Rights Watch the neighborhood had avoided the worst of the hostilities over the subsequent months. Mousa was the Anera supply and logistics coordinator, and, upon moving to al-Zuwaida, he had communicated the coordinates of the home with his Anera colleagues, the organization confirmed.

    On March 8, an Israeli attack on an apartment in al-Zuwaida, killed Mousa Shawwa, the American Near East Refugee Aid (Anera) supply and logistics coordinator.

    On March 8, an Israeli attack on an apartment in al-Zuwaida, killed Mousa Shawwa, the American Near East Refugee Aid (Anera) supply and logistics coordinator. © Private

    Anera showed the New York Times emails it had sent to Israeli authorities in which it included the coordinates of the house, as well as photographs of the building, informing them that this was where one of their workers was living with his family. In the emails, Israeli authorities confirmed that the location was being “processed” in their “system.”

    On Friday, March 8, at about 4 p.m., an Israeli strike hit the building without warning, Doaa said. Mousa was standing in the doorway of the apartment with Doaa’s visiting brother, Baha al-Gifri, speaking to Doaa when the strike hit. “He was halfway through his sentence when we were hit. I don’t remember anything from that moment, I lost consciousness immediately and only woke up later in the hospital to find out that I had lost Mousa and my brother,” she said.

    Mousa had injuries all over his body and died as he arrived at al-Aqsa Hospital, Doaa said she was later told. Baha died at the moment of impact, with wounds to his head and face. Doaa’s 6-year-old son, Karim, had a head injury, but medical staff did not realize he had a skull fracture and internal bleeding in his brain, so his injuries went initially untreated. He died at al-Arish Hospital in Egypt, 11 days after the attack.

    With the assistance of Anera, Doaa, Karim, and Dima had been transferred to Egypt from Gaza eight days after the attack. The attack fractured Doaa’s right hand and caused a large wound to her face and head. It fractured Dima’s right foot, and covered her body and face with wounds from metal fragments. Dima also had burns on her right hand. A friend who owned the home in Gaza where they were attacked also had burns on his face, Doaa said.

    Doaa said that, as far as she knew, the other two apartments in their building had only been housing civilians, and that she knew of no presence of armed forces in the neighborhood. Human Rights Watch verified Al Jazeera footage, posted on YouTube on March 9, of the building after the attack which shows considerable damage to the second floor of the building, and experts consulted by the New York Times concluded the attack was carried out with a precision-guided air-dropped munition. Israel told the New York Times in response to its request for comment that the attack had targeted a Hamas member who participated in the October 7 assault in Israel. Anera said it had received no information from Israel about who or what had been targeted, or why.

    “We did not receive any warning from the Israelis before the attack,” Doaa said. “This is the thing that upsets me the most. My husband works for an American organization and the Israelis knew we were there. They should have sent us a message to warn us to get out. Why didn’t they?” Doaa said she keeps asking herself. “This was something beyond our imagination. Our hearts were destroyed.”

    Oh Say AOC

    Portside
    portside.org
    2024-05-16 06:02:39
    Oh Say AOC Geoffrey Thu, 05/16/2024 - 01:02 ...
    Original Article

    The Rebels: Elizabeth Warren, Bernie Sanders, Alexandria Ocasio-Cortez, and the Struggle for a New American Politics
    Joshua Green
    Penguin Press
    ISBN: 9780525560241

    WANT TO FEEL OLD? Some Americans born during the 2008 financial crisis will be getting their driver’s licenses this year. These youngest Zoomers have never known an America where serious people think that the free market can work without significant government intervention, and they’ve likely known the names Elizabeth Warren, Bernie Sanders, and Alexandria Ocasio-Cortez for as long as they’ve been politically aware. They have never believed capitalism would deliver for them, never experienced the disillusionment of seeing it fail for the first time, and never known the thrill of seeing it challenged by upstart politicians or the disappointment of seeing those politicians co-opted by moderating forces. They were born disillusioned.

    Their parents’ generation, typically born in the 1970s, grew up in a completely different America, one in which the neoliberal consensus was first taking shape. This is the America of journalist Joshua Green’s childhood. In his new book, The Rebels: Elizabeth Warren, Bernie Sanders, Alexandria Ocasio-Cortez, and the Struggle for a New American Politics, Green traces the neoliberal turn to 1978, when he was six, and when Jimmy Carter’s populist proposal to restructure the US tax code to be more egalitarian was rejected by a Democratic Congress. In grim economic circumstances, Carter then succumbed to pressure to sign a bill that prioritized tax cuts over redistribution, two years before Ronald Reagan would unseat him with a platform promising even more of that. The stage was set for thirty years of market-driven policies, during which Wall Street bankers would become steadily more entrenched in both political parties and would set the terms of national debate.

    Green uses this backstory to explain how the Democrats, a party once primarily accountable to unionized blue-collar workers, became so dominated by the finance industry that his titular protagonists had to mobilize for an ongoing struggle to restore the party to its working-class roots. If you’re my age (forty) or a bit younger, it’s a story you’ve probably spent much of your adult life immersed in. As the generation old enough to have grown up with the neoliberal dream and to have watched it come crashing down right when we were supposed to claim our stake in it, millennials are the base cohort for the genre of left-wing populism Green describes in The Rebels. Many of us have, or at least had, passionate feelings about one or more of the figures Green focuses on.

    Speaking for myself, between about 2015 and 2020, an attack on Sanders felt like an attack on my whole identity. Like many Sanders supporters—and like our New Left antecedents after about 1972—I’ve spent the pandemic and the Biden presidency contemplating the limits of romantic, youth-oriented left-wing electoral politics. When you’re emotionally invested in a politician’s success, it can be hard to objectively assess their role in history, especially in the face of bad faith criticism from defenders of the status quo.

    It’s to Green’s credit, then, that he’s able to tell a positive story about Warren, Sanders, and Ocasio-Cortez from the perspective of a mainstream political reporter who is broadly sympathetic. The Rebels is not the first book about these three or the movements they represent, but it might be the first to consider them soberly. Green documents their undeniable impact on national politics without indulging in hagiography or overinflated rhetoric.

    For Green, as for many observers, 2008 is the key moment of rupture. After the collapse of the housing market and the resulting economic meltdown, millions of people saw how both parties prioritized rescuing Wall Street over helping ordinary Americans. As a matter of fiscal engineering, Obama Treasury Secretary Timothy Geithner’s program of Wall Street bailouts succeeded on its own terms. As a matter of political optics, it was a disaster, communicating to a broad swath of the public that Washington had left them behind, as it largely had. Elements on the far right would eventually find ways to capitalize on this, culminating in the presidency of Donald Trump and the takeover of the GOP by MAGA populists. (Green wrote about this in his best-selling previous book, Devil’s Bargain: Steve Bannon, Donald Trump, and the Storming of the Presidency.) But the populist left would also see its first real opening since the Carter era to at least attempt a remaking of the Democratic Party.

    Although The Rebels’ subtitle and cover art suggest three protagonists with equal prominence, Warren gets the most attention. Sanders partisans who are still annoyed at Warren over the contentious 2020 primaries might look askance at this, but it makes sense in Green’s time line: for most of Obama’s two terms, Warren was the administration’s most prominent critic on the left, while Sanders was considered a Senate backbencher and the young Ocasio-Cortez had no profile whatsoever. It may be hard to remember now, but Warren’s reputation during Obama’s eventful first term was as a populist firebrand capable of channeling the public’s anger at the Wall Street bailouts through effective political theater.

    Before she ever ran or intended to run for Senate, Warren drew national attention by becoming one of Jon Stewart’s favored guests on the Daily Show, where she had a gift for translating wonky policy analysis into righteous, commonsensical rhetoric (“We just keep pulling the threads out of the regulatory fabric”). But she also kept the administration on its toes, leaking unflattering stories about Geithner to reporters and leading successful campaigns to sink Larry Summers’s appointment as Fed chair and Wall Street banker Antonio Weiss’s nomination to a Treasury Department job. At the time, Warrenmania and Occupy Wall Street were seen as responses to the same problem. Both signified young progressives becoming disenchanted by Obama’s failure to deliver real hope and change in the wake of the financial crisis. By the time Sanders emerged as a national figure in 2015—with Ocasio-Cortez volunteering for his campaign in New York—there was a significant network of leftists ready to organize.

    In the 2016 cycle, Warren decided not to challenge Hillary Clinton for the presidency (despite an energetic “draft Warren” campaign) because she feared that a hard-fought primary would diminish her influence on a likely Clinton administration. In Green’s telling, the Sanders campaign inherited what might have been Warren’s activist infrastructure almost overnight. Sanders’s appeal lay in his decades-long consistency and authenticity—“a kind of anti-charisma, a truculent refusal to indulge the bullshit and euphemism that’s the lingua franca of electoral campaigning”—which managed to draw thousands of young people to rallies across the country. It also attracted $228 million in small donations, demonstrating the viability of campaigning nationally without any support from Wall Street or other big donors. These organizing efforts, along with Trump’s unexpected victory over Clinton, galvanized young progressives and helped inspire a new generation of activists of diverse backgrounds to run for office.

    One of them was Ocasio-Cortez, who was working as a bartender when Sanders first ran and who found herself drawn into organizing by his calls for a “political revolution.” Green casts Ocasio-Cortez as a “natural” while also reminding us how improbable her rise was. He recounts how a group of Sanders campaign alums founded an organization called Brand New Congress that set out to recruit novice progressive candidates in all 435 congressional districts. In the end, they recruited only thirty, and of those, Ocasio-Cortez was the sole winner. Her upset victory against consummate Democratic insider Joe Crowley was a product of organizing, clever local strategizing, and demographic shifts in Queens and the Bronx, as well as her own unique strengths as a candidate.

    “Thanks to the vagaries of New York’s primary system, Ocasio-Cortez was able to build her appeal among a small, very liberal segment of her district’s voters—she won fewer than seventeen thousand votes in a primary that drew barely 5 percent of the district’s eligible voters—and that was enough for her to prevail,” writes Green. “None of this precluded her from becoming a force in the party or invalidated her full-spectrum leftist platform. She played by the rules that Crowley and his cronies had established, and she won.” That’s all true, and it meant that the Ocasio-Cortez phenomenon would be difficult to scale nationally, even though a handful of like-minded candidates across the country have since managed to build up the progressive “Squad” in the House. What has kept Ocasio-Cortez particularly influential, Green argues, has been twofold: first, she is based in New York City (with strongholds in some of the fastest-gentrifying neighborhoods in Queens) and thus enmeshed in the social universe of journalists and political staffers with national platforms; and second, she has skillfully adapted to a different set of political realities in Washington. After initially trying to legislate as an insurgent against House Speaker Nancy Pelosi and the Democratic establishment, Ocasio-Cortez moved away from the “activist phase of her congressional career,” toned down criticism of her colleagues, and began taking advantage of the theatrical potential of televised oversight hearings to drive national debates—a tactic Warren had pioneered.

    Watching Ocasio-Cortez’s trajectory, some on the left have accused her of surrendering to pressure from the establishment; some liberals counter that she has left childish things behind and sought greater influence inside the system. Certainly, to Green, her approach represents political maturity: “Being on the inside isn’t the same as selling out. It means your interests are represented. You get a say in what happens.” There’s something to that, but it risks losing sight of why Ocasio-Cortez attracted so much attention in the first place. Politicians who pursue traditional routes to public office don’t find themselves balancing their principles against the incentives of the inside game, because they never had principles to begin with. It is precisely because Ocasio-Cortez ran as a sincere activist that her adaptation to the ways of Washington represents sophistication and not simple careerism.

    Green credits his three “rebels” with successfully making the transition from outsiders to insiders within President Biden’s coalition, and in turn credits Biden with taking on their priorities. “In a break with past administrations, including Obama’s, Biden has begun to remake the political economy along many of the same lines as his populist opponents wished to do,” he writes. Green credits pressure from the party’s left wing—and its committed constituencies—for the fact that Biden began his term by pushing a $1.9 trillion COVID package through Congress “instead of worrying about deficits”; for walking union picket lines; for reinvigorating antitrust regulation and labor law enforcement; and for the record-setting climate investments of the Inflation Reduction Act.

    These are real accomplishments, and Green is right that the activists, organizers, and high-profile politicians on the left deserve to be proud of pushing the Democratic Party. The Rebels represents the mainstreaming of the contemporary left’s narrative on economic policy, which itself is a measure of the mainstreaming of the contemporary left’s substantive agenda.

    Still, the left’s narrative on Palestine remains well outside the Democratic mainstream. Since October 7, the Biden administration has squandered much of the credibility it built up with the left on its morally indefensible support for Israel’s assault on Gaza. To pro-Palestine activists, Warren, Sanders, and Ocasio-Cortez have all, to varying extents, fallen short of holding the administration accountable for its complicity in Israeli atrocities, even as it may cost Biden his reelection and return Trump to Washington. If that happens, it will fall to a new generation of leftists to organize for political power in the face of a hostile and intellectually exhausted establishment. As Green’s relatively optimistic account shows, that could take a long time.

    David Klion is a journalist and cultural critic working on a book about the legacy of neoconservatisms.

    Some notes on Rust, mutable aliasing and formal verification

    Hacker News
    graydon2.dreamwidth.org
    2024-05-16 06:01:53
    Comments...
    Original Article

    Hello, you've been (semi-randomly) selected to take a CAPTCHA to validate your requests. Please complete it below and hit the button!

    Things I won't work with: the higher states of bromine (2019)

    Hacker News
    blogs.sciencemag.org
    2024-05-16 05:24:02
    Comments...

    Earth rotation limits in-body image stabilization to 6.3 stops (2020)

    Hacker News
    thecentercolumn.com
    2024-05-16 04:17:08
    Comments...
    Original Article

    In 2016, Olympus Camera made some buzz in the photo world when they claimed that their new camera was capable of an impressive 6.5 stops of stabilization and that the limiting factor was in fact the rotation of the Earth.  This was rather surprising given the slow and steady improvement since the first such stabilization systems were introduced in lenses in the 1990s.  These only provided a couple stops of benefit.  Since then the technology has improved dramatically and the move from film to silicon has allowed it to be incorporated into the camera itself as IBIS.

    A major driver of this increase in stabilization performance has been in the gyroscopic sensors used to measure the vibration and control electronics used to correct it.  For these types of applications, the accuracy of the zero offset of the gyro sensor is often the limiting factor.  Even when perfectly still, noise will cause the sensor to read a small but non-zero value, which will in turn cause the stabilization system to drift.  The smaller the drift, the longer the stabilization system can hold an image steady.  If there were no noise on the gyro sensor and the stabilization system worked perfectly, it should in theory be able to provide an infinite number of stops of benefit.  However, at somewhere around 6 stops of shutter speed increase, the limiting factor stops becoming the electronics, and instead becomes the rotational motion of the Earth!

    To illustrate , lets imagine that you are somewhere on the Earth’s surface, pointing the camera due East or West.  For simplicity, lets assume you are on the equator, but your latitude doesn’t actually matter for this analysis.  There are 86,400 seconds in a day, so Earth rotates at a rate of 2π/86400 radians/second, or 7.27*10^-5 rad/s.  That means that your subject, which is presumably stationary on Earth’s surface as well, is rotating at this rate.  Your camera, which is using its IBIS system to attempt to keep everything as still as possible, may not realize that you are rotating with your subject and will instead try to zero out any rotation of the camera, including that of the Earth.  More technically, the camera is trying to maintain stability with respect to an inertial reference frame, which by virtue of the Earth’s rotation, you and your subject are not.

    As the Earth rotates during the exposure, a basic IS system will try to maintain the pointing of the camera as if it were in an inertial frame or reference. If the camera is pointed east, this will cause it to gradually point up compared to the subject, which is not on an inertial frame.

    The camera will of course move with the Earth and your subject, but will rotate relative to the subject.  If the camera is pointed east as shown in the figure above, it will rotate up relative to the subject.

    Lets say that you have an exposure time given by the variable T.  IBIS will therefore cause the image to move by a distance on the sensor given by:

    FocalLength \times T \times 7.27*10^-5

    Using our typical standard for the maximum allowable blur to be 1 pixel width, we get the maximum allowable shutter time to be

    T = \frac{1}{Focal Length}\frac{PixelWidth}{7.27e^{-5}}

    A 24 megapixel full frame camera will have pixels that are 0.0059mm wide.  Plugging this into the above equation, we get

    T = \frac{81}{Focal Length}

    If we take 1/Focal Length as the standard advice for the maximum shutter speed you can use to achieve sharp images, this equation says we can use shutter speeds 81 times as long with stabilization before Earth’s rotation blurs the image by one pixel.  In more familiar terms:

    log_{2}(81) = 6.3 Stops

    Neat.  Of course not all cameras have the same 0.0059mm pixel pitch, but the rule for the maximum hand-held shutter speed will vary accordingly, so this 6.3 stops will be consistent across most cameras.  We can turn this around and say that in order to provide 6.3 stops of stabilization, the system must be able to measure and compensate for rotations of the camera as slow as the Earth’s, or 360 degrees per day.  That’s pretty impressive.

    Presumably, a calculation like the one above or very similar was the inspiration for the claim by Olympus Camera:

    “6.5 stops is actually a theoretical limitation at the moment due to rotation of the earth interfering with gyro sensors”

    Since then the plot has thickened.  Olympus has released the OM-D E-M1X which claims to have 7.5 stops of stabilization, and Panasonic claims their new 70-200 f/2.8 has 7 stops of stabilization.  How could this be?  Without access to the data used to perform the CIPA stabilization rating test for these pieces of equipment, it’s difficult to say for sure.  In theory though, there are some possible ways to work around the limitations placed be Earth’s rotation:

    1.   Use the camera’s GPS, accelerometer, and compass to calculate exactly where it is pointed and its latitude.  With this information you could calculate the necessary offset and program your stabilization system to compensate accordingly.
    2.   Use a high pass filter on your stabilization system.  The rotation of the Earth is very constant, so if your gyro sensor should measure a small but constant rotation.  In comparison, your hands shake the camera all over the place, so an engineer could tell the sensor to only compensate for this later kind of motion.

    The first isn’t a good solution for many reasons.  Don’t have GPS signal?  Shooting next to a magnet?  Your system won’t work.  The second solution is much more plausible, but still very difficult.  The user would have to be pointing the camera at the subject for long enough such that the drift in their aim at the subject is smaller than the drift from the rotation of the earth.  This is also implausible.  What is concerning though, is that this second method is one that could work very well to cancel out Earth’s rotation on the CIPA specified stabilization test apparatus.

    For the CIPA stabilization test, the camera is mounted to a vibration platform.  The camera is then moved by the platform in a way that is determined by a CIPA provided waveform designed to mimic the motions from hand-holding a camera.  The setup is shown below:

    CIPA Image Stabilization Test Setup

    In this test setup, the camera is mounted to a very stable platform and held there for a long time before and after the test images are being taken.  In theory, this could make it much easier to for the camera to identify and filter out any effects from Earth’s rotation.  If the waveform has no very low frequency components, it would be easy to identify any low frequency motion as Earth’s rotation.  Without knowing exactly what waveform is given to camera manufacturers to perform this test though, it’s impossible to draw any meaningful conclusions.  It would be great if we could get some independent verification of the stated stabilization values, but CIPA seems to make that deliberately difficult.  As quoted on their application guide:

    • The applicant must be a corporate organization.
    • The applicant must understand that the standard and measurement kit cannot be provided to individuals, universities, or any other parties for research purposes.

    This seems unnecessarily restrictive to me and makes independent verification and analysis of the test impossible.

    This has been a long way of saying that I don’t know if Olympus and Panasonic have found a way to compensate for the Earth’s rotation in their stabilization systems, breaking through the 6.3 stop limit, or if they are achieving 7+ stops through oddities of the CIPA rating test.  If anyone has one of these cameras with 7+ stops of stabilization and some time on their hands, it would be really cool to show the camera breaking through the Earth rotation barrier.  If the cameras can’t, and you could show that Earth’s rotation is actually the limiting factor on the stabilization system, well that would be pretty cool too.

    [$] LWN.net Weekly Edition for May 16, 2024

    Linux Weekly News
    lwn.net
    2024-05-16 04:01:57
    The LWN.net Weekly Edition for May 16, 2024 is available....
    Original Article

    The page you have tried to view (LWN.net Weekly Edition for May 16, 2024) is currently available to LWN subscribers only.

    Reader subscriptions are a necessary way to fund the continued existence of LWN and the quality of its content.

    If you are already an LWN.net subscriber, please log in with the form below to read this content.

    Please consider subscribing to LWN. An LWN subscription provides numerous benefits, including access to restricted content and the warm feeling of knowing that you are helping to keep LWN alive.

    (Alternatively, this item will become freely available on May 23, 2024)

    Mozilla Foundation Welcomes Nabiha Syed as Executive Director

    Linux Weekly News
    lwn.net
    2024-05-16 03:56:33
    The Mozilla Foundation has announced that its new executive director will be Nabiha Syed. Syed is known for her mission-driven leadership, focused on increasing transparency into the most powerful institutions in society. She comes to Mozilla after leading The Markup, an award-winning publicat...
    Original Article

    [Posted May 16, 2024 by corbet]

    The Mozilla Foundation has announced that its new executive director will be Nabiha Syed.

    Syed is known for her mission-driven leadership, focused on increasing transparency into the most powerful institutions in society. She comes to Mozilla after leading The Markup, an award-winning publication that challenges technology to serve the public good, from its launch through its successful acquisition in 2024.


    (Log in to post comments)

    Mozilla Foundation Welcomes Nabiha Syed as Executive Director

    Posted May 16, 2024 7:00 UTC (Thu) by coriordan (guest, #7544) [Link]

    The internet needs users to come back to Firefox. A free software browser is one of the absolute most important packages for people to be in control of their use of technology. It would be great to hear from Syed about plans to achieve this.

    Mozilla Foundation Welcomes Nabiha Syed as Executive Director

    Posted May 16, 2024 7:51 UTC (Thu) by k3ninho (subscriber, #50375) [Link]

    As a Firefox user, I wish Mozilla would come back to Firefox, too.

    K3n.

    Mozilla Foundation Welcomes Nabiha Syed as Executive Director

    Posted May 16, 2024 15:55 UTC (Thu) by flussence (subscriber, #85566) [Link]

    I wish the people who built this browser would come back and do it again, but I wouldn't wish the task *upon* them.

    Mozilla Foundation Welcomes Nabiha Syed as Executive Director

    Posted May 16, 2024 11:41 UTC (Thu) by blyxyas (guest, #171533) [Link]

    The internet is made for Chrome / Chromium based browsers. While Firefox is not perfect, the fact that >70% of the market share is dominated by Chromium-based browsers doesn't help developers make their websites Gecko-friendly.

    It's quite sad hearing people say that "I'd love to use Firefox, but using the internet with it is a miserable experience".

    Mozilla Foundation Welcomes Nabiha Syed as Executive Director

    Posted May 16, 2024 11:56 UTC (Thu) by LtWorf (subscriber, #124958) [Link]

    I think firefox is back where it was in the IE days, in the sense that it's only known by a few nerds and nobody in the general population has any idea that it exists and what it is.

    Mozilla Foundation Welcomes Nabiha Syed as Executive Director

    Posted May 16, 2024 12:06 UTC (Thu) by roc (subscriber, #30627) [Link]

    That is sad. However, I use Firefox at home and Chrome at work and I don't find the experiences to be significantly different. I suppose there are some sites that don't work well in Firefox and I just don't happen to use them.

    Where are the sites that don't work in Firefox?

    Posted May 16, 2024 14:54 UTC (Thu) by dskoll (subscriber, #1630) [Link]

    I use Firefox on my desktop and my phone and have yet to encounter a site that fails to work with it. Where are all these broken sites?

    Where are the sites that don't work in Firefox?

    Posted May 16, 2024 15:13 UTC (Thu) by cesarb (subscriber, #6266) [Link]

    One example is Slack. Their "huddle" feature (which is basically audio or video chat) rejects Firefox as an unsupported browser, you have to use either Chrome/Chromium or their native client (which I suspect is just Chrome/Chromium disguised as a normal application).

    I've also had to switch to Chromium for video chat in Teams, but lately I've been able to use it in Firefox just fine.

    Where are the sites that don't work in Firefox?

    Posted May 16, 2024 15:18 UTC (Thu) by farnz (subscriber, #17727) [Link]

    One of the processes started as part of the "native" Slack client on my laptop is chrome_crashpad_handler - this strongly supports your suspicion that it's just a disguised browser.

    Where are the sites that don't work in Firefox?

    Posted May 16, 2024 16:01 UTC (Thu) by rschroev (subscriber, #4164) [Link]

    > their native client (which I suspect is just Chrome/Chromium disguised as a normal application)

    Yes, it's an Electron app, like Visual Studio Code, Atom and many others.

    Where are the sites that don't work in Firefox?

    Posted May 16, 2024 16:05 UTC (Thu) by tzafrir (subscriber, #11501) [Link]

    At work we need to use Office365 hosted domain. Authentication with yubikey only works with Chrome (or Firefox with a modified user agent). A great way to ignore Firefox users.

    Google fixes third actively exploited Chrome zero-day in a week

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 23:36:08
    ​Google has released a new emergency Chrome security update to address the third zero-day vulnerability exploited in attacks within a week. [...]...
    Original Article

    Google Chrome

    ​Google has released a new emergency Chrome security update to address the third zero-day vulnerability exploited in attacks within a week.

    "Google is aware that an exploit for CVE-2024-4947 exists in the wild," the search giant said in a security advisory published on Wednesday.

    The high-severity zero-day vulnerability (CVE-2024-4947) is caused by a type confusion weakness in the Chrome V8 JavaScript engine reported by Kaspersky's Vasily Berdnikov and Boris Larin.

    Although such flaws generally enable threat actors to trigger browser crashes by reading or writing memory out of buffer bounds, they can also exploit them for arbitrary code execution on targeted devices.

    The other two actively exploited Chrome zero-days patched this week are CVE-2024-4671 (a use-after-free flaw in the Visuals component) and CVE-2024-4761 (an out-of-bounds write bug in the V8 JavaScript engine).

    Microsoft also said it's "aware of the recent exploits existing in the wild" targeting CVE-2024-4947 and that its engineers are "actively working on releasing a security fix" for the Chromium-based Edge web browser.

    Fix rolling out to Stable channel users

    The company fixed the zero-day flaw with the release of 125.0.6422.60/.61 for Mac/Windows and 125.0.6422.60 (Linux). The new versions will roll out to all users in the Stable Desktop channel over the coming weeks.

    Chrome updates automatically when security patches are available. However, users can also confirm they're running the latest version by going to Chrome menu > Help > About Google Chrome, letting the update finish, and then clicking on the 'Relaunch' button to install it.

    Today's update was immediately available when BleepingComputer checked for new updates.

    Chrome 125.0.6422.61 update

    Seventh actively exploited zero-day patched in 2024

    While Google confirmed the CVE-2024-4947 bug was used in attacks, the company has yet to share more details regarding these incidents.

    "Access to bug details and links may be kept restricted until a majority of users are updated with a fix. We will also retain restrictions if the bug exists in a third party library that other projects similarly depend on, but haven't yet fixed," Google said.

    This latest Chrome vulnerability is the seventh zero-day fixed in the Google web browser since the start of the year, with the complete list of zero-days patched in 2024 including:

    • CVE-2024-0519: A high-severity out-of-bounds memory access weakness within the Chrome V8 JavaScript engine, allowing remote attackers to exploit heap corruption via a specially crafted HTML page, leading to unauthorized access to sensitive information.
    • CVE-2024-2887: A high-severity type confusion flaw in the WebAssembly (Wasm) standard. It could lead to remote code execution (RCE) exploits leveraging a crafted HTML page.
    • CVE-2024-2886: A use-after-free vulnerability in the WebCodecs API used by web applications to encode and decode audio and video. Remote attackers exploited it to perform arbitrary reads and writes via crafted HTML pages, leading to remote code execution.
    • CVE-2024-3159: A high-severity vulnerability caused by an out-of-bounds read in the Chrome V8 JavaScript engine. Remote attackers exploited this flaw using specially crafted HTML pages to access data beyond the allocated memory buffer, resulting in heap corruption that could be leveraged to extract sensitive information.
    • CVE-2024-4671: A high-severity use-after-free flaw in the Visuals component that handles the rendering and displaying content in the browser.
    • CVE-2024-4761: An out-of-bounds write problem in Chrome's V8 JavaScript engine, which is responsible for executing JS code in the application.

    Gaza: Israelis Attacking Known Aid Worker Locations

    Portside
    portside.org
    2024-05-15 22:00:17
    Gaza: Israelis Attacking Known Aid Worker Locations Maureen Wed, 05/15/2024 - 17:00 ...
    Original Article

    (Jerusalem, May 14, 2024) – Israeli forces have carried out at least eight strikes on aid workers’ convoys and premises in Gaza since October 2023, even though aid groups had provided their coordinates to the Israeli authorities to ensure their protection, Human Rights Watch said today. Israeli authorities did not issue advance warnings to any of the aid organizations before the strikes, which killed or injured at least 31 aid workers and those with them. More than 250 aid workers have been killed in Gaza since the October 7 assault in Israel, according to the UN.

    One attack on January 18, 2024, injured three people who were staying in a joint guest house belonging to two aid organizations and was most likely carried out with a US-made munition, according to one of the organizations and to a report by UN investigators who visited the site after the attack, which Human Rights Watch reviewed. One of the aid organizations, Medical Aid for Palestinians (MAP), said UN inspectors concluded that the bomb was delivered by an F-16 aircraft. F-16 aircraft use British made components according to campaigners.

    The eight incidents reveal fundamental flaws with the so-called deconfliction system, meant to protect aid workers and allow them to safely deliver life-saving humanitarian assistance in Gaza.

    “Israel’s killing of seven World Central Kitchen aid workers was shocking and should never have happened under international law,” said Belkis Wille, associate crisis, conflict, and arms director at Human Rights Watch. “Israel’s allies need to recognize that these attacks that have killed aid workers have happened over and over again, and they need to stop.”

    Israel’s attack on April 1 on the World Central Kitchen convoy, which killed seven workers, far from being an isolated “mistake,” is just one of at least eight incidents that Human Rights Watch identified in which aid organizations and UN agencies had communicated with Israeli authorities the GPS coordinates of an aid convoy or premises and yet Israeli forces attacked the convoy or shelter without any warning.

    In these eight incidents, Israeli forces killed at least 15 people, including 2 children, and injured at least 16 others. Five of these attacks were the subject of a recent New York Times investigation that included visual evidence and internal communications between aid organizations and the Israeli military.

    The other seven attacks are:

    • Attack on a Médecins Sans Frontières (MSF or Doctors without Borders) convoy, November 18, 2023
    • Attack on a guest house of the United Nations Relief and Works Agency for Palestine Refugees in the Near East (UNRWA), December 9, 2023
    • Attack on an MSF shelter, January 8, 2024
    • Attack on an International Rescue Committee (IRC) and Medical Aid for Palestinians (MAP) guest house, January 18, 2024
    • Attack on an UNRWA convoy, February 5, 2024
    • Attack on an MSF guest house, February 20, 2024
    • Attack on a home sheltering an American Near East Refugee Aid Organization (Anera) employee, March 8, 2024

    As of April 30, the UN reported that 254 aid workers had been killed in Gaza since October 7, 2023, with UNRWA personnel accounting for 188 of these fatalities. On May 13, a UN vehicle was hit on the way to a hospital in Gaza, killing at least one UN staff member and injuring at least one more. According to UNRWA, 169 of its facilities have been affected by the hostilities in 368 incidents and at least 429 displaced people have been killed in UNRWA shelters. Israeli forces have, according to the UN, also shot at and shelled people congregating to collect aid, killing and injuring hundreds. These attacks are having a chilling effect on efforts to provide lifesaving aid in Gaza.

    Aid workers have also been unable to leave Gaza, since Israeli forces seized control of and closed the Rafah Crossing on May 7.

    During a recent trip to Cairo and northern Sinai, near the border between Egypt and Gaza, Human Rights Watch met with staff from 11 humanitarian organizations and UN aid agencies operating in Gaza who said that Israeli attacks on aid workers had forced them to take various measures that for some included suspending activities for a period of time, reducing their staff inside Gaza, or severely restricting their aid activities in other ways.

    “I can’t risk sending more staff into Gaza because I cannot rely on deconfliction as a way of keeping them safe,” a senior employee from one of the organizations whose guest house was attacked told Human Rights Watch. He said this was a key factor in limiting the organization’s ability to provide medical services. “You can build docks and send shipments, but without a safe operating environment, you will have a pile up of shipments that people aren’t able to deploy safely to help people.”

    This pattern of attacks despite proper notification of Israeli authorities raises serious questions about Israel’s commitment and capacity to comply with international humanitarian law, which some countries, including the UK, rely on to continue to license arms exports that end up in Israel.

    Human Rights Watch has found that Israeli authorities are using starvation as a method of warfare in Gaza. Pursuant to a policy set out by Israeli officials and carried out by Israeli forces, the Israeli authorities are deliberately blocking the delivery of water, food, and fuel, willfully impeding humanitarian assistance, apparently razing agricultural areas, and depriving the civilian population of objects indispensable to its survival. Children in Gaza have been dying from starvation-related complications.

    Israel has not responded to a Human Rights Watch letter sent on May 1, requesting specific information about the attacks on aid workers documented in this report.

    The laws of war prohibit attacks that target civilians and civilian objects, that do not discriminate between civilians and combatants, or that are expected to cause harm to civilians or civilian objects that is disproportionate to any anticipated military advantage. Indiscriminate attacks include attacks that are not directed at a specific military target or use a method or means of combat whose effects cannot be limited as required.

    Warring parties must take all feasible precautions to minimize harm to civilians, including by providing effective advance warnings of attacks unless circumstances do not permit, and by sparing civilians under their control from the effects of attacks. Serious violations of the laws of war committed by individuals with criminal intent – that is, deliberately or recklessly – are war crimes.

    Israel should make public the findings of investigations into attacks that have killed and injured aid workers, and into all other attacks that caused civilian casualties. The Israeli military’s long track record of failing to credibly investigate alleged war crimes underscores the importance of the International Criminal Court’s (ICC) inquiry into serious crimes committed by all parties to the conflict.

    Israeli and Palestinian officials should cooperate with the ICC in their work, Human Rights Watch said. Israel should also provide the Independent International Commission of Inquiry on the Occupied Palestinian Territory, including East Jerusalem, and Israel access to Gaza to conduct its investigations.

    Given the pattern of attacks on aid groups that have provided Israeli authorities with proper information about their locations, a group of recognized international experts should conduct an independent review of the humanitarian deconfliction process. Israel should give these experts full access to its processes, including the coordination and communications that occur before, during, and after such attacks as well as information regarding any alleged military target in the vicinity and any precautionary measures taken to mitigate harm.

    Israel’s allies, including the United States and United Kingdom – both states sending the weapons parts apparently used in at least one of the documented attacks – should suspend military assistance and arms sales to Israel so long as its forces commit systematic and widespread laws-of-war violations against Palestinian civilians with impunity. Governments that continue to provide arms to the Israeli government risk complicity in war crimes.

    They should also use their leverage, including through targeted sanctions, to press Israeli authorities to cease committing grave abuses and enable the provision of humanitarian aid and basic services in Gaza, in accordance with Israel’s obligations under international law and recent International Court of Justice (ICJ) orders to Israel in the case brought by South Africa concerning alleged violations of the Genocide Convention.

    “On one hand, Israel is blocking access to critical lifesaving humanitarian provisions and on the other, attacking convoys that are delivering some of the small amount that they are allowing in,” Wille said. “Israeli forces should immediately end their attacks on aid organizations, and there should be accountability for these crimes.”

    For details of attacks on the aid organizations, please see below.

    Attack on the World Central Kitchen Workers

    On April 1, just before 11 p.m., Israeli forces carried out a drone strike with three missiles targeting a convoy of three World Central Kitchen (WCK) vehicles, two marked with the organization’s logo on the roof, in central Gaza, all carrying civilians, that were escorting eight aid trucks. The attack killed seven aid workers. The convoy had just left a food warehouse in Deir al-Balah and was traveling a route that the organization said they had agreed upon with the Israeli military. The attack was reportedly carried out by an Israeli-made Hermes 450 drone.

    After the attack, WCK paused its operations in Gaza for several weeks, as did American Near East Refugee Aid  (Anera). At the time, the two groups had together been providing an average of 300,000 meals across Gaza daily. Photographs of the damaged vehicles were initially verified by the independent investigative collective Bellingcat and later independently verified by Human Rights Watch researchers.

    A preliminary Israeli investigation into the attack found that Israeli forces’ conduct was “contrary to the Standard Operating Procedures” and had occurred because of “a grave mistake,” including a lack of coordination between different levels of the army and the mistaken identity of a man in one of the vehicles, according to the Israeli armed forces. The preliminary investigation also found that the two additional drone missiles were fired against army protocol.

    In its response, WCK reiterated its call for an independent commission to investigate the incident because, it said, the “[Israeli Defense Forces] cannot credibly investigate its own failure in Gaza.” WCK resumed its operations in late April because, it said, “The humanitarian situation in Gaza remains dire,” but said it had still received “no concrete assurances” that the Israeli military’s operational procedures had changed.

    This incident elicited widespread condemnation, including from leaders of countries whose citizens were killed in the attack, including United States President Joe Biden, United Kingdom Prime Minister Rishi SunakAustralian Prime Minister Anthony Albanese, and Canadian Prime Minister Justin Trudeau.

    Attack on a Médecins Sans Frontières (MSF) Convoy, November 18

    On November 18, 2023, armed forces attacked a convoy of five marked MSF vehicles, killing two people, witnesses said. The group had been trying to evacuate 137 civilians from its guesthouse near al-Shifa Hospital in Rimal, northern Gaza, where they had been trapped for a week, to southern Gaza. MSF said that it had coordinated the convoy’s movement with the Israeli armed forces and followed the route prescribed by the army. Once the convoy reached a crowded checkpoint near Wadi Gaza, Israeli soldiers did not allow the vehicles to clear the checkpoint for hours.

    When gunfire rang out near the checkpoint, MSF staff, who were still waiting to go through the checkpoint, decided to return to the guest house, 7.5 kilometers to the north. They said they maintained contact with the Israeli Coordination and Liaison Administration (CLA), the military unit responsible for the coordination of access to and from Gaza in connection with the facilitation of civilian and humanitarian needs, throughout their travel back and informed them that the convoy had to return to their guest house.

    As they were approaching their office, between 3:30 and 4 p.m., MSF said that the Israeli army attacked the convoy, hitting two of the vehicles. The organization quoted one staff member as saying: “I was terrified when I saw that the snipers and the tanks were pointing their weapons at us, especially at the fourth and the fifth van [in the convoy].” MSF said that the staff there during the incident saw no military targets in the area. The organization has requested an explanation from Israeli authorities, but has received no response, a representative told Human Rights Watch.

    “This incident shows just how ineffective the coordination mechanisms put in place by Israeli authorities have been,” said the representative of MSF. In this instance, “The latter appeared to have little or no influence on the operational troops on the ground, including to let the vehicles pass through the checkpoint.”

    This failed coordination with the CLA has been cited in previous UN reporting.

    Attack on a Guest House of the United Nations Relief and Works Agency for Palestine Refugees in the Near East (UNRWA), December 9

    On December 9, the Israeli navy fired 20mm cannon rounds at an UNRWA guest house consisting of two buildings in Rafah, Gaza’s southernmost governorate, the agency told Human Rights Watch. The rounds damaged the west side of both buildings. The attack occurred late in the evening, while 10 staff were asleep inside. The agency said it had shared the coordinates of the guest house with Israeli authorities on a regular basis prior to the attack, including on the date of the attack, and was not aware of any military targets in the area at the time. UNRWA told Human Rights Watch that it had received no warning of the attack. Following the attack, the deputy commander of the Israeli Southern Command told UNRWA that the attack had been carried out in error, UNRWA told Human Rights Watch.

    Attack on an MSF Shelter, January 8

    On January 8, an Israeli projectile pierced the side of a building in which over 100 MSF staff and their families were sheltering in Khan Yunis, MSF said. The strike killed the 5-year-old daughter of an MSF worker and injured four people. At the time, the staff saw no military targets in the area and received no warning of the attack, which took place in an area under no evacuation order, the organization told Human Rights Watch. The organization said it had shared the coordinates of the building with Israeli authorities on a regular basis, saying it was being used as an MSF shelter.

    MSF published a video in which Léo Cans, the MSF head of mission for Palestine, described the attack and showed two parallel holes in the wall that munitions had passed through, he said. The video also included two photographs of remnants lying on the grass, allegedly outside the building. Human Rights Watch could not confirm the location of these remnants but was not able to find them online prior to January 8. The New York Times analyzed the photographs and reported that they showed the remnants of an Israeli 120mm tank shell with Hebrew markings outside the shelter. Human Rights Watch independently verified the type of remnants. 

    The Israeli military denied to the New York Times that it had struck the building. However, MSF said that Israeli authorities later told the organization that the damage to the guest house had been collateral in an attack on a “terror” target.

    Attack on an International Rescue Committee (IRC) and Medical Aid for Palestinians (MAP) Guest House, January 18

    On January 18, an Israeli air attack hit the perimeter wall around a guest house being used by both the IRC and MAP north of Khan Younis, where 12 people, including 4 doctors, were staying at the time, according to the 2 organizations. No one was killed in the strike but three people suffered light injuries, MAP told Human Rights Watch.

    Satellite analysis shows the attack left a roughly 15-meter-wide crater in the sandy ground, destroyed the wall marking the perimeter of the property, and significantly damaged the house. MAP confirmed to Human Rights Watch that the organization had shared the coordinates of the guest house with the Israeli authorities and with the UN twice in late 2023 to ensure it did not come under attack. The building stands alone, with no other buildings or structures around it, and MAP said they knew of no military targets in the area at the time of the attack and received no warnings.

    Human Rights Watch reviewed a report of an on-site independent assessment by a multi-agency UN team after the attack, which concluded that the damage was the result of an airstrike, most likely involving a US-made guided GBU-32 air-dropped bomb. MAP said inspectors concluded that the bomb was delivered by an F-16 aircraft. The organizations said that, since the attack, Israel has provided six different and often contradictory explanations as to whether and why the attack took place, but they said the explanations had not provided clarity or accountability.

    Attack on an UNRWA Convoy, February 5

    On February 5, Israeli naval gunfire hit an UNRWA aid truck, the agency said. The attack occurred while a convoy of 10 trucks flanked by marked UN vehicles were parked on a road in western Nuseirat, waiting at a previously agreed holding point for permission from the Israeli military to proceed to an Israeli checkpoint. The shelling damaged the last truck in the convoy. No one was injured. UNRWA said it had coordinated with Israeli authorities the planned movement of trucks prior to the attack, including reporting to Israeli authorities when the convoy had reached the holding point and when aid workers in the convoy began to hear naval gunfire in proximity to the stationary convoy.

    On February 5, 2024, Israeli naval gunfire hit an UNRWA aid truck carrying food.Click to expand Image

    On February 5, 2024, Israeli naval gunfire hit an UNRWA aid truck carrying food. © 2024 UNRWA

    Because of this incident, UNRWA and its partners had to pause assistance activities to northern Gaza, affecting 200,000 people, for 19 days, a UNRWA representative said. Since March 24, the Israeli government has restricted access to northern Gaza for UNRWA , refusing to allow UNRWA to provide food assistance to the north, despite UNRWA’s mandate. Israeli authorities have taken other steps that have undermined the ability of UNRWA to distribute aid in Gaza, which has contributed to the dire humanitarian situation, given that UNRWA has maintained  the largest humanitarian aid operation in Gaza.

    The Israeli military told CNN the same day that it was looking into the incident. An UNRWA official told Human Rights Watch that Israeli authorities have since acknowledged the attack and said they have put in place “prevention measures to prevent another such occurrence.”

    Attack on an MSF Guest House, February 20

    Just after 8 p.m. on February 20, an Israeli tank fired a medium- to large-caliber weapon at a multi-story apartment building in al-Mawasi neighborhood of Khan Younis housing only MSF staff and their families, 64 people in all. The attack killed two people and injured seven others. MSF said that the weapon was an Israeli tank shell. It said that staff saw no military objects in the area at the time and received no warning.

    On February 20, 2024, an Israeli tank fired a medium- to large-caliber weapon at a multi-story apartment building in al-Mawasi neighborhood of Khan Younis in Gaza.  The building housed only Médecins Sans Frontières (MSF) staff and their families, killing two people and injuring seven more. Click to expand Image

    On February 20, 2024, an Israeli tank fired a medium- to large-caliber weapon at a multi-story apartment building in al-Mawasi neighborhood of Khan Younis in Gaza.  The building housed only Médecins Sans Frontières (MSF) staff and their families, killing two people and injuring seven more. © 2024 Mohammed Abed/MSF

    Photographs and videos included in a Sky News report on the attack and reviewed by Human Rights Watch confirm that a large MSF flag was draped on the outside of the building at the time of the attack. The images and satellite imagery also show that the building is secluded, with the nearest buildings approximately 50 meters away.

    MSF said that armed forces fired additional rounds at the building’s exterior and the interior of the ground floor. It told Human Rights Watch that an independent investigation, which was corroborated by witness accounts, confirmed that there had been an Israeli tank in the area at the time of the incident. The investigation found that the projectile causing the explosion was fired by an Israeli Merkava tank. The small-caliber bullet impacts on the building are consistent with the secondary armament of Merkava tanks, it also concluded. Human Rights Watch verified a photograph posted on X (formerly known as Twitter) by MSF on February 22, showing damage to the exterior of the building.

    MSF said that the organization had shared the coordinates of the building with the Israeli authorities prior to the attack. It received no warning. MSF said that, after the attack, Israeli authorities reconfirmed that they had received the coordinates of the building.

    In response to the attack, the Israeli army told Sky News the tank opened fire on the building because it had been “identified as a building where terror activity is occurring.” It committed to an examination by the Israeli Army's General Staff's Fact Finding and Assessment Mechanism, a permanent “independent” body established in 2014 to examine “exceptional incidents” that take place during military operations. No results have been made public.

    “These killings underscore the grim reality that nowhere in Gaza is safe, that promises of safe areas are empty and deconfliction mechanisms unreliable,” Meinie Nicolai, MSF general director, told Sky News after the incident.

    Attack on a Home Sheltering an American Near East Refugee Aid (Anera) Employee, March 8 

    On October 13, Doaa Shawwa, her husband Mousa Shawwa, and their children Dima, 13, and Karim, 6, fled their home in Tal al-Hawa and moved into the second-floor apartment of a friend in al-Zuwaida, in a building with three apartments further south. The attack killed at least three people and injured at least three more. Doaa told Human Rights Watch the neighborhood had avoided the worst of the hostilities over the subsequent months. Mousa was the Anera supply and logistics coordinator, and, upon moving to al-Zuwaida, he had communicated the coordinates of the home with his Anera colleagues, the organization confirmed.

    On March 8, an Israeli attack on an apartment in al-Zuwaida, killed Mousa Shawwa, the American Near East Refugee Aid (Anera) supply and logistics coordinator.Click to expand Image

    On March 8, an Israeli attack on an apartment in al-Zuwaida, killed Mousa Shawwa, the American Near East Refugee Aid (Anera) supply and logistics coordinator. © Private

    Anera showed the New York Times emails it had sent to Israeli authorities in which it included the coordinates of the house, as well as photographs of the building, informing them that this was where one of their workers was living with his family. In the emails, Israeli authorities confirmed that the location was being “processed” in their “system.”

    On Friday, March 8, at about 4 p.m., an Israeli strike hit the building without warning, Doaa said. Mousa was standing in the doorway of the apartment with Doaa’s visiting brother, Baha al-Gifri, speaking to Doaa when the strike hit. “He was halfway through his sentence when we were hit. I don’t remember anything from that moment, I lost consciousness immediately and only woke up later in the hospital to find out that I had lost Mousa and my brother,” she said.

    Mousa had injuries all over his body and died as he arrived at al-Aqsa Hospital, Doaa said she was later told. Baha died at the moment of impact, with wounds to his head and face. Doaa’s 6-year-old son, Karim, had a head injury, but medical staff did not realize he had a skull fracture and internal bleeding in his brain, so his injuries went initially untreated. He died at al-Arish Hospital in Egypt, 11 days after the attack.

    With the assistance of Anera, Doaa, Karim, and Dima had been transferred to Egypt from Gaza eight days after the attack. The attack fractured Doaa’s right hand and caused a large wound to her face and head. It fractured Dima’s right foot, and covered her body and face with wounds from metal fragments. Dima also had burns on her right hand. A friend who owned the home in Gaza where they were attacked also had burns on his face, Doaa said.

    Doaa said that, as far as she knew, the other two apartments in their building had only been housing civilians, and that she knew of no presence of armed forces in the neighborhood. Human Rights Watch verified Al Jazeera footage, posted on YouTube on March 9, of the building after the attack which shows considerable damage to the second floor of the building, and experts consulted by the New York Times concluded the attack was carried out with a precision-guided air-dropped munition. Israel told the New York Times in response to its request for comment that the attack had targeted a Hamas member who participated in the October 7 assault in Israel. Anera said it had received no information from Israel about who or what had been targeted, or why.

    “We did not receive any warning from the Israelis before the attack,” Doaa said. “This is the thing that upsets me the most. My husband works for an American organization and the Israelis knew we were there. They should have sent us a message to warn us to get out. Why didn’t they?” Doaa said she keeps asking herself. “This was something beyond our imagination. Our hearts were destroyed.”

    Your tax deductible gift can help

    Fair Use Still Protects Histories and Documentaries—Even Tiger King

    Electronic Frontier Foundation
    www.eff.org
    2024-05-15 21:28:44
    Copyright’s fair use doctrine protects lots of important free expression against the threat of ruinous lawsuits. Fair use isn’t limited to political commentary or erudite works – it also protects popular entertainment like Tiger King, Netflix’s hit 2020 documentary series about the bizarre and somet...
    Original Article

    Copyright’s fair use doctrine protects lots of important free expression against the threat of ruinous lawsuits. Fair use isn’t limited to political commentary or erudite works – it also protects popular entertainment like Tiger King, Netflix’s hit 2020 documentary series about the bizarre and sometimes criminal exploits of a group of big cat breeders. That’s why a federal appeals court’s narrow interpretation of fair use in a recent copyright suit threatens not just the producers of Tiger King but thousands of creators who make documentaries, histories, biographies, and even computer software. EFF and other groups asked the court to revisit its decision. Thankfully, the court just agreed to do so.

    The case, Whyte Monkee Productions v. Netflix, was brought by a videographer who worked at the Greater Wynnewood Exotic Animal Park, the Oklahoma attraction run by Joe Exotic that was chronicled in Tiger King. The videographer sued Netflix for copyright infringement over the use of his video clips of Joe Exotic in the series. A federal district court in Oklahoma found Netflix’s use of one of the video clips—documenting Joe Exotic’s eulogy for his husband Travis Maldonado—to be a fair use. A three-judge panel of the Court of Appeals for the Tenth Circuit reversed that decision and remanded the case, ruling that the use of the video was not “transformative,” a concept that’s often at the heart of fair use decisions.

    The appeals court based its ruling on a mistaken interpretation of the Supreme Court’s opinion in Andy Warhol Foundation for the Visual Arts v. Goldsmith. Warhol was a deliberately narrow decision that upheld the Supreme Court’s prior precedents about what makes a use transformative while emphasizing that commercial uses are less likely to be fair. The Supreme Court held that commercial re-uses of a copyrighted work—in that case, licensing an Andy Warhol print of the artist Prince for a magazine cover when the print was based on a photo that was also licensed for magazine covers—required a strong justification. The Warhol Foundation’s use of the photo was not transformative, the Supreme Court said, because Warhol’s print didn’t comment on or criticize the original photograph, and there was no other reason why the foundation needed to use a print based on that photograph in order to depict Prince. In Whyte Monkee, the Tenth Circuit honed in on the Supreme Court’s discussion about commentary and criticism but mistakenly read it to mean that only uses that comment on an original work are transformative. The court remanded the case to the district court to re-do the fair use analysis on that basis.

    As EFF, along with Authors Alliance, American Library Association, Association of Research Libraries, and Public Knowledge explained in an amicus brief supporting Netflix’s request for a rehearing, there are many kinds of transformative fair uses. People creating works of history or biography frequently reproduce excerpts from others’ copyrighted photos, videos, or artwork as indispensable historical evidence. For example, using sketches from the famous Zapruder film in a book about the assassination of President Kennedy was deemed fair, as was reproducing the artwork from Grateful Dead posters in a book about the band. Software developers use excerpts from others’ code—particularly declarations that describe programming interfaces—to build new software that works with what came before. And open government organizations, like EFF client Public.Resource.Org, use technical standards incorporated into law to share knowledge about the law. None of these uses involves commentary or criticism, but courts have found them all to be transformative fair uses that don’t require permission.

    The Supreme Court was aware of these uses and didn’t intend to cast doubt on their legality. In fact, the Supreme Court cited to many of them favorably in its Warhol decision. And the Court even engaged in some non-commentary fair use itself when it included photos of Prince in its opinion to illustrate how they were used on magazine covers. If the Court had meant to overrule decades of court decisions, including its own very recent Google v. Oracle decision about software re-use, it would have said so.

    Fortunately, the Tenth Circuit heeded our warning, and the warnings of Netflix, documentary filmmakers, legal scholars, and the Motion Picture Association, all of whom filed briefs. The court vacated its decision and asked for further briefing about Warhol and what it means for documentary filmmakers.

    The bizarre story of Joe Exotic and his friends and rivals may not be as important to history as the Kennedy assassination, but fair use is vital to bringing us all kinds of learning and entertainment. If other courts start treating the Warhol decision as a radical rewriting of fair use law when that’s not what the Supreme Court said at all, many kinds of free expression will face an uncertain future. That’s why we’re happy that the Tenth Circuit withdrew its opinion. We hope the court will, as the Supreme Court did, reaffirm the importance of fair use.

    Join EFF Lists

    A ‘plague’ comes before the fall: lessons from Roman history

    Hacker News
    thebulletin.org
    2024-05-15 21:11:55
    Comments...
    Original Article

    Colosseum.The ruins of the Colosseum in Rome. Credit: Livioandronico2013. CC BY-SA 4.0.

    The Pax Romana—the 200-year “golden age” of the Roman Empire—was a marvel of diversity, connectivity, and unchallenged hegemony. By the middle of the second century AD, imperial Rome ruled territory across three different continents. Roughly one-quarter of the Earth’s population, some 60 million people, lived under Rome’s vast aegis, and the emperors of the age—most notably Marcus Aurelius—enjoyed the consent of those they governed. The Empire’s elites—witnessing the disciplined legions, widespread religiosity, cultural efflorescence, and dominant economy—likely expected their world order to endure forever.

    In the year 166 AD, however, seemingly eternal Rome was caught completely off-guard as a deadly novel disease swept across the Eurasian landmass. It ransacked Rome’s cities for at least a decade and preceded centuries of decline. This major biological event—now known as the Antonine plague—appears to have been the world’s first pandemic.

    Historians hotly debate its death toll—with estimates ranging from 2 percent to 35 percent mortality—and its broader social and economic effects. The disease itself remains undiagnosed. The great Greek physician Galen described its main symptoms as fever, throat ulcers, and a pustular rash. Some have suspected it was measles or smallpox, but modern analysis provides reasons to doubt these as the possible culprits. Human remains from the Antonine plague period, meanwhile, have thus far failed to yield genetic evidence sufficient to identify the pathogen.

    Although the plague did not on its own cut short Rome’s dominance, it struck an empire that was confronting multiple challenges beneath a veneer of prosperity and growth—factors that modern-day infectious disease experts might recognize as creating the ideal conditions for pandemics. Much remains unknown about the Antonine plague; in some ways, modern scholars are just as in the dark about this first pandemic as its contemporary victims. But interdisciplinary researchers, trying to understand how the plague could have helped push such a powerful empire to the breaking point, have recently been unravelling some of its mysteries.

    Probing the plague. Historians, archaeologists, and scientists have been sharing data and expertise, working together to develop histories of past pandemics—including the Antonine plague—that are surprisingly comprehensive and nuanced. Paleogenetic and paleoclimatological evidence reveal the crucial role of environmental and demographic factors in the pandemic. Insights from modern economics and sociology have improved historians’ understanding of how the institutions of the Roman Empire were affected by disease mortality. Even before the pandemic arrived, the pre-existing ecological, economic, and demographic context of mid-second century Eurasia prepared the way for the disease that would accelerate the end of Rome’s era of efflorescence.

    Research assessing the severity of modern anthropogenic climate change, for example, has compiled a vast array of climatological data dating back to the Roman period, and well before. Such research offers historians an increasingly detailed and comprehensive view of the ecosystems of ancient Eurasia and Africa. The ancient Mediterranean was (and still is) polka-dotted with microclimates; meanwhile, ice cores from Greenland, ancient tree rings from northern Europe, and sediment cores from Egypt and Italy suggest that some regions in and around Roman territory endured cooler temperatures and droughts about a decade ahead of the Antonine plague pandemic. These climatological shifts were hardly severe, nor did they affect the entire Mediterranean Basin. Many of the affected regions, however, happened to play outsized roles in supplying Roman cities with grain.

    The annual Nile flood in Egypt, for instance, reliably nourished well-irrigated grainfields with nutrient-rich water from the Ethiopian highlands. The resulting harvests, often abundant, were stored and then shipped in massive vessels across the Mediterranean to Rome for distribution to the city’s masses. But from the 150s onward, a series of droughts near the Nile headwaters in equatorial east Africa disrupted the flood, reducing the productivity of Rome’s main breadbasket. Meanwhile, at the same time, increased storm activity in the western Mediterranean—as confirmed by sediment cores extracted from the coast of southern France—made shipping already scarce grain far riskier than in previous centuries. As a result, denizens of Rome and several other major cities, and possibly also some of Rome’s soldiers, endured greater food insecurity and malnutrition—weakening their bodies ahead of the pandemic’s arrival in the 160s.

    An interconnected, vulnerable ancient world. Historians still don’t know exactly where and when the pandemic entered Roman territory. But, again, historical circumstances conspired in favor of the novel disease.

    An outbreak today can jump continents as quickly as an airplane can fly. Travel and transportation can facilitate the spread of infectious diseases. It may not be coincidental, therefore, that by the time of the Antonine plague, the Eurasian landmass was better-connected than ever before. In 166 AD, for the first time in recorded history, the imperial Han court in Luoyang, China, received visitors from the Roman Empire. Merchants from India, sub-Saharan Africa, Arabia, and Egypt rode the trade winds to ports all around the Indian Ocean. Roman soldiers, seeking to police and tax such abundant trade, ventured well outside Roman borders—as Latin inscriptions in the Farasan Islands of southern Arabia attest. In short, there were plenty of opportunities for novel diseases to cross political and geographic barriers into new populations, transforming what might have otherwise been a regional epidemic into a pandemic that spread across three different continents.

    In the Roman Empire, an impressive transportation infrastructure—once a source of economic and military power—became a sudden liability once the pandemic breached its borders. Roman roads and ships weren’t themselves responsible, but larger movements and migrations transported the disease from city to city.

    Because of the shifts in local climates, and resulting food insecurity, desperate and hungry rural peasants had already flooded into cities in Asia Minor (present day Turkey) and Italy. Beyond Roman borders, nomadic peoples on the Eurasian Steppe in search of food pushed against the Germanic tribes along the Danube River, sending hordes of migrants and invaders into Roman frontier provinces. Contemporary sources from the Han Empire reference a series of epidemics in several Chinese cities, as well as the army. Concerns over ever-present sickness were partly responsible for the famed Yellow Turban Rebellion—a peasant rebellion that unleashed decades of civil war and instability in much of eastern China.

    At the exact same time, tens of thousands of Roman soldiers were uprooted from their military bases and sent thousands of miles—first to fight a war on the Empire’s eastern frontier in Persia (Iran), then back into Europe to resist the surging tide of Germanic migrants. At multiple points along these journeys, soldiers could have collected the Antonine plague pathogen.

    The plague and the capital. Rome’s large legions might have sustained disease transmission for weeks, if not months, as armies passed back-and-forth through the same densely populated cities of Asia Minor and Italy that were taking on underfed refugees from the budding crisis.

    None of these cities, however, were as packed as Rome—a cosmopolis of over one million people. In October of 166 AD, just as the pandemic reached Italy, the city held a massive triumphal parade for the legions, fresh off their victory in Persia. Perhaps 100,000 or more citizens crammed into the city center to celebrate, creating what may have been the world’s first super-spreader event.

    Shortly following the triumph, the streets of Rome must have resembled a war zone. Bodies were so strewn about the city that Marcus Aurelius and his co-emperor imposed strict regulations on burials and tombs. They funded corpse removal. They sought out the gods for aid. At some point, perhaps after the first wave abated, the emperors commissioned statues to memorialize elite victims, while the masses were commemorated in remembrance events.

    The ancient Romans had limited means to treat the Antonine plague, although they developed many remedies of unknown or suspect effectiveness. Elites, including the emperor Marcus Aurelius, used a concoction called “theriac”—an aged blend of exotic spices and expensive substances, mixed with a dose of opium. Others tried various smell therapies—including smelling laurel leaves. Galen claimed that fresh urine applied directly to the skin could help—the younger the urinator, the better.

    The Antonine plague would continue to rage in the cities and military camps of the Roman Empire for at least another decade. A second wave of an undiagnosed epidemic disease hit Rome in 190 AD; if this too was part of the Antonine plague, then the pandemic lasted at least a quarter-century. However long it endured, the plague was an unprecedented test the resilience of Roman systems; Galen named it “the everlasting pestilence.”

    Marcus may have rallied Rome during the first wave. But when the plague struck northern Italy a few years later, he abandoned his friends and soldiers to a dark winter of sickness. Officials responded to drought and high grain prices with price controls, most likely disincentivizing production and making shortages even worse. In response to plague and war deaths in the legions, Marcus recruited criminals and slaves into the military. This proved fateful when, a few years later, many of them deserted and, now well-equipped and trained, turned on the cities of the Empire, pillaging and murdering in a crime wave that stretched from Asia Minor to western Europe.

    While it might seem like the pandemic single-handedly caused the decline and fall of the Roman Empire, it was clearly more complicated than that. The western Roman Empire would muddle along for over 200 years, but its heyday ended with the Antonine plague. The plague exposed and exacerbated pre-existing fragilities. Many Roman achievements may have been grand, but the Empire was a product of its pre-industrial context, in which weather, famine, and other factors could be destabilizing. The agricultural economy was subject to the vagaries of its ecosystem and the limitations of fledgling markets. Roman cities, for all the attention paid to aqueducts and baths, were contaminated by poor sanitation and grappled with persistent malnutrition. They may have been temporarily well-connected enough to enjoy the commodities of distant regions, but these same populations were simultaneously “immunologically naive” to pathogens from outside their immediate area. While it is no coincidence that the pandemic and the end of the Pax Romana occurred at the same time, exploring the connections between them underscores the interconnectedness and even interdependence of past human societies and their environmental contexts.

    Present societies now easily mitigate much of what ailed Rome during the Antonine plague. The wonders of modern medicine—treatments, vaccines, and proven sanitation measures—render once-deadly scourges innocuous or even eradicated. A globalized society is one which collaborates and coordinates—orienting markets, scientific research, and communication channels towards responding to threats and, even better, predicting and preventing them before they occur. And yet, like the Roman Empire, the strengths of the modern world order have inbuilt weaknesses. Travel and transportation are so cheap and easy that pandemic diseases seem virtually impossible to contain.

    The collaborative process that permeates most democratic societies nevertheless requires seemingly slow and cumbersome debate and consensus building. Yet all told, the modern world’s capacity to understand and adapt to our natural context—clumsy as it is at times—so far continues to outpace the rapidly evolving diseases that surround us. A vital part of our strategy must be to learn from the pandemics of the past.

    Android to add new anti-theft and data protection features

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 21:10:21
    ​Google is introducing multiple anti-theft and data protection features later this year, some available only for Android 15+ devices, while others will roll out to billions of devices running Android 10 and later. [...]...
    Original Article

    Android

    ​Google is introducing multiple anti-theft and data protection features later this year, some available only for Android 15+ devices, while others will roll out to billions of devices running Android 10 and later.

    To protect your personal and sensitive data if your device is stolen or lost, a new AI-powered automated screen lock named Theft Detection Lock will lock the screen if it detects abrupt motions associated with theft attempts, like thieves snatching your device out of your hand.

    To further ensure that thieves can't access your sensitive data and apps, another new feature known as Offline Device Lock will automatically lock the device shortly after a thief disconnects it from the network or if it detects too many failed authentication attempts.

    Google also announced a Remote Lock feature to help those whose Android devices were stolen lock their smartphones or tablets remotely using only their phone number and a security challenge. To use the feature, you will have to go to android.com/lock.

    "This buys you time to recover your account details and access additional helpful options in Find My Device, including sending a full factory reset command to completely wipe the device," said Google Vice President Suzanne Frey.

    Theft Detection Lock, Offline Device Lock, and Remote Lock will be available on devices running Android 10 or later through a Google Play services update that will roll out later this year.

    ​As announced at Google I/O 2024, the new Android 15 release will also upgrade factory reset protection to make stolen devices very difficult or impossible to sell by requiring your Google account credentials during the setup process.

    "With this upgrade, if a thief forces a reset of the stolen device, they're not able to set it up again without knowing your device or Google account credentials. This renders a stolen device unsellable, reducing incentives for phone theft," Frey added.

    Android theft alert
    Android theft alert (Google)

    Android will also require your PIN, password, or biometric authentication when trying to access or change critical Google account and device settings from an untrusted location, such as changing your PIN, accessing Passkeys, or disabling theft protection.

    Similarly, disabling Find My Device or extending the device screen timeout will also require entering your PIN or password or using some form of biometric authentication.

    This adds one more layer of security designed to prevent criminals who steal your device from keeping it "unlocked or untrackable online."

    The new Android version will also include so-called "private spaces" that can be locked using a PIN of your choice to prevent thieves from accessing sensitive data stored in your apps, such as health or financial information.

    Factory reset protection updates and private space will be released when Android 15 launches this fall, while enhanced authentication protections will be available on select devices later this year.

    At Google I/O 2024, the company also announced new Android 15 and Google Play Protect features to protect against scams, fraud, spyware, and banking malware.

    What’s the difference between an -ectomy, an -ostomy, and an -otomy? (1986)

    Hacker News
    www.straightdope.com
    2024-05-15 21:01:37
    Comments...
    Original Article

    Dear Cecil: In medicine, what’s the difference between an "-ectomy,” an "-ostomy,” and an "-otomy”? My wife believes they mean “hack it off,” “bite it off,” and “pinch it till it drops off.” J.W., Chicago

    861219.gif

    Illustration by Slug Signorino

    Cecil replies:

    Very funny, J.W., and actually not all that far off the mark. Turning to Taber’s Cyclopedic Medical Dictionary, which for an old deve like me is a constant garden of delight, we learn the following:

    • An “-ectomy” is the cutting out of something, as in “tonsillectomy.” In other words, hacking it off. This may account for lingering male squeamishness about another well-known operation, the vasectomy. (In reality, of course, only a tiny portion of the vas deferens is removed.)
    • An “-ostomy” (actually, “-stomy”) involves cutting a hole in something, or more precisely, furnishing it with a mouth or outlet, as in “colostomy,” in which an opening is cut into the colon to create an artificial anus. (Seems like a waste, considering how many real ones there are already.)
    • Finally, there’s “-otomy,” (or “-tomy”), which means to slice it up, i.e., an operation in which cutting is involved. Thus we can distinguish a lobectomy, in which a lobe, typically of the brain, is removed, from a lobotomy, in which they merely jab an ice pick in there and chop things up.

    I’m not kidding, either. You might want to read an engrossing volume entitled Great and Desperate Cures: The Rise and Decline of Psychosurgery and Other Radical Treatments for Mental Illness, by Elliott Valenstein (1986). Valenstein quotes a letter written in the mid-1940s by one prominent lobotomist, Walter Freeman:

    I have also been trying out a sort of half-way stage between electroshock and prefrontal lobotomy [to treat mental patients]. … This consists of knocking them out with a shock and while they are under the ‘anesthetic’ thrusting an ice pick up between the eyeball and the eyelid through the roof of the orbit [the bony cavity that contains the eye] actually into the frontal lobe of the brain and making the lateral cut by swinging the thing from side to side. I have done two patients on both sides and another on one side without running into any complications, except a very black eye in one case. There may be trouble later on but it seemed fairly easy, although definitely a disagreeable thing to watch. It remains to be seen how these cases hold up, but so far they have shown considerable relief of their symptoms, and only some of the minor behavior difficulties that follow lobotomy. [That is, prefrontal lobotomy, which typically involved boring holes through the front of the skull. The ice pick operation is called a transorbital lobotomy.] They can even get up and go home within an hour or so. If this works out it will be a great advance for people who are too bad for shock but not bad enough for surgery.

    Freeman went around the country in the late 1940s demonstrating this technique in mental hospitals. These exhibitions reportedly went well for the most part, except on those occasions when the patient bled too much or the ice pick broke off within the orbit or inside the skull. To remedy this problem, the ice pick was later replaced with a sturdier instrument and an ordinary carpenter’s hammer was used to drive it into the brain.

    The first lobotomy in the United States took place on September 14, 1936. By August 15, 1949, the procedure had been performed 10,706 times. In the mid-1950s the popularity of the operation waned due to the availability of psychotropic drugs, which offered similar benefits without the trauma. One hopes today the practice is extinct, but you never know.

    My point in telling this story is that you’re right to regard -otomies, -ectomies and so on with some skepticism. The majority of medical professionals performing such techniques help their patients, but a few are just mopes with icepicks. The challenge is telling the two apart.

    Cecil Adams

    Send questions to Cecil via cecil@straightdope.com.

    New exponent functions that make SiLU and SoftMax 2x faster, at full accuracy

    Hacker News
    github.com
    2024-05-15 20:57:01
    Comments...
    Original Article

    📈 llama.cpp server for bench-server-baseline on Standard_NC4as_T4_v3 for phi-2-q4_0: 543 iterations 🚀

    Expand details for performance related PR only
    • Concurrent users: 8, duration: 10m
    • HTTP request : avg=8626.19ms p(95)=21696.44ms fails=, finish reason: stop=474 truncated=69
    • Prompt processing (pp): avg=94.59tk/s p(95)=412.43tk/s
    • Token generation (tg): avg=33.43tk/s p(95)=48.33tk/s
    • ggml-org/models/phi-2/ggml-model-q4_0.gguf parallel=8 ctx-size=16384 ngl=33 batch-size=2048 ubatch-size=256 pp=1024 pp+tg=2048 branch=expf commit=d7359a389c236193edac1c8761e6ac98844654f3

    prompt_tokens_seconds

    More
    ---
    config:
        xyChart:
            titleFontSize: 12
            width: 900
            height: 600
        themeVariables:
            xyChart:
                titleColor: "#000000"
    ---
    xychart-beta
        title "llama.cpp bench-server-baseline on Standard_NC4as_T4_v3
     duration=10m 543 iterations"
        y-axis "llamacpp:prompt_tokens_seconds"
        x-axis "llamacpp:prompt_tokens_seconds" 1715376005 --> 1715376631
        line [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 676.15, 676.15, 676.15, 676.15, 676.15, 693.38, 693.38, 693.38, 693.38, 693.38, 686.03, 686.03, 686.03, 686.03, 686.03, 716.71, 716.71, 716.71, 716.71, 716.71, 787.67, 787.67, 787.67, 787.67, 787.67, 798.67, 798.67, 798.67, 798.67, 798.67, 798.41, 798.41, 798.41, 798.41, 798.41, 816.18, 816.18, 816.18, 816.18, 816.18, 816.66, 816.66, 816.66, 816.66, 816.66, 826.24, 826.24, 826.24, 826.24, 826.24, 827.91, 827.91, 827.91, 827.91, 827.91, 839.83, 839.83, 839.83, 839.83, 839.83, 845.37, 845.37, 845.37, 845.37, 845.37, 891.54, 891.54, 891.54, 891.54, 891.54, 896.52, 896.52, 896.52, 896.52, 896.52, 898.39, 898.39, 898.39, 898.39, 898.39, 896.16, 896.16, 896.16, 896.16, 896.16, 909.86, 909.86, 909.86, 909.86, 909.86, 901.74, 901.74, 901.74, 901.74, 901.74, 898.93, 898.93, 898.93, 898.93, 898.93, 900.17, 900.17, 900.17, 900.17, 900.17, 901.19, 901.19, 901.19, 901.19, 901.19, 901.37, 901.37, 901.37, 901.37, 901.37, 914.57, 914.57, 914.57, 914.57, 914.57, 913.27, 913.27, 913.27, 913.27, 913.27, 914.12, 914.12, 914.12, 914.12, 914.12, 884.7, 884.7, 884.7, 884.7, 884.7, 880.58, 880.58, 880.58, 880.58, 880.58, 874.62, 874.62, 874.62, 874.62, 874.62, 874.44, 874.44, 874.44, 874.44, 874.44, 878.93, 878.93, 878.93, 878.93, 878.93, 876.59, 876.59, 876.59, 876.59, 876.59, 879.89, 879.89, 879.89, 879.89, 879.89, 889.29, 889.29, 889.29, 889.29, 889.29, 896.06, 896.06, 896.06, 896.06, 896.06, 895.27, 895.27, 895.27, 895.27, 895.27, 898.07, 898.07, 898.07, 898.07, 898.07, 895.61, 895.61, 895.61, 895.61, 895.61, 898.03, 898.03, 898.03, 898.03, 898.03, 900.02, 900.02, 900.02, 900.02, 900.02, 903.55, 903.55, 903.55, 903.55, 903.55, 912.38, 912.38, 912.38, 912.38, 912.38, 913.02, 913.02, 913.02, 913.02, 913.02, 909.18, 909.18, 909.18, 909.18, 909.18, 908.34, 908.34, 908.34, 908.34, 908.34, 904.61, 904.61, 904.61, 904.61, 904.61, 904.91, 904.91, 904.91, 904.91, 904.91, 909.01, 909.01, 909.01, 909.01, 909.01, 908.42, 908.42, 908.42, 908.42, 908.42, 913.16, 913.16, 913.16, 913.16, 913.16, 912.15, 912.15, 912.15, 912.15, 912.15, 914.4, 914.4, 914.4, 914.4, 914.4, 917.57, 917.57, 917.57, 917.57, 917.57, 915.58, 915.58, 915.58, 915.58, 915.58, 920.75, 920.75, 920.75, 920.75, 920.75, 919.24, 919.24, 919.24, 919.24, 919.24, 920.07, 920.07, 920.07, 920.07, 920.07, 918.79, 918.79, 918.79, 918.79, 918.79, 917.24, 917.24, 917.24, 917.24, 917.24, 918.44, 918.44, 918.44, 918.44, 918.44, 918.61, 918.61, 918.61, 918.61]
                        
    
    predicted_tokens_seconds
    More
    ---
    config:
        xyChart:
            titleFontSize: 12
            width: 900
            height: 600
        themeVariables:
            xyChart:
                titleColor: "#000000"
    ---
    xychart-beta
        title "llama.cpp bench-server-baseline on Standard_NC4as_T4_v3
     duration=10m 543 iterations"
        y-axis "llamacpp:predicted_tokens_seconds"
        x-axis "llamacpp:predicted_tokens_seconds" 1715376005 --> 1715376631
        line [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 41.33, 41.33, 41.33, 41.33, 41.33, 35.68, 35.68, 35.68, 35.68, 35.68, 29.47, 29.47, 29.47, 29.47, 29.47, 28.84, 28.84, 28.84, 28.84, 28.84, 30.64, 30.64, 30.64, 30.64, 30.64, 31.13, 31.13, 31.13, 31.13, 31.13, 32.39, 32.39, 32.39, 32.39, 32.39, 33.65, 33.65, 33.65, 33.65, 33.65, 33.61, 33.61, 33.61, 33.61, 33.61, 33.73, 33.73, 33.73, 33.73, 33.73, 33.4, 33.4, 33.4, 33.4, 33.4, 33.78, 33.78, 33.78, 33.78, 33.78, 33.62, 33.62, 33.62, 33.62, 33.62, 32.91, 32.91, 32.91, 32.91, 32.91, 32.27, 32.27, 32.27, 32.27, 32.27, 32.39, 32.39, 32.39, 32.39, 32.39, 32.5, 32.5, 32.5, 32.5, 32.5, 32.5, 32.5, 32.5, 32.5, 32.5, 32.07, 32.07, 32.07, 32.07, 32.07, 31.93, 31.93, 31.93, 31.93, 31.93, 31.67, 31.67, 31.67, 31.67, 31.67, 31.58, 31.58, 31.58, 31.58, 31.58, 31.79, 31.79, 31.79, 31.79, 31.79, 31.57, 31.57, 31.57, 31.57, 31.57, 31.78, 31.78, 31.78, 31.78, 31.78, 32.01, 32.01, 32.01, 32.01, 32.01, 32.02, 32.02, 32.02, 32.02, 32.02, 31.52, 31.52, 31.52, 31.52, 31.52, 31.35, 31.35, 31.35, 31.35, 31.35, 31.45, 31.45, 31.45, 31.45, 31.45, 31.65, 31.65, 31.65, 31.65, 31.65, 31.8, 31.8, 31.8, 31.8, 31.8, 32.01, 32.01, 32.01, 32.01, 32.01, 32.12, 32.12, 32.12, 32.12, 32.12, 32.05, 32.05, 32.05, 32.05, 32.05, 31.82, 31.82, 31.82, 31.82, 31.82, 31.67, 31.67, 31.67, 31.67, 31.67, 31.73, 31.73, 31.73, 31.73, 31.73, 31.87, 31.87, 31.87, 31.87, 31.87, 31.99, 31.99, 31.99, 31.99, 31.99, 32.1, 32.1, 32.1, 32.1, 32.1, 32.02, 32.02, 32.02, 32.02, 32.02, 31.97, 31.97, 31.97, 31.97, 31.97, 31.31, 31.31, 31.31, 31.31, 31.31, 30.76, 30.76, 30.76, 30.76, 30.76, 30.0, 30.0, 30.0, 30.0, 30.0, 29.71, 29.71, 29.71, 29.71, 29.71, 29.65, 29.65, 29.65, 29.65, 29.65, 29.82, 29.82, 29.82, 29.82, 29.82, 29.85, 29.85, 29.85, 29.85, 29.85, 29.95, 29.95, 29.95, 29.95, 29.95, 29.98, 29.98, 29.98, 29.98, 29.98, 30.01, 30.01, 30.01, 30.01, 30.01, 29.85, 29.85, 29.85, 29.85, 29.85, 29.78, 29.78, 29.78, 29.78, 29.78, 29.74, 29.74, 29.74, 29.74, 29.74, 29.88, 29.88, 29.88, 29.88, 29.88, 30.01, 30.01, 30.01, 30.01, 30.01, 30.1, 30.1, 30.1, 30.1, 30.1, 30.18, 30.18, 30.18, 30.18, 30.18, 30.28, 30.28, 30.28, 30.28]
                        
    
    Details

    kv_cache_usage_ratio

    More
    ---
    config:
        xyChart:
            titleFontSize: 12
            width: 900
            height: 600
        themeVariables:
            xyChart:
                titleColor: "#000000"
    ---
    xychart-beta
        title "llama.cpp bench-server-baseline on Standard_NC4as_T4_v3
     duration=10m 543 iterations"
        y-axis "llamacpp:kv_cache_usage_ratio"
        x-axis "llamacpp:kv_cache_usage_ratio" 1715376005 --> 1715376631
        line [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.24, 0.24, 0.24, 0.24, 0.24, 0.38, 0.38, 0.38, 0.38, 0.38, 0.23, 0.23, 0.23, 0.23, 0.23, 0.12, 0.12, 0.12, 0.12, 0.12, 0.21, 0.21, 0.21, 0.21, 0.21, 0.11, 0.11, 0.11, 0.11, 0.11, 0.13, 0.13, 0.13, 0.13, 0.13, 0.15, 0.15, 0.15, 0.15, 0.15, 0.18, 0.18, 0.18, 0.18, 0.18, 0.22, 0.22, 0.22, 0.22, 0.22, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.26, 0.26, 0.26, 0.26, 0.26, 0.32, 0.32, 0.32, 0.32, 0.32, 0.17, 0.17, 0.17, 0.17, 0.17, 0.17, 0.17, 0.17, 0.17, 0.17, 0.18, 0.18, 0.18, 0.18, 0.18, 0.3, 0.3, 0.3, 0.3, 0.3, 0.28, 0.28, 0.28, 0.28, 0.28, 0.32, 0.32, 0.32, 0.32, 0.32, 0.21, 0.21, 0.21, 0.21, 0.21, 0.17, 0.17, 0.17, 0.17, 0.17, 0.15, 0.15, 0.15, 0.15, 0.15, 0.14, 0.14, 0.14, 0.14, 0.14, 0.12, 0.12, 0.12, 0.12, 0.12, 0.2, 0.2, 0.2, 0.2, 0.2, 0.31, 0.31, 0.31, 0.31, 0.31, 0.23, 0.23, 0.23, 0.23, 0.23, 0.16, 0.16, 0.16, 0.16, 0.16, 0.15, 0.15, 0.15, 0.15, 0.15, 0.11, 0.11, 0.11, 0.11, 0.11, 0.13, 0.13, 0.13, 0.13, 0.13, 0.17, 0.17, 0.17, 0.17, 0.17, 0.23, 0.23, 0.23, 0.23, 0.23, 0.21, 0.21, 0.21, 0.21, 0.21, 0.19, 0.19, 0.19, 0.19, 0.19, 0.16, 0.16, 0.16, 0.16, 0.16, 0.15, 0.15, 0.15, 0.15, 0.15, 0.14, 0.14, 0.14, 0.14, 0.14, 0.09, 0.09, 0.09, 0.09, 0.09, 0.25, 0.25, 0.25, 0.25, 0.25, 0.44, 0.44, 0.44, 0.44, 0.44, 0.54, 0.54, 0.54, 0.54, 0.54, 0.62, 0.62, 0.62, 0.62, 0.62, 0.6, 0.6, 0.6, 0.6, 0.6, 0.29, 0.29, 0.29, 0.29, 0.29, 0.14, 0.14, 0.14, 0.14, 0.14, 0.15, 0.15, 0.15, 0.15, 0.15, 0.12, 0.12, 0.12, 0.12, 0.12, 0.17, 0.17, 0.17, 0.17, 0.17, 0.11, 0.11, 0.11, 0.11, 0.11, 0.17, 0.17, 0.17, 0.17, 0.17, 0.31, 0.31, 0.31, 0.31, 0.31, 0.23, 0.23, 0.23, 0.23, 0.23, 0.25, 0.25, 0.25, 0.25, 0.25, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.14, 0.14, 0.14, 0.14, 0.14, 0.11, 0.11, 0.11, 0.11, 0.11, 0.17, 0.17, 0.17, 0.17]
                        
    
    requests_processing
    More
    ---
    config:
        xyChart:
            titleFontSize: 12
            width: 900
            height: 600
        themeVariables:
            xyChart:
                titleColor: "#000000"
    ---
    xychart-beta
        title "llama.cpp bench-server-baseline on Standard_NC4as_T4_v3
     duration=10m 543 iterations"
        y-axis "llamacpp:requests_processing"
        x-axis "llamacpp:requests_processing" 1715376005 --> 1715376631
        line [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6.0, 6.0, 6.0, 6.0, 6.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 5.0, 5.0, 5.0, 5.0, 5.0, 4.0, 4.0, 4.0, 4.0, 4.0, 8.0, 8.0, 8.0, 8.0, 8.0, 6.0, 6.0, 6.0, 6.0, 6.0, 5.0, 5.0, 5.0, 5.0, 5.0, 7.0, 7.0, 7.0, 7.0, 7.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 5.0, 5.0, 5.0, 5.0, 5.0, 2.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0, 4.0, 8.0, 8.0, 8.0, 8.0, 8.0, 7.0, 7.0, 7.0, 7.0, 7.0, 4.0, 4.0, 4.0, 4.0, 4.0, 6.0, 6.0, 6.0, 6.0, 6.0, 5.0, 5.0, 5.0, 5.0, 5.0, 7.0, 7.0, 7.0, 7.0, 7.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.0, 3.0, 3.0, 3.0, 3.0, 6.0, 6.0, 6.0, 6.0, 6.0, 3.0, 3.0, 3.0, 3.0, 3.0, 8.0, 8.0, 8.0, 8.0, 8.0, 2.0, 2.0, 2.0, 2.0, 2.0, 6.0, 6.0, 6.0, 6.0, 6.0, 4.0, 4.0, 4.0, 4.0, 4.0, 2.0, 2.0, 2.0, 2.0, 2.0, 7.0, 7.0, 7.0, 7.0, 7.0, 6.0, 6.0, 6.0, 6.0, 6.0, 4.0, 4.0, 4.0, 4.0, 4.0, 8.0, 8.0, 8.0, 8.0, 8.0, 5.0, 5.0, 5.0, 5.0, 5.0, 8.0, 8.0, 8.0, 8.0, 8.0, 1.0, 1.0, 1.0, 1.0, 1.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 6.0, 6.0, 6.0, 6.0, 6.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 8.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 8.0, 8.0, 8.0, 8.0, 8.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 8.0, 8.0, 8.0, 8.0, 8.0, 6.0, 6.0, 6.0, 6.0, 6.0, 3.0, 3.0, 3.0, 3.0, 3.0, 5.0, 5.0, 5.0, 5.0, 5.0, 4.0, 4.0, 4.0, 4.0, 4.0, 2.0, 2.0, 2.0, 2.0, 2.0, 4.0, 4.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.0, 3.0, 3.0, 3.0]
                        
    

    Android 15, Google Play Protect get new anti-malware and anti-fraud features

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 20:53:51
    Today, Google announced new security features coming to Android 15 and Google Play Protect that will help block scams, fraud, and malware apps on users' devices. [...]...
    Original Article

    Android figure holding a shield

    Today, Google announced new security features coming to Android 15 and Google Play Protect that will help block scams, fraud, and malware apps on users' devices.

    Announced at Google I/O 2024, the new features are designed not only to help end users but also to warn developers when their apps have been tampered with.

    "Today, we're announcing more new fraud and scam protection features coming in Android 15 and Google Play services updates later this year to help better protect users around the world," reads a Google blog post from Dave Kleidermacher, VP Engineering, Android Security and Privacy.

    "We're also sharing new tools and policies to help developers build safer apps and keep their users safe."

    Protecting against spyware, banking malware

    Google is introducing numerous new features in Android 15 that are aimed at blocking banking trojans and spyware from stealing your information.

    Android banking trojans are used to steal users banking credentials by displaying fake login overlays, stealing MFA codes from notifications/messages, and allowing threat actors to remotely control devices.

    Over the years, researchers have illustrated how Android malware commonly steals one-time passcodes from messages and notifications. Last year, a new version of the Xenomorph Android malware took it a step further by allowing MFA codes to be stolen from Google Authenticator.

    Google has announced new security features that cause one-time passcodes to be hidden from notifications so that malware cannot steal them.

    The company is also expanding its restricted settings feature to include additional permissions that users must explicitly grant apps to prevent them from stealing data.

    Google says they are also introducing new features that protect against screen-sharing attacks conducted via social engineering.

    When Android is in screen-sharing mode, the operating system will automatically block sensitive information from appearing in notifications so that it cannot be stolen by remote threat actors.

    "During screen sharing, private notification content will be hidden, preventing remote viewers from seeing details in a user's notifications," explains Kleidermacher.

    "Apps that post OTPs in notifications will be automatically protected from remote viewers when you're screen sharing, helping thwart attempts to steal sensitive data."

    This new feature will also prevent your screen from being shown to attackers when entering credentials and credit card information during a screen-share session. A feature rolling out later this year will display more prominent indicators when screen sharing is active.

    Finally, Google is rolling out notifications alerting you when connected to an unencrypted cellular network to block Stingray attacks.

    "We'll notify you if your cellular network connection is unencrypted, potentially exposing voice and SMS traffic to radio interception, and potentially visible to others. This can help warn users if they're being targeted by criminals who are trying to intercept their traffic or inject a fraud SMS message," Kleidermacher further shared.

    "We'll help at risk-users like journalists or dissidents by alerting them if a potential false cellular base station or surveillance tool is recording their location using a device identifier."

    Unencrypted cellular network warning
    Unencrypted cellular network warning

    Bringing AI to Google Play

    Google says they are introducing a new feature called Google Play Protect live threat detection, which uses on-device artificial intelligence to detect when an Android app performs suspicious behavior.

    The app is then sent back to Google for review, and users are warned to disable it until it can be determined if it is malicious.

    Google Play Protect live threat detection
    Google Play Protect live threat detection

    For developers, Google has updated its Play Integrity API to allow developers to check if apps are running in secure environments.

    The API has now been updated to allow dev to check the following in-app signals:

    • Risk From Screen Capturing or Remote Access: Developers can check if there are other apps running that could be capturing the screen, creating overlays, or controlling the device. This is helpful for apps that want to hide sensitive information from other apps and protect users from scams.
    • Risk From Known Malware: Developers can check if Google Play Protect is active and the user device is free of known malware before performing sensitive actions or handling sensitive data. This is particularly valuable for financial and banking apps, adding another layer of security to protect user information.
    • Risk From Anomalous Devices: Developers can also opt-in to receive recent device activity to check if a device is making too many integrity checks, which could be a sign of an attack.

    Google says all these features will be rolling out to Android users via Google Play services updates and Android 15 later this year.

    Nissan North America data breach impacts over 53,000 employees

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 20:32:22
    Nissan North America (Nissan) suffered a data breach last year when a threat actor targeted the company's external VPN and shut down systems to receive a ransom. [...]...
    Original Article

    Nissan North America data breach impacts over 53,000 employees

    Nissan North America (Nissan) suffered a data breach last year when a threat actor targeted the company's external VPN and shut down systems to receive a ransom.

    The car maker discovered the breach in early November 2023 and discovered recently that the incident exposed personal data belonging to more than 53,000 current and former employees.

    “As shared during the Nissan Town Hall meeting on December 5, 2023, Nissan learned on November 7, 2023, that it was the victim of a targeted cyberattack. Upon learning of the attack, Nissan promptly notified law enforcement and began taking immediate actions to investigate, contain, and successfully terminate the threat,” the company said in a notification to impacted individuals.

    Nissan disclosed that the threat actor targeted its external VPN and then shut down certain company systems before asking for a ransom. The company notes that none of its systems were encrypted during the attack.

    Working with external cybersecurity experts, the company was able to assess the situation, contain the incident, and terminate the threat.

    The subsequent investigation revealed that the hacker had accessed some files on local and network shares that contained mostly business information.

    However, on February 28 the company "identified certain personal information in the data primarily relating to current and former NNA [Nissan] employees including Social Security numbers."

    In a data breach notification to the Office of the Maine Attorney General, the company states that the exposed details included a personal identifier (e.g. name) and social security numbers, and that financial details were not present in the files accessed by the threat actor.

    Nissan notes that it is not aware of the exposed data having been misused.

    To mitigate the risk of this data exposure, though, Nissan enclosed instructions for letter recipients on how they can enroll in a free-of-charge 24-month credit monitoring and identity theft protection service through Experian.

    Nissan has been the target of several security incidents over the past few years, which affected various divisions of the Japanese car manufacturer.

    In early December 2023, Nissan Oceania (Australia and New Zealand) announced an investigation into a cyberattack and potential data breach. In March 2024, Nissan confirmed thaat Akira ransomware had stolen data belonging to 100,000 of its customers.

    In January 2023, Nissan North America suffered an indirect breach when a third-party technology service provider exposed the data of 17,988 customers due to a poorly configured database.

    Two years before, Nissan North America left an exposed Git server repository online using default (admin/admin) credentials, exposing 20 GB of source code for internal apps and tools.

    Nissan reacted by pulling the repository offline only when it was notified by a researcher who spotted users sharing the source code via torrents.

    Brothers arrested for $25 million theft in Ethereum blockchain attack

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 19:36:46
    ​The U.S. Department of Justice has indicted two former MIT students for allegedly manipulating the Ethereum blockchain and stealing $25 million worth of cryptocurrency within approximately 12 seconds in a "first-of-its-kind" scheme. [...]...
    Original Article

    Hackers cryptocurrency

    ​The U.S. Department of Justice has indicted two former MIT students for allegedly manipulating the Ethereum blockchain and stealing $25 million worth of cryptocurrency within approximately 12 seconds in a "first-of-its-kind" scheme.

    Anton Peraire-Bueno and James Pepaire-Bueno were arrested in Boston and New York on Tuesday on charges of wire fraud and conspiracy to commit wire fraud and money laundering. If convicted, each of them faces a maximum penalty of 20 years in prison for each count.

    Their case was investigated by IRS Criminal Investigation (IRS-CI) Cyber Investigations Unit in New York, with the assistance of the New York City Police Department and U.S. Customs and Border Protection.

    "The brothers, who studied computer science and math at one of the most prestigious universities in the world, allegedly used their specialized skills and education to tamper with and manipulate the protocols relied upon by millions of Ethereum users across the globe. And once they put their plan into action, their heist only took 12 seconds to complete," said U.S. Attorney Damian Williams.

    The two former Massachusetts Institute of Technology (MIT) students allegedly manipulated transaction validation processes on the blockchain by accessing pending private transactions, altering them, obtaining victims' cryptocurrency, and rejecting requests to return the stolen funds—instead, they took steps to conceal their illegal gains.

    The indictment claims the brothers learned their victims' trading behaviors while preparing the attack (starting December 2022) and took measures to hide their identities and the stolen proceeds.

    They also used multiple cryptocurrency addresses and foreign exchanges and set up shell companies. Following the attack, they moved the stolen crypto assets through a series of transactions that would obscure their source and ownership.

    While planning and executing the attack, they allegedly took the following steps, among others:

    • Establishing a series of Ethereum validators in a manner that concealed their identities through the use of shell companies, intermediary cryptocurrency addresses, foreign exchanges, and a privacy layer network;
    • Deploying a series of test transactions of "bait transactions" designed to identify particular variables most likely to attract MEV Bots that would become the victims of the Exploit (collectively the "Victim Traders");
    • Identifying and exploiting a vulnerability in the MEV-Boost relay code that caused the relay to release the full content of a proposed block prematurely;
    • Re-ordering the proposed block to the defendants' advantage;
    • And publishing the re-ordered block to the Ethereum blockchain, which resulted in the theft of approximately $25 million in cryptocurrency from the Victim Traders.

    Throughout the process, the brothers also searched online for information on carrying out the attack, concealing their involvement in the Ethereum exploit, laundering the criminal proceeds through cryptocurrency exchanges with lax verification procedures, hiring attorneys with cryptocurrency expertise, extradition procedures, and the crimes outlined in the indictment.

    "These brothers allegedly committed a first-of-its-kind manipulation of the Ethereum blockchain by fraudulently gaining access to pending transactions, altering the movement of the electronic currency, and ultimately stealing $25 million in cryptocurrency from their victims," said IRS-CI special agent Thomas Fattorusso.

    The Cybertiger Strikes Again! EFF's 8th Annual Tech Trivia Night

    Electronic Frontier Foundation
    www.eff.org
    2024-05-15 19:26:05
    Being well into spring, with the weather getting warmer, we knew it was only a matter of time till the Cybertiger awoke from his slumber. But we were prepared. Prepared to quench the Cybertiger's thirst for tech nerds to answer his obscure and fascinating minutiae of tech-related questions. But how ...
    Original Article

    Being well into spring, with the weather getting warmer, we knew it was only a matter of time till the Cybertiger awoke from his slumber. But we were prepared. Prepared to quench the Cybertiger's thirst for tech nerds to answer his obscure and fascinating minutiae of tech-related questions.

    But how did we prepare for the Cybertiger's quiz? Well, with our 8th Annual Tech Trivia Night of course! We gathered fellow digital freedom supporters to test their tech-know how, and to eat delicious tacos, churros, and special tech-themed drinks, including LimeWire, Moderated Content, and Zero Cool.

    Nine teams gathered before the Cybertiger, ready to battle for the *new* wearable first, second, and third place prizes:

    EFF's Tech Trivia Awards! An acrylic award with an image of a blue/pink tiger.

    But this year, the Cybertiger had a surprise up his sleeve! A new way to secure points had been added: bribes. Now, teams could donate to EFF to sway the judges and increase their total points to secure their lead. Still, the winner of the first-place prize was the Honesty Winner, so participants needed to be on their A-game to win!

    At the end of round two of six, team Bad @ Names and 0x41434142 were tied for first place, making a tense game! It wasn’t until the bonus question after round two, where the Cybertiger asked each team, “What prompt would you use to jailbreak the Cybertiger AI?” where the team Bad @ Names came in first place with their answer.

    By the end of round 4, Bad @ Names was still in first place, only in the lead by three points! Could they win the bonus question again? This time, each team was asked to create a ridiculous company elevator pitch that would be on the RSA expo floor. (Spoiler alert: these company ideas were indeed ridiculous!)

    After the sixth round of questions, the Cybertiger gave one last chance for teams to scheme their way to victory! The suspense built, but after some time, we got our winners... 

    In third place, AI Hallucinations with 60 total points! 

    In second place, and also winning the bribery award, 0x41434142, with 145 total points!

    In first place... Bad @ Names with 68 total points!

    EFF’s sincere appreciation goes out to the many participants who joined us for a great quiz over tacos and drinks while never losing sight of EFF’s mission to drive the world towards a better digital future. Thank you to the digital freedom supporters around the world helping to ensure that EFF can continue working in the courts and on the streets to protect online privacy and free expression.

    Thanks to EFF's Luminary Organizational Members DuckDuckGo, No Starch Press, and the Hering Foundation for their year-round support of EFF's mission. If you or your company are interested in supporting a future EFF event, or would like to learn more about Organizational Membership, please contact Tierney Hamilton.

    Learn about upcoming EFF events when you sign up for our email list, or just check out our event calendar. We hope to see you soon!

    Join EFF Lists

    Linux maintainers were infected for 2 years by SSH-dwelling backdoor (ars technica)

    Linux Weekly News
    lwn.net
    2024-05-15 19:15:01
    Ars technica looks at a a recent report on the Ebury root kit, with a focus on the 2011 compromise of kernel.org, which may have been more extensive than believed at the time. In 2014, ESET researchers said the 2011 attack likely infected kernel.org servers with a second piece of malware they ca...
    Original Article

    Ars technica looks at a a recent report on the Ebury root kit, with a focus on the 2011 compromise of kernel.org, which may have been more extensive than believed at the time.

    In 2014, ESET researchers said the 2011 attack likely infected kernel.org servers with a second piece of malware they called Ebury. The malware, the firm said, came in the form of a malicious code library that, when installed, created a backdoor in OpenSSH that provided the attackers with a remote root shell on infected hosts with no valid password required. In a little less than 22 months, starting in August 2011, Ebury spread to 25,000 servers. Besides the four belonging to the Linux Kernel Organization, the infection also touched one or more servers inside hosting facilities and an unnamed domain registrar and web hosting provider.


    (Log in to post comments)

    Apple blocked $7 billion in fraudulent App Store purchases in 4 years

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 18:42:24
    Apple's antifraud technology has blocked more than $7 billion in potentially fraudulent transactions in four years, the company states in its latest annual fraud prevention analysis. [...]...
    Original Article

    Apple blocked $7 billion in fraudulent App Store purchases in 4 years

    Apple's antifraud technology has blocked more than $7 billion in potentially fraudulent transactions in four years, the company states in its latest annual fraud prevention analysis.

    From 2020 through 2023, the company also detected more than 14 million stolen cards and blocked them from transacting on its platform along with 3.3 million accounts.

    Statistics for last year show that Apple stopped $1.8 billion in suspicious transactions, slightly less than the $2 billion blocked in 2022.

    The report also notes that Apple also prevented throughout 2023 the use of 3.5 million stolen credit cards for purchases made on its App Store and banned over 1.1 million accounts from transacting again.

    Financial

    In terms of app security and privacy policy enforcement, Apple rejected last year over 1.7 million app submissions that failed to meet App Store's standards for privacy, security, and content.

    • Among these, 248,000 were rejected for being spam, copycats, or misleading users,
    • 38,000 were rejected for containing hidden or undocumented features,
    • 375,000 were rejected for various privacy violations,
    • 47,000 were rejected for being illegitimate apps of pirate storefronts,
    • 40,000 were remove or rejected because they engaged in "bait-and-switch" tactics,
    • and 98,000 were deemed "potentially fraudulent" and were proactively blocked.

    Apps

    The App Review team, which consists of 500 experts, examined 6.9 million app submissions in 2023 and discovered violations that led to rejecting 1.7 million requests.

    Additionally, Apple last year terminated 118,000 accounts and turned down 91,000.

    Customer accounts have also been found to be fraudulent (153 million) or engaged in illegal activities (374 million), which led to blocking or deactivating them.

    Finally, out of the 1.1 billion app ratings and reviews that users submitted to the App Store in 2023, 152 million were deemed fake/fraudulent and were removed.

    Apple expressed a strong commitment to continuing and enhancing its efforts to ensure the security and integrity of the App Store, investing in security, expanding its anti-fraud initiatives, and further strengthening its secure payment technologies like Apple Pay and StoreKit.

    However, users can also take action to protect themselves from fraud. In this context, it is advisable to:

    • Only download apps from the official App Store, avoiding poorly vetted third-party app stores or shady sites.
    • Carefully read user reviews and look for signs of fraud, such as suspiciously high ratings with few detailed reviews.
    • Only use software from reputable developers who have a portfolio of trustworthy projects.
    • Pay attention to the permissions the app requests and reject unnecessary ones.
    • Regularly update your device's operating system and apps to the latest versions.
    • Remove apps you no longer need and revoke permissions for apps you're not using.

    However, despite the stringent policies for apps to be included in the App Store, some threat actors still manage to bypass the review mechanisms and plant bad apps.

    This year, there have been two high-profile cases of fake apps added to Apple's repository, one mimicking the LastPass password manager and another impersonating the Leather cryptocurrency wallet.

    Windows Quick Assist abused in Black Basta ransomware attacks

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 18:06:50
    ​Financially motivated cybercriminals abuse the Windows Quick Assist feature in social engineering attacks to deploy Black Basta ransomware payloads on victims' networks. [...]...
    Original Article

    Microsoft social engineering

    ​Financially motivated cybercriminals abuse the Windows Quick Assist feature in social engineering attacks to deploy Black Basta ransomware payloads on victims' networks.

    Microsoft has been investigating this campaign since at least mid-April 2024, and, as they observed, the threat group (tracked as Storm-1811) started their attacks by email bombing the target after subscribing their addresses to various email subscription services.

    Once their mailboxes flood with unsolicited messages, the threat actors call them while impersonating a Microsoft technical support or the attacked company's IT or help desk staff to help remediate the spam issues.

    During this voice phishing attack, the attackers trick the victims into granting them access to their Windows devices by launching the Quick Assist built-in remote control and screen-sharing tool.

    "Once the user allows access and control, the threat actor runs a scripted cURL command to download a series of batch files or ZIP files used to deliver malicious payloads," Microsoft said.

    "In several cases, Microsoft Threat Intelligence identified such activity leading to the download of Qakbot, RMM tools like ScreenConnect and NetSupport Manager, and Cobalt Strike."

    After installing their malicious tools and concluding the phone call, Storm-1811 performs domain enumeration, moves laterally through the victim's network, and deploys Black Basta ransomware using the Windows PsExec telnet-replacement tool.

    Quick Assist screen sharing prompts
    Quick Assist screen sharing prompts (Microsoft)

    Cybersecurity company Rapid7, which also spotted the attacks, says the malicious actors will use "a batch script to harvest the victim’s credentials from the command line using PowerShell."

    "The credentials are gathered under the false context of the 'update'requiring the user to log in. In most of the observed batch script variations, the credentials are immediately exfiltrated to the threat actor’s server via a Secure Copy command (SCP)," Rapid7 added.

    "In at least one other observed script variant, credentials are saved to an archive and must be manually retrieved."

    ​To block these social engineering attacks, Microsoft advises network defenders to block or uninstall Quick Assist and similar remote monitoring and management tools if they're not used and to train employees to recognize tech support scams.

    Those targeted in these attacks should only allow others to connect to their device if they contacted their IT support personnel or Microsoft Support and immediately disconnect any Quick Assist sessions if they suspect malicious intent.

    The Black Basta ransomware operation

    After the Conti cybercrime group shut down two years ago following a series of embarrassing data breaches, it broke up into multiple factions, one of which is believed to be Black Basta.

    Black Basta surfaced as a Ransomware-as-a-Service (RaaS) operation in April 2022. Since then, its affiliates have breached many high-profile victims, including German defense contractor Rheinmetall, U.K. technology outsourcing company Capita, Hyundai's European division, the Toronto Public Library, the American Dental Association, industrial automation company and government contractor ABB, Sobeys, Knauf, and Yellow Pages Canada.

    More recently, Black Basta was linked to a ransomware attack that hit U.S. healthcare giant Ascension, forcing it to divert ambulances to unaffected facilities.

    As ​CISA and the FBI revealed in a joint advisory last week, Black Basta ransomware affiliates have breached more than 500 organizations between April 2022 and May 2024, encrypting and stealing data from at least 12 out of 16 critical infrastructure sectors.

    Health-ISAC (Information Sharing and Analysis Center) also warned in a threat bulletin that the ransomware gang "has recently accelerated attacks against the healthcare sector."

    According to cybersecurity company Elliptic and cyber insurance firm Corvus Insurance research, Black Basta has collected at least $100 million in ransom payments from over 90 victims until November 2023.

    Jepsen: Datomic Pro 1.0.7075

    Hacker News
    jepsen.io
    2024-05-15 17:57:30
    Comments...
    Original Article

    Datomic is a temporal Entity-Attribute-Value OLTP database which supports non-interactive transactions on top of pluggable storage engines. It offers a variety of query mechanisms across thick and thin clients, including Datalog, graph traversal, and an ODM-style API. We evaluated Datomic Pro 1.0.7075 and found its inter-transaction safety properties appear stronger than claimed. Not only was every history Serializable, but sessions bound to a single peer appear Strong Session Serializable, and histories restricted to write transactions and reads using d/sync appear Strong Serializable. However, inside of a transaction Datomic behaves as if operations were evaluated concurrently. Depending on how one interprets those operations, this might violate three of the most widely accepted formalizations of Serializability, each of which specify serial intra-transaction semantics. It also creates the potential for invariant violations when composing transaction functions. Datomic has published a companion blog post alongside this report. This work was funded by Nubank (Nu Pagamentos S.A), and conducted in accordance with the Jepsen ethics policy.

    Background

    Datomic is a general-purpose database intended for systems of record. In many ways, Datomic is unusual. At any instant in time, the state of the database is represented by a set of [entity, attribute, value] (EAV) triples, known as datoms. Each datom declares that some entity (like a person) has a particular attribute (like a name) with a specific value (like “Vidrun”). The types and cardinality of attributes are controlled by a schema.

    Datomic is also a temporal database: it models time explicitly. Every transaction is identified by a strictly monotonic logical timestamp t, as well as a wall-clock time txInstant. Transactions can assert a datom, adding it to the database, or they can retract a datom, removing it from the database. Every datom also retains a reference to the transaction that asserted or retracted it. A full datom is therefore a five-tuple of [entity, attribute, value, transaction, asserted-or-retracted?]. The database is an ever-growing set of these tuples.1

    Users can request a snapshot state of the database at any logical or wall-clock time—right now or years in the past. They can also obtain a full view of the database’s history, allowing users to ask questions like “was there ever a time when Janelle Monáe and Cindi Mayweather were recorded in the same room together?”

    Given a state of the database, users may query it via a Datalog-style API, a declarative graph traversal API, or an ODM-style Entity datatype which allows lazy access to an entity’s associated values, including other entities.

    Datomic comes in two flavors. In this report we discuss Datomic Pro, which anyone can run on their own computers. Datomic Cloud runs in AWS and uses a somewhat different architecture.

    Architecture

    Datomic Pro comprises several co-operating services. Transactors execute write transactions, maintain indices, and write data to storage. Peers are thick clients: they embed a JVM library which submits transactions to transactors, executes read queries against storage, and caches results. For applications written in other languages, Datomic also has a traditional client-server model. Clients are thin clients which forward transactions and queries to a peer server: a peer which runs a small network API.

    Internally, Datomic appends each transaction to the log: a time-ordered set of transactions. From the log Datomic maintains four indices sorted by different permutations of entity, attribute, value, and time. These indices allow efficient queries like “which entities were modified yesterday,” or “who run the world?”2

    Both log and indices are stored as persistent, immutable trees in a data store like Cassandra or DynamoDB. Because tree nodes are immutable, their backing storage only needs to guarantee eventual consistency. A small pointer to the roots of these trees provides a consistent, immutable snapshot of the database’s state. To commit a transaction, a transactor saves new immutable tree nodes to storage, then executes a compare-and-set (CaS) operation to advance the root pointer. This CaS operation must execute under Sequential consistency.

    Using a Sequential CaS operation ensures a global order of transactions, and limits Datomic’s write throughput to the speed of a single transactor. To reduce contention, Datomic tries to have a single active transactor at all times. Operators typically deploy multiple transactors for fault tolerance.

    Peers connect directly to storage, and also to transactors. Transactions are forwarded to an active transactor, which executes them. Each peer also maintains a local, monotonically-advancing copy of the root pointer, which allows the peer to read tree nodes from storage. Since tree nodes are immutable, they can be trivially cached. There may be any number of peers, allowing near-linear read scalability.

    Transaction Model

    Datomic has an unusual transaction model. Most OLTP databases offer interactive transactions: one begins a transaction, submits an operation, receives results from that operation, submits another, and so on before finally committing. Some databases, like VoltDB, use stored procedures: an operator writes a small program which is installed in the database. Clients invoke that program by name, which mutates database state and returns values to the client. Other databases like FaunaDB allow clients to directly submit miniature programs as text or an abstract syntax tree. Like stored procedures, these programs perform arbitrary reads and writes, mutate state, and return data to the user.

    Datomic does something rather different. It enforces a strict separation between read and write paths. There are no interactive transactions. It has stored procedures, but they cannot return values to the caller.

    A read obtains an immutable state of the entire database. For instance, the db function returns the most recent database state3 the peer is aware of. To obtain the most recent state across all peers, or a state later than a given time, one calls d/sync. To obtain a state from a past time (seconds or years ago), one calls d/as-of. These states are cheap, highly cacheable, and never block other writers or readers.

    Given a database state, one can run any number of queries using (e.g.) q or pull. Queries lazily fetch datoms from cache or storage. Since database states are immutable, any number of queries run against the same state occur at the exact same logical time. In this sense, all queries run on the same state take place in a single atomic transaction—even two queries executed on different machines, months apart.

    Write transactions4 are represented as an ordered list of operations.5

    A transaction is simply a list of lists and/or maps, each of which is a statement in the transaction.

    For example, here is a transaction of three operations, all involving entity 123:

    [[:db/add 123 :person/name "N. K. Jemisin"]
     [:db/cas 123 :author/hugo-count 2 3]]
     [:author/add-book 123 "The Stone Sky"]]

    Those operations may be simple assertions (:db/add) or retractions (:db/retract) of datoms, or they may be calls to transaction functions: either built-in or user-defined. In this example, the built-in db/cas function performs a CaS operation, asserting the number of Hugo awards for this author is 3 if and only if that number is currently 2. One can also store a function (represented as a Clojure AST or Java string) in the database just like any other value. Alternatively, one may write a function in any JVM language, and provide it in a jar file on the transactor’s classpath. Once a function has been installed, any transaction may invoke it by providing the function’s name and arguments. Here, the author/add-book function receives the state of the database as of the start of the transaction, as well as any arguments from the transaction. It can perform arbitrary (pure) computation, including running queries against the database state. It then returns a new set of operations for the transaction—for instance, assertions, retractions, or calls to other functions. Function calls are recursively expanded until only assertions and retractions remain.

    While transaction functions can make decisions based on the results of reads they perform internally, there is no channel to return those reads (or other information) to the caller of transact. Transactions only return effects. This means there is no direct analogue for an arbitrary read-write transaction in Datomic! For example, you can write a function which performs a conditional write,6 but you can’t inform the caller whether the write took place or not. This constraint nudges Datomic users towards pulling reads out of the write transaction path—a key factor in obtaining good performance from a system which can logically execute only one write transaction at a time.

    Instead of offering arbitrary return values from transactions, every call to transact returns the database state just before the transaction, the database state the transaction produced, and the set of datoms the transaction expanded to. This allows callers to execute read-write transactions by splitting them in twain: they submit a transaction which performs some writes, then use the pre-state of the database to determine what data that transaction would have read. Peers can also examine the post-state and set of datoms produced by the transaction to (e.g.) determine whether a conditional write took place.

    From the perspective of traditional database systems, this sounds absurd. Mixed read-write transactions are a staple of OLTP workloads—how could you get anything done without them? Datomic offers a view of an alternate universe: one where database snapshots are cheap, efficient, and can be passed from node to node with just a timestamp. From this point of view, other databases feel impoverished. What do you mean, Postgres can’t give you the state of the entire database a transaction observed? The lack of a return channel for transaction functions may be annoying, but Datomic’s other strengths generally allow it to solve the same kinds of problems as a traditional, interactive transaction system. For example, NuBank (Datomic’s current developers) offers financial services to nearly 94 million users, processing an average of 2.3 billion user transactions per day. Almost all of their products use Datomic as a system of record.

    Consistency

    Datomic advertises ACID transactions and means it: their ACID documentation makes detailed, specific promises with respect to consistency models and durability guarantees. Transactions are “written to storage in a single atomic write,” which precludes intermediate read anomalies. Every peer “sees completed transactions as of a particular point in time,” and observes all transactions, totally ordered, up to that time. Transactions are always flushed to durable storage before client acknowledgement.

    When our analysis began in early January 2024, Datomic’s documentation informally claimed write transactions were Serializable:

    The Isolation property ensures that concurrent transactions result in the same system state that would result if the transactions were executed serially.

    Since write transactions are Serializable and execute atomically, and since read-only queries execute against committed snapshots, it seems plausible that histories of both read and write transactions should also be Serializable.7

    Serializability does not impose real-time or session ordering constraints: in a Serializable system, it is legal for a client to execute a transaction which inserts object x, then execute a second transaction which fails to observe x. While Datomic’s documentation does not make this claim, it seems plausible that Datomic’s transactor design might provide Strong Serializability over write transactions, preventing real-time anomalies.

    Since d/db returns an asynchronously updated copy of the database, we expect peers to observe stale reads. Indeed, Datomic is explicit that peer reads may not observe some recently committed transactions. However, it would be straightforward for peers to ensure that their time basis advances monotonically; if we say that every session is bound to a single peer node, we would expect to observe Strong Session Serializable histories.

    In addition to these possible realtime and session constraints, Datomic has multiple synchronization mechanisms. Clients can block until they observe a value of the database at or later than some time t. This enables clients to ensure consistency when threading state through side channels. Calling d/sync forces the client to synchronize with the transactor, preventing stale reads. We expect histories which always use d/sync to be Strict Serializable as well.

    Datomic’s documentation also described it as a “single-writer” system:

    A single thread in a single process is responsible for writing transactions. The Isolation property follows automatically from this, because there are no concurrent transactions. Transactions are always executed serially.

    This is wrong in two senses. First, Datomic is fault-tolerant: one can and should run several transactor nodes on different computers. Typically one transactor is active and the others are in standby. When a transactor’s failure detector believes there is no active transactor, it will attempt to promote itself to active. However, perfect failure detectors are impossible in asynchronous networks. There may be times when a standby transactor believes it should take over, but another active transactor is still running. This means transactions may actually execute concurrently. During this window Datomic is not a single-writer system, but a multi-writer one!

    Second, even if there were a perfect failure detector which ensured a single Datomic transactor at a time, its messages to storage could be arbitrarily delayed by the network and arrive interleaved with messages from other transactors. Thankfully this doesn’t matter: Datomic’s safety property follows directly from the Sequential consistency of the storage system’s CaS operation. Any number of concurrent transactors ought to be safe.

    Test Design

    We designed a test suite for Datomic using the Jepsen testing library. Our test installed Datomic Pro 1.0.7075 on a cluster of Debian Bookworm nodes. For storage, it provisioned a DynamoDB table in AWS. Two of the test nodes ran transactors, and the remaining nodes ran peers.

    Our peers were small Clojure programs which used the Datomic peer library. They connected to storage and transactors and exposed a small HTTP API for performing test suite operations. For each operation the test used an HTTP client to submit that operation to some peer. The peer executed that operation using the peer library, and returned a result to the client. We ran our workloads both using d/db, which may yield stale reads, and also with d/sync, which blocks but guarantees recency.

    Our test harness injected faults into both transactors and peers, including process pauses, crashes, and clock errors. We created network partitions between nodes (including both transactors and peers) and between nodes and the storage system. We also requested Datomic perform garbage collection.

    Datomic transactors kill themselves when they cannot maintain a stable connection to storage. When we ran transactors with the default 5-second timeout settings on nodes outside AWS, transactors routinely killed themselves every few minutes due to normal network fluctuations. With a 1-second timeout, even transactors running in our EC2 test environment would kill themselves roughly every 10–20 minutes. To work around this, Datomic advises that operators run their own supervisor daemons to restart transactors. We used a systemd service with Restart=on-failure.

    Our test suite included four workloads.

    List Append

    We designed an append workload for use with the Elle transaction checker. Logically, this workload operates over lists of integer elements, with each list identified by an integer primary key. Clients perform transactions comprising random operations. Each operation may read the current value of a list, or append a unique element to the end of a list. Elle then performs a broad array of checks on the history of transactions. It looks for aborted and intermediate reads, violations of internal consistency, and inconsistent orders of elements across different reads of a list. From the element orders, it infers write-write, write-read, and read-write dependencies between transactions. From the order of transactions on each logical process, and the global order of transactions, it infers per-process and real-time orders, respectively. Elle then searches for cycles in the resulting dependency graphs. Various cycles correspond to violations of different consistency models, like Strict Serializability.

    We encoded our lists in Datomic as follows. Each list was represented by a single entity with two attributes. One, append/key, served as the primary key. The other, append/elements, was a many-valued attribute which stored all the integer elements in a given list.

    Performing the writes in a transaction was straightforward: given a write, we emitted a single operation for the transaction stating that the given key now had that element: {:append/key k, :append/elements element}. To perform a read of k, we read a local cache of k’s elements. We populated that cache with an initial series of read queries, then used a small state machine to simulate internal reads.

    Note that multi-valued attributes represent an unordered set, not an ordered list. Elle’s inference uses the order of list elements to infer the serialization order of transactions. To obtain this order, we took advantage of the fact that Datomic is a temporal database: every datom includes a reference to the transaction which wrote it. When we read the elements for a given key, we also included their corresponding transactions. We then sorted the elements by transaction times, which provides exactly the order Elle needs.

    Elle’s list-append workload is designed for databases which offer mixed read-write transactions, but Datomic doesn’t have this concept. As previously mentioned, any read-write transaction can be expressed in Datomic by running the writes in a transaction function, then using the returned database state to determine what the transaction’s reads would have been. We used this technique in our workload: a single function executes the transaction, simulates internal reads, and produces side effects (for the write transaction) and completed reads (to be returned to the client). We execute this function twice: once using a stored procedure via transact, then a second time on the peer to fill in reads, using the pre-state of the database transact returned.

    List Append with CaS

    Many Datomic users use the built-in compare-and-set function db/cas to control concurrent updates to an attribute of an entity outside a transaction. For example, they might read the current DB state using d/db, read the value of a counter as 4, then increment the counter’s value using [:db/cas 123 :counter/value 4 5]. The CaS function asserts the new value 5 if and only if the current value is 4.

    Datomic guarantees transactions are always Serializable, but a user might want to express a logical “user transaction” consisting of a read followed by a separate write transaction. Since Datomic database states are always complete snapshots, and transactions are Serializable, using db/cas for every write8 allows users to build an ad hoc Snapshot Isolation over these user transactions.

    Our append-cas workload provides the same logical API as the list-append workload, but uses this CaS pattern to ensure Snapshot Isolation. Instead of multi-valued elements, we encoded each list as a single-valued, comma-separated string. We performed a read at the start of each transaction, applied reads and writes locally, maintaining a buffer of written values, then constructed a transaction of CaS operations which ensured that any values we wrote had not been modified since they were read.

    Internal

    Our two list-append workloads measured safety between transactions, but because they simulated the results of internal reads, they did not measure Datomics intra-transaction semantics. We designed an internal workload which measures internal consistency with a suite of hand-crafted transactions. For instance, we assert that the value for some attribute of an entity is 1, then 2. We assert and retract a fact in the same transaction. We assert a value, then try to CaS it to something else. We perform multiple CaS operations—trying to change 1 to 2, then 2 to 3. We create an entity, then modify it using a lookup ref. Using a transaction function, we attempt to increment a value twice, and so on.

    Grant

    To ensure that transaction functions preserved function invariants, we designed a grant workload which simulates a simple state machine using transaction functions. Grants are first created, then can either be approved or denied. We encode a grant as a single entity with three attributes: created-at, approved-at, and denied-at.

    No grant should be both approved and denied. We ensure this invariant by writing a pair of transaction functions approve and deny. Each first checks that the grant under consideration has not been approved or denied already, aborting the transaction if necessary. If the grant hasn’t been approved or denied yet, approve adds the grant’s approved-at date. Our deny function works the same way.

    Our grant workload creates a new grant in one transaction. In subsequent transactions it tries to approve and/or deny the grant. We repeat this process, exploring different combinations of functions and transaction boundaries. We check to make sure that no grant is both approved and denied.

    Results

    We found no behavior which violated Datomic’s core safety claims. Transactions appeared to execute as if they had been applied in a total order, and that order was consistent with the local order of operations on each peer. Histories restricted to just those transactions performing writes, and histories in which reads used (d/sync conn) to obtain a current copy of the database, were consistent with real-time order.

    However, we did observe unusual behavior within transactions. This intra-transaction behavior is generally consistent with Datomic’s documentation, but it represents a significant departure both from typical database behavior and the major formalisms used to model transactional isolation. We discuss those divergences here.

    Internal Consistency

    Virtually all databases and formalisms Jepsen is familiar with provide serial execution semantics within a transaction. For example, a transaction like set x = 1; read x; would print 1, rather than the value of x when the transaction started.

    Although Datomic transactions are ordered lists of operations, Datomic does not preserve this order in execution. Instead, all operations within a transaction (adds, retracts, and transaction functions) are executed as if they were concurrent with one another. Transaction functions always observe the state of the database at the beginning of the transaction. They do not observe prior assertions, retractions, or transaction functions. For example, consider these results from our internal workload. Imagine entity 123 currently has an :internal/value of 0, and we execute the following transaction:

    [[:db/cas 123 :internal/value 0 1]
     [:db/cas 123 :internal/value 0 1]]

    In a serial execution model, this transaction would fail: the first CaS would alter the value of key 123 from 0 to 1, and the second CaS would fail, since the current value was 1 and not 0. In Datomic, both CaS operations observe the initial state 0, and both succeed. They produce a pair of redundant assertions [:db/add 123 :interval/value 1], and the value of entity 123 becomes 1.

    This means that state transitions may not compose as one expects. For instance, here is a transaction function that increments the value of the entity with key k:

    (defn increment
      [db k]
      (let [{:keys [id value]} (read db k)]
        [[:db/add id :internal/value (inc value)]]))

    What value does the following transaction produce, given an entity with key "x" and value 0?

    [['internal/increment "x"]
     ['internal/increment "x"]]

    In a serial model, the result of two increments would be 2. In Datomic, it’s 1: both increment functions receive the database state from the start of the transaction. Similarly, transaction functions do not observe lexically prior assertions or retractions.

    [[:db/add id-of-x :internal/value 1]
     ['internal/increment "x"]]

    This produces a final value of 1, not 2.

    Likewise, lookup refs use the state of the database as of the start of the transaction. This means a transaction which adds an entity cannot use a lookup ref to refer to it later in that same transaction. The following transaction aborts with an Unable to resolve entity message:

    [; Create an entity with key "x"
     [:db/add "x" :internal/key "x"]
     ; And set the value of the entity with key x
     ; to 0:
     [:db/add [:internal/key "x"] :internal/value 0]]

    Many of the above transactions included multiple assertion requests with the same entity, attribute, and value. What happens if the values conflict? Imagine this transaction executes on a state where x’s value is 0.

    [[:db/add id-of-x :internal/value 2]
     ['internal/increment "x"]]

    In a database with serial intra-transaction semantics, this would produce the value 3. In Datomic, the increment observes the start-of-transaction value 0. It completes successfully, and the transaction expands to the following:

    [[:db/add id-of-x :internal/value 2]
     [:db/add id-of-x :internal/value 1]]

    If this were executed by a serial database, it would produce the value 1. But Datomic’s order-free semantics have another rule we have not yet discussed. If two assertions in the same transaction have different values for the same single-cardinality attribute of the same entity, the transaction aborts with :db.error/datoms-conflict. This transaction aborts!

    This in-transaction conflict detection mechanism likely rules out many cases where the use of transaction functions would produce surprising results. A pair of increments will silently produce a single increment, but this is only possible because they all expand to compatible [entity, attribute, value] triples. Since there are an infinite number of incompatible values, and a single compatible choice for any [entity, attribute] pair, it seems likely that users who accidentally compose transaction functions incorrectly will find their transactions fail due to conflicts, and recognize their mistake.

    This behavior may be surprising, but it is generally consistent with Datomic’s documentation. Nubank does not intend to alter this behavior, and we do not consider it a bug.

    Pseudo Write Skew

    The fact that transactions appear to execute in serial, but the operations within a transaction appear to execute concurrently, creates an apparent paradox. A set of transaction functions might be correct when executed in separate transactions, but incorrect when executed in the same transaction! While Datomic’s in-transaction conflict checker prevents conflicts on a (single-cardinality) [entity, attribute] pair, it does nothing to control concurrency of functions which produce disjoint [entity, attribute] pairs.

    We designed the grant workload to illustrate this scenario. Following the documentation’s advice that transaction functions “can atomically analyze and transform database values,” and can be used to “ensure atomic read-modify-update processing, and integrity constraints,” we wrote a pair of transaction functions approve and deny. These functions encode the two legal state transitions for a single grant.

    (defn approved?
      "Has a grant been approved?"
      [db id]
      (-> '{:find  [?t]
            :in    [$ ?id]
            :where [[?id :grant/approved-at ?t]]}
          (d/q db id)
          count
          pos?))
    
    (defn ensure-fresh
      "Throws if the given grant ID
      is approved or denied."
      [db id]
      (when (approved? db id)
        (throw+ {:type :already-approved}))
      (when (denied? db id)
        (throw+ {:type :already-denied})))
    
    (defn approve
      "Approves a grant by ID. Ensures the
      grant has not been approved or denied."
      [db id]
      (ensure-fresh db id)
      [[:db/add id :grant/approved-at (Date.)]])

    The denied? and deny functions are identical to approved? and approve, except they use the denied-at attribute; we omit them for brevity.

    By ensuring that the given grant ID is fresh (i.e. neither approved nor denied), these functions ensure an important invariant: no sequence of approve and/or deny calls can produce a grant which is both approved and denied. And indeed, Datomic’s Serializable transactions guarantee this invariant holds—so long as calls to approve and deny only ever take place in different transactions.

    However, if a single transaction happens to call both approve and deny, something very interesting occurs:

    [['grant/approve id]
     ['grant/deny id]]

    This transaction produces a grant with the following state:

    {:db/id             17592186045426,
     :grant/created-at  #inst "2024-02-01...",
     :grant/denied-at   #inst "2024-02-01...",
     :grant/approved-at #inst "2024-02-01..."}

    This grant is both approved and denied at the same time. Our invariant has been violated! Datomic’s in-transaction conflict checker did not prevent this behavior because the approve and deny functions returned assertion requests for disjoint [entity, attribute] pairs.

    If we were to draw a data dependency graph between these two functions using the language of Adya’s formalism, we’d see something like the following:

    The approve function wrote a new version of the grant’s approved-at attribute, but when deny read that attribute, it observed the previous (unborn) version from the start-of-transaction database state. This is analogous to a read-write (rw) anti-dependency edge in Adya’s Direct Serialization Graph. Symmetrically, deny wrote a new version of the grant’s denied-at attribute, but approve saw the previous unborn version of denied-at. This gives rise to a dependency cycle: each transaction function failed to observe the other’s effects.

    If these approve and deny boxes were transactions, we’d call this cycle G2-item: an isolation anomaly proscribed by Repeatable Read and Serializability. Indeed, this phenomenon is analogous to a concurrency anomaly Berenson et al called called Write Skew:

    Suppose T1 reads x and y, which are consistent with C(), and then a T2 reads x and y, writes x, and commits. Then T1 writes y. If there were a constraint between x and y, it might be violated.

    There are some similarities between the inter-transaction concurrency control of Berenson et al’s Snapshot Isolation and the intra-transaction concurrency control of Datomic’s end-of-transaction conflict checker. When the write sets (assertion requests) of two transactions (transaction functions) intersect on some object (an entity and cardinality-one attribute), the first-committer-wins principle (conflict checker) prevents concurrent execution by forcing an abort. When their write sets are disjoint, invariants preserved by two transaction functions individually may be violated by the transaction as a whole.

    Like the internal consistency findings above, this behavior may be surprising, but it is broadly consistent with Datomic’s documentation. Nubank intends to preserve Datomic’s concurrent intra-transaction semantics. We consider this expected behavior for Datomic, rather than a bug.

    Entity Predicates

    From Datomic’s point of view, the grant workload’s invariant violation is a matter of user error. Transaction functions do not execute atomically in sequence. Checking that a precondition holds in a transaction function is unsafe when some other operation in the transaction could invalidate that precondition!

    However, Datomic offers a suite of constraints for enforcing database invariants, including type, uniqueness, and arbitrary predicates on specific attributes. One of the most general constraints is an entity predicate.

    Entity predicates are functions which receive a candidate state of the database with all transaction effects applied, the ID of an entity, and return true if the transaction should be allowed to commit that state. “Entity” is something of a misnomer: these predicates have access to the entire state of the database, and can therefore enforce arbitrary global constraints, not just those scoped to a particular entity.

    We can use entity predicates to ensure grants are never approved and denied. To start, we write an entity predicate function valid-grant?.

    (defn valid-grant?
      [db eid]
      (let [{:grant/keys [approved-at denied-at]}
            (d/pull db '[:grant/approved-at
                         :grant/denied-at]
                       eid)]
       (not (and approved-at denied-at))))

    Then we add an entity spec to the schema which references that function.

    (def schema
     [...
      {:db/ident        :grant/valid?
       :db.entity/preds ['grant/valid-grant?]
       :db/doc          "Ensures the given grant
                         is not approved *and*
                         denied"}])

    Unlike other schema constraints, which are enforced for every transaction, entity specs (and their associated entity predicates) are only enforced when transactions explicitly ask for them. Datomic believes that whether or not to enforce an entity spec is a domain decision, and that this approach is more flexible than making entity specs mandatory. Therefore our transition functions assert the grant’s approved-at or denied-at attribute, then request the entity spec be enforced by adding a special request for a virtual datom, binding the attribute :db/ensure to our entity spec.

    (defn approve
      [db id]
      [[:db/add id :grant/approved-at (Date.)]
       [:db/add id :db/ensure :grant/valid?]])
    
    (defn deny
      [db id]
      [[:db/add id :grant/denied-at (Date.)]
       [:db/add id :db/ensure :grant/valid?]])

    Using this entity spec, attempts to approve and deny a grant within the same transaction throw an error, preserving our intended invariant.

    {:cognitect.anomalies/category
     :cognitect.anomalies/incorrect,
     :cognitect.anomalies/message
     "Entity 17592186045427 failed pred
      #'jepsen.datomic.peer.grant/valid-grant?
      of spec :grant/valid?",
      :db.error/pred-return false,
      :db/error :db.error/entity-pred}

    Discussion

    In our testing, Datomic’s inter-transaction semantics were consistent with Strong Session Serializability. Intra-transaction semantics appeared strictly concurrent: the operations within a transaction seemed to be executed simultaneously, and the resulting effects merged via set union. This combination satisfies a common high-level definition of Serializability: “equivalence to a serial execution of transactions.” However, it does seem to violate the definitions of Serializability in the most broadly-adopted academic formalisms for transactional isolation. Datomic argues—and Jepsen is willing to entertain—that these formalisms should not be applied to Datomic; they are fundamentally different kinds of databases.

    While some details of the documentation were inaccurate or misleading, Datomic’s inter- and intra-transaction behavior appeared consistent with its core safety claims. Indeed, we believe Datomic’s inter-transaction safety properties are stronger than promised.

    As always, we caution that Jepsen takes an experimental approach to safety verification: we can prove the presence of bugs, but not their absence. We also note that correctness errors in the storage system underlying Datomic could cause violations of Datomic’s guarantees; Datomic atop DynamoDB is only as safe as DynamoDB’s compare-and-set operation.

    Inter-Transaction Semantics

    If one considers a session as being bound to a single peer, Datomic appears to guarantee Strong Session Serializability. Histories of transactions appear indistinguishable from one in which those transactions had executed in some total order, and that order is consistent with the order observed on each peer.

    Histories restricted to write transactions (i.e. calls to d/transact) appear Strict Serializable. So too do histories where readers use d/sync to obtain an up-to-date state of the database rather than d/db, which could be stale.

    Intra-Transaction Semantics

    Most transactional systems provide serial semantics within a single transaction.9 Each operation—writes, reads, procedure calls, etc.—within a transaction appears to take place after the previous operation in that same transaction. This property is explicitly encoded in the major formalisms for transactional isolation. Adya, Liskov, and O’Neil begin their database model by defining transactions as ordered, and explicitly specify later operations observe earlier ones:

    Each transaction reads and writes objects and indicates a total order in which these operations occur….

    If an event wi(xi.m) is followed by ri(xj) without an intervening event wi(xi.n) in E, xj must be xi.m. This condition ensures that if a transaction modifies object x and later reads x, it will observe its last update to x.

    Similarly, the abstract execution formalism of Cerone, Bernardi, and Gotsman defines an internal consistency axiom preserved by all consistency models from Read Atomic through Serializable:

    The internal consistency axiom ensures that, within a transaction, the database provides sequential semantics: a read from an object returns the same value as the last write to or read from this object in the transaction. In particular, guarantees that, if a transaction writes to an object and then reads the object, then it will observe its last write.

    Crooks, Alvisi, Pu, and Clement’s client-centric formalism similarly specifies transactions include a total order, and uses that order to ensure reads observe the most recent write to that object within the current transaction:

    Further, once an operation in T writes v to k, we require all subsequent operations in T that read k to return v.

    Even as far back as 1979, Kung and Papadimitriou defined transactions as a finite sequence of transaction steps. “Thus, our transactions are straight-line programs,” they explain.

    In all of these models, a Serializable system behaves equivalently to one which begins with an initial database state db0, picks some transaction T, applies the first operation in T producing an intermediate database state db0, applies the second operation in T to db0 producing db0, and so on until the transaction has completed, producing a committed database state db1. Then it moves to a second transaction, and the process continues.

    Datomic’s semantics are quite different. As previously discussed, the operations within a transaction (assertions, retractions, transaction functions, etc.) are evaluated logically concurrent with one another. Every transaction function in a transaction T observes the state of the database when T began, and produces a new set of operations. They do not observe the other assertions, retractions, or functions in T. These operations are recursively evaluated until only assertions and retractions remain. Those assertions and retractions are merged with set union, checked for conflicts (e.g. contradictory assertions about the value of a single-cardinality attribute on some entity), and then applied to the database state to produce a new, committed version of the database.

    This behavior may be surprising to users familiar with other databases, but it is (to some extent) documented. The lookup ref documentation explains that refs use the before-transaction database state. The database functions documentation says the transaction processor calls transactions “in turn”, which hints at ordered execution, but explicitly notes that functions are passed “the value of the db (currently, as of the beginning of the transaction).” On the other hand, that same documentation goes on to say that “[t]ransaction functions are serialized by design,” which is true between transactions, but not within them.

    Datomic’s concurrent semantics yield advantages and drawbacks. For one, a common axiom of database systems is that committed database state is always consistent, in the business-rules sense. Read Committed and above proscribe phenomenon G1b (intermediate read) in which one transaction sees intermediate state from another transaction. Datomic goes one step further: it is impossible to observe your own transaction’s intermediate state. One can never10 produce or observe an inconsistent view of the system—full stop! In some sense, the concept of intermediate state is inherently confusing; Datomic does away with it altogether. This choice also simplifies Datomic’s model of time: everything in a transaction happens “at once”, and every datom is always associated with a single, totally-ordered time.

    On the other hand, Datomic’s model reintroduces one of the problems Serializability has long been used to prevent. As Papadimitriou’s 1979 paper The Serializability of Concurrent Database Updates11 concisely argues:

    Another way of viewing serializability is as a tool for ensuring system correctness. If each user transaction is correct—i.e., when run by itself, it is guaranteed to map consistent states of the database to consistent states—and transactions are guaranteed to be intermingled in a serializable way, then the overall system is also correct.

    It seems plausible that users would want to write transaction functions that transform data while preserving some kind of correctness invariant. Datomic’s transaction functions documentation originally suggested as much:

    Transaction functions run on the transactor inside of transactions, and thus can atomically analyze and transform database values. You can use them to ensure atomic read-modify-update processing, and integrity constraints… A transaction function can issue queries on the db value it is passed, and can perform arbitrary logic in the programming language.

    If one writes a set of transaction functions which independently preserve some invariant—say, that a grant must never be both approved and also denied, or that the circuits in a home never exceed the capacity of the main panel—one would like to say (analogous to Serializable transactions) that any composition of these functions also preserves that invariant. But as we’ve demonstrated, within a single Datomic transaction this is not true! A transaction which calls multiple transaction functions might produce an outcome incompatible with the atomic application of those functions. It might violate integrity constraints. Paradoxically, combining two transactions into one can actually make the system less safe.

    It seems likely that Datomic’s behavior violates the major modern transaction formalisms: Cerone et al’s internal consistency axiom, Adya’s program order, Crooks et al’s in-transaction order, etc. It may be possible to contort Datomic’s model into alignment with these formalisms: say, by defining Datomic as containing only one object (the entire database), or through a non-local translation of Datomic operations to the formalism’s sequence of reads and writes, in which reads are reordered to the beginning of the transaction, and writes to the end. However, these approaches strain intuition. Datomic databases obviously contain independently addressable entities and attributes. Datomic transactions are clearly made up of individual parts, those parts are written in order, and this looks very much like how other databases would express a transaction with serial semantics. Convincing users to ignore that intuition seems a challenging lift.

    An easier path might be to abandon these formalisms altogether: they are clearly not designed to apply to Datomic’s concurrent intra-transaction semantics. Instead, we could follow the classic informal definition of Serializability. The internal structure of transactions is completely opaque; all that matters is that the history of transactions is equivalent to one which executed in a serial order. Under this interpretation, Datomic does ensure Serializability, Strong Session Serializability, and so on—just with different intra-transaction rules. To avoid confusion, we carefully distinguish between inter- and intra-transaction consistency throughout this report.

    Recommendations

    We found no evidence of safety bugs in Datomic, or serious divergence between documentation and system behavior. Datomic’s concurrency architecture is refreshingly straightforward, and its transactional correctness easy to argue. Jepsen believes users can rely on Datomic’s inter-transaction Serializability.

    However, Datomic users should be aware of the concurrent execution semantics within transactions. These are specified in the documentation, but remain an unusual choice which creates the potential for subtle invariant violations. Users should be careful when calling multiple transaction functions in the same transaction. In particular, watch out for intersecting read sets and disjoint write sets. Also be aware of the possibility that multiple updates (e.g. increments) to a single value might quietly collapse to a single update.

    In practice, we believe several factors protect Datomic users against encountering anomalies. First, users often try to create a schema and use it in the same transaction, or try to use a lookup ref to refer to an entity created in the same transaction. Both of these scenarios fail, which guides users towards re-reading the documentation and internalizing Datomic’s model. Second, the in-transaction conflict checker likely prevents many of the anomalies that could arise from logically-concurrent transaction functions: if two transaction functions produce different values for a single-cardinality attribute of an entity, the transaction aborts.

    In addition, users can use attribute predicates to constrain individual values, and entity specs (which must be requested on each transaction) to constrain all attributes of a single entity, or even an entire database. However, users must take care to explicitly request the appropriate entity specs within every transaction that might require them.

    Another potential surprise: Datomic goes to great pains to ensure every database state is business-rules consistent: there are no intermediate states, every state is the product of a committed transaction, and so on. However, not all schema constraints apply to extant data. In particular, attribute predicates are only enforced on newly-added datoms, not on existing datoms.

    A small operational note: Datomic transactors kill themselves after a few minutes of not being able to talk to storage. We recommended Datomic add a retry loop to make transactors robust to network fluctuations.

    Documentation Changes

    Following our collaboration, Datomic has made extensive revisions to their documentation.

    First, we worked together to rewrite Datomic’s transaction safety documentation. It now reflects the stronger safety properties we believe Datomic actually offers: Serializability globally, monotonicity on each peer, and Strict Serializability when restricted to writes, or reads which use sync. Datomic also removed the “single-writer” argument from their safety documentation.

    Datomic’s docs now include a comprehensive explanation of transaction syntax and semantics. It covers the structure of transaction requests, the rules for expanding map forms and transaction functions, and the process of applying a transaction. Expanded documentation for transaction functions explains Datomic’s various mechanisms for ensuring consistency, how to create and invoke functions, and the behavior of built-in functions. The transaction function documentation no longer says they can be used to “atomically analyze and transform database values”, nor does it claim transaction functions can “ensure atomic read-modify-write processing”.

    Datomic used to refer to the data structure passed to d/transact as a “transaction”, and to its elements as “statements” or “operations”. Going forward, Datomic intends to refer to this structure as a “transaction request”, and to its elements as “data”. The [:db/add ...] and [:db/retract ...] forms are “assertion requests” and “retraction requests,” respectively. This helps distinguish between assertion datoms, which are [entity, attribute, value, transaction, added-or-removed?] tuples, and the incomplete [entity, attribute, value] assertion request in a transaction request.

    Datomic has also added documentation arguing for a difference between Datomic transactions and SQL-style “updating transactions.” There is also a new tech note which discusses the differences between transaction functions and entity predicates when composing transactions.

    Future Work

    Our tests did not evaluate excision or historical queries. Nor did we investigate the Datomic client library—though we believe its behavior is likely similar to the peers we designed in this test. We also limited ourselves to a single storage engine: DynamoDB. Datomic runs atop a variety of storage systems; testing others might be of interest. Finally, we have not evaluated Datomic Cloud, which uses a slightly different architecture.

    Jepsen is aware of few systems or formalisms which provide inter-transaction Serializability but intra-transaction concurrent semantics. Datomic’s behavior suggests fascinating research questions.

    First, what are Datomic transactions? Is there a sense in which they are a dual to typical database transactions? Rather than happening entirely in series, everything happens all at once. What are the advantages and drawbacks of such a “co-transaction” model? Can the drawbacks be mitigated through static analysis, runtime checks, or API extensions? And does this actually matter in practice, or are users unlikely to write transactions which could violate invariants?

    Second, are there other databases with concurrent intra-transaction semantics? Conversely, what about other temporal databases with serial intra-transaction semantics? How does Datomic’s model fit into this landscape?

    Alvaro’s Dedalus, a research project exploring temporal Datalog, comes to mind. Like Datomic, its transactions happen “all at once.” As in Datomic, this creates the apparent paradox that breaking up operations into multiple transactions can actually make them safer. Consider also Fauna, a temporal database supporting up to Strong Serializability. Like Datomic, Fauna transactions are small programs that the database evaluates, rather than an interactive session driven by a client. Unlike Datomic, Fauna’s transactions provide (what appears to be) serial execution with incremental side effects within each transaction. Are Fauna’s in-transaction temporal semantics sound? How do their models compare?

    The similarity between Datomic’s end-of-transaction conflict checker and Snapshot Isolation’s first-committer-wins rule suggests new research opportunities. How close is the relationship between Snapshot Isolation and Datomic’s in-transaction semantics, and what parts of the existing literature on Snapshot Isolation could we apply to Datomic? Can we show that within a Datomic transaction, cycles between transaction functions must always involve a pair of adjacent read-write anti-dependency edges. Clearly Datomic does not prevent the intra-transaction analogue of lost update, since it collapses multiple increments. What about Fractured Read? Does it allow something like the read-only transaction anomaly described by Fekete, O’Neil, and O’Neil? Or Long Fork? Are there analogues to other G2-item and G2 cycles, perhaps involving predicates?

    Finally, one wonders whether there might be a connection to Hellerstein & Alvaro’s CALM theorem. Could we show, for instance, that transaction functions which are logically monotonic are safe to combine in a single Datomic transaction? Datalog programs without negation are logically monotonic. Can we show that those programs are also safe under this execution model? Jepsen encourages future research.

    Jepsen wishes to thank the entire Datomic team at Nubank, and in particular Dan De Aguiar, Guilherme Baptista, Adrian Cockcroft, Stuart Halloway, Keith Harper, and Chris Redinger. Peter Alvaro offered key insights into concurrent semantics. Irene Kannyo provided invaluable editorial support. This work was funded by Nubank (Nu Pagamentos S.A), and conducted in accordance with the Jepsen ethics policy.


    1. Datomic also provides an excision mechanism which rewrites history to permanently delete datoms. This is useful for regulatory compliance or removing unwanted PII.↩︎

    2. Girls!↩︎

    3. Datomic refers to an immutable version of the database as a “value”. To avoid confusion with other kinds of values in this report, we call this a “database state”.↩︎

    4. Most systems use “transaction” to refer to a group of operations, including reads or writes, executed as a unit. Datomic uses “transaction” to refer specifically to a write transaction—i.e. a call to d/transact. However, Datomic’s reads are trivially transactional as well. We refer to both reads and writes as transactions in this work—it significantly simplifies our discussion of consistency models.↩︎

    5. At the start of our collaboration, Datomic used “statement”, “operation”, and “data” to refer to elements of a transaction. We use “operation” in this report for consistency with the database literature, and to avoid confusion with other kinds of data. Datomic intends to refer to transaction elements solely as “data” going forward.↩︎

    6. Datomic wishes to note that transaction functions (for instance, db/cas) do not actually perform writes. They produce data structures which represent requests for writes. Those writes are performed during the final stages of transaction execution. Delayed evaluation of transaction effects is a common database technique; we use the term “write” loosely with this understanding.↩︎

    7. As Fekete, O’Neil, and O’Neil point out, adding read-only transactions to a history which is otherwise Serializable can actually yield non-Serializable histories! However, this paper applies specifically to Snapshot Isolation, where two transactions may read the same state and write new values concurrently. Datomic’s design ensures transactions are atomic, in the sense that no two transactions overlap in the window between their read and write timestamps.↩︎

    8. We say “every” write for safety and clarity. In practice, users often arrange for all transactions requiring concurrency control to conflict on a single attribute of an entity. A single CaS operation on, say, a customer’s version attribute could ensure that any number of updates to that customer occur sequentially.↩︎

    9. Of course, typical Serializable databases may not actually execute operations in serial order. However, they (ought to) behave indistinguishably from a system which had. Similarly, Datomic may not execute transaction functions in parallel—but it guarantees concurrent semantics. For concision, we say “serial semantics” instead of “behavior which is indistinguishable from a serial execution,” and so on.↩︎

    10. Unless one produces new, transient database states using d/with.↩︎

    11. Intriguingly, Papadimitriou’s paper begins with transactions which perform a set of reads, then a set of writes; this formalism might be more readily applicable to Datomic transactions. Later in the paper he addresses “multistep transactions,” which are analogous to the serial formalisms discussed in this section.↩︎

    Starting emails with "BEGIN PGP MESSAGE" will fool the filter

    Hacker News
    nondeterministic.computer
    2024-05-15 17:32:08
    Comments...

    YouTube blocks videos set to Hong Kong protest anthem

    Guardian
    www.theguardian.com
    2024-05-15 16:47:45
    Court order compels Google subsidiary to block local access to 32 videos of Glory to Hong Kong, judged to be prohibited content Alphabet’s YouTube on Tuesday said it would comply with a court decision and block access inside Hong Kong to 32 video links deemed prohibited content, in what critics say ...
    Original Article

    Alphabet’s YouTube on Tuesday said it would comply with a court decision and block access inside Hong Kong to 32 video links deemed prohibited content, in what critics say is a blow to freedoms in the financial hub amid a security clampdown.

    The action follows a government application granted by Hong Kong’s court of appeal requesting the ban of a protest anthem called Glory to Hong Kong. The judges warned that dissidents seeking to incite secession could weaponize the song for use against the state.

    A spokesperson for YouTube, part of Mountain View-based Alphabet in California, said the geoblocking of videos would take effect immediately for viewers in Hong Kong.

    Eventually, links to the videos will no longer show up on Google Search in Hong Kong as the company’s systems process the changes, YouTube said. Attempts to view the song on YouTube from Hong Kong displayed the message: “This content is not available on this country domain due to a court order.”

    A Chinese foreign ministry spokesperson has said that stopping the song’s spread was necessary for Hong Kong to safeguard national security.

    In comments criticizing the court order, YouTube said the ruling would raise skepticism around the Hong Kong government’s work to foster the digital economy and reclaim its reputation as a predictable place for doing business.

    “We are disappointed by the Court’s decision but are complying with its removal order,” YouTube said in a statement, saying it shared human rights groups’ concerns that the content ban could chill free expression online. “We’ll continue to consider our options for an appeal, to promote access to information.“

    Some observers, including the US government, say the ban will further undermine Hong Kong’s international reputation as a financial hub, and raise concerns about the erosion of freedoms and its commitment to the free flow of information.

    “It is not a desirable situation from the perspective of free internet and free speech,” said George Chen, co-chair of digital practice at the Asia Group, a Washington DC-based business policy consultancy. He is also former head of public policy for Greater China at Meta.

    “Now the question is how far and how aggressive the government wants to go,” Chen added. “If you start to send platforms 100 or 1,000 links for takedown every day, this will drive platforms crazy and also make global investors more worried about Hong Kong’s free market environment. How predictable and how stable the policy environment is matters a lot to foreign investors, and Hong Kong is now at a crossroads to defend its reputation.“

    Industry groups, including the Asia Internet Coalition, which represents big tech firms like Meta, Apple and Google, have said keeping a free and open internet in Hong Kong is “fundamental” to maintaining the city’s edge.

    The Hong Kong government did not immediately respond to a request for comment.

    The action is not a worldwide first for the US technology sector or Google parent Alphabet, which has restricted items when legally required to do so. In China, it has also removed content. In 2010, Google took its search engine out of mainland China, where YouTube is not available.

    Hong Kong does not have an official anthem. Glory to Hong Kong was written in 2019 during widespread pro-democracy protests that year, becoming an unofficial alternative anthem to China’s March of the Volunteers.

    In recent years, Hong Kong officials have been sanctioned by the US government for a sweeping national security crackdown on dissent that has seen many opposition democrats jailed and liberal media outlets and civil society groups shuttered.

    The former British colony returned to Chinese rule in 1997 with a guarantee that its freedoms would be preserved under a “one country, two systems” formula.

    Wild Diamond review – French social-realist drama fuelled by TikTok energy

    Guardian
    www.theguardian.com
    2024-05-15 16:43:42
    Cannes film festivalFirst-time actor Agathe Riedinger is a wannabe influencer from the wrong side of the tracks in this forthright and fluent film Feature first-timer Agathe Riedinger is bringing the TikTok energy for this story of a wannabe Insta influencer-princess from the wrong side of the track...
    Original Article

    Feature first-timer Agathe Riedinger is bringing the TikTok energy for this story of a wannabe Insta influencer-princess from the wrong side of the tracks – but the director is also bringing some pretty old school social realism, exerting its downward gravitational pull. The result is forthright and fluent and fiercely acted by a newcomer lead who, in the time-honoured style of movies like this, is defiant, vulnerable and front and centre of almost every shot. But it also sometimes treads water in terms of narrative, running out of ideas before the end, and its final ambiguity about an ultimate success that is there to be hallucinated rather than achieved feels anticlimactic.

    Liane, played by Malou Khebizi, is a 19-year-old with a French and Italian background living in Fréjus in the south of France. She was once given up for foster care by her troubled mother but now taken back home and is now in charge of babysitting her kid sister, whom she is busily turning into a mini-me version of her own brassy, sexualised image. Liane shoplifts and sells the stolen goods – which has paid for her breast-implant surgery and she has also had her lips done. She hangs out with her friends, getting drunk, but is fastidious about how and with whom she’s having sex; she has thousands of followers on her Only-Fans-type insta (although oddly, it doesn’t occur to her to have an actual Only Fans account). Liane also has a poignantly religious sense of her own heroic martyrdom, her ill-treatment at the hands of online haters, men and her appalling mother.

    Then a miracle happens: a reality TV producer to whom she sent a raunchy video wants her to audition. Liane is surely about to ascend into the paradise of celebrity and wealth. Her icily interrogative “audition” – undressed to her underwear facing the unseen producer behind the camera – is in many ways the most interesting thing about the film. This is an authority figure (to whom Liane is unquestioningly obedient as she is to no other such figure) asking questions to which the answers have to emphasise the bad-girl image which she had to deny or suppress in front of social services, but which is as artificial and constructed as the good-girl image officialdom expects.

    After the audition, we see how Liane is now in what can only be described as the euphoric version of PTSD. She thinks she has the reality show in the bag. Everything that she sees – and which the audience sees – is just the old world, the old neighbourhood and the lame friends that she is (surely) leaving behind, all sentimentally transfigured by her imminent triumph. She is distant with a boy who loves her – because he is another foster kid and that reminds her of everything she wants to shrug off.

    But the weeks and months go by and the TV producer hasn’t called her back. Is failure her destiny? Not necessarily. Everyone knows that people like Liane do indeed get to be reality TV stars – for a while, anyway. And Liane has undoubtedly shown energy and imagination. Is there a residue of hope and possibility here, whatever happens with the audition? It’s hard to tell. The film itself can’t quite decide if Liane’s aspirations are obviously vacuous and she would be better off cultivating the quieter values of intimacy and love, or if Liane is right to want more, to aim high and use what she has.

    Then there’s an odd scene where she’s caught shoplifting and somehow escapes (we assume) from the uniformed security guards. She gatecrashes a fancy party and offers three creepy guys a private dance for a thousand euros – but gets cold feet halfway through and runs away. (Did she leave the cash behind? If not, the guys were unexpectedly gentlemanly about the whole thing.) It’s indicative of the film’s indecision about what kind of moralism to assert. At all events, Khebizi gives a heartfelt performance.

    OpenAI co-founder who had key role in attempted firing of Sam Altman departs

    Guardian
    www.theguardian.com
    2024-05-15 16:08:43
    Ilya Sutskever helped orchestrate dramatic firing and rehiring of ChatGPT maker’s CEO last year OpenAI’s co-founder and chief scientist, Ilya Sutskever, is leaving the startup at the center of today’s artificial intelligence boom. “After almost a decade, I have made the decision to leave OpenAI,” Su...
    Original Article

    OpenAI’s co-founder and chief scientist, Ilya Sutskever, is leaving the startup at the center of today’s artificial intelligence boom.

    “After almost a decade, I have made the decision to leave OpenAI,” Sutskever said in a post on X.

    Sutskever played a key role in the dramatic firing and rehiring in November last year of OpenAI’s CEO, Sam Altman. At the time, Sutskever was on the board of OpenAI and helped to orchestrate Altman’s firing. Days later, he reversed course, signing on to an employee letter demanding Altman’s return and expressing regret for his “participation in the board’s actions”.

    After Altman returned, Sutskever was removed from the board, and his position at the company became unclear. Sutskever has reportedly been absent from the company’s day-to-day operations for several months.

    “OpenAI would not be what it is without him,” Altman wrote in a message to the company, which OpenAI posted on its blog.

    Sutskever posted that he was working on a new project “that is very personally meaningful to me about which I will share details in due time”.

    Jakub Pachocki will be the company’s new chief scientist, the company said on its blog. He has previously served as OpenAI’s director of research and led the development of GPT-4 and OpenAI Five.

    Microsoft-backed OpenAI makes the popular ChatGPT chatbot, which sparked a race among the world’s largest tech companies for dominance in the emerging generative AI field.

    Sutskever’s exit comes a day after the company said at an event on Monday that it would release a new AI model called GPT-4o, capable of realistic voice conversation and able to interact across texts and images.

    Shortly after launching in late 2022, ChatGPT was called the fastest application ever to reach 100 million monthly active users, hitting the milestone in January 2023. However, worldwide traffic to ChatGPT’s website has been on a rollercoaster ride in the past year and is only now returning to its May 2023 peak, according to the analytics firm Similarweb.

    Sutskever has long been a prominent researcher in the AI field. Before founding OpenAI, he worked as a researcher at Google Brain, and was a postdoctoral researcher at Stanford, according to his personal website. He started his career working with Geoffrey Hinton, one of the so-called “godfathers of AI”.

    Put it down! Should children be allowed smartphones? - podcast

    Guardian
    www.theguardian.com
    2024-05-15 16:00:44
    Almost all children have them by the time they are 11 years old – and some get them at four. But are they ruining childhoods? Blake Montgomery reports This episode was first played on our global news podcast, Today in Focus. Conversations around if and when children should be given mobile phones hav...
    Original Article

    This episode was first played on our global news podcast, Today in Focus.

    Conversations around if and when children should be given mobile phones have being going on for years. But recently the question has been catapulted to the forefront of national debate.

    From campaigning parents to bestselling books, a movement has emerged that believes smartphones are ruining childhoods and that young people should be banned from having them. It’s not hard to come up with reasons why: they are addictive, keep children glued to screens instead of playing, can be used for online bullying and are one reason why so many children have seen pornography.

    But there are also positives: offering parents the security of knowing their children can reach them if they need help, and allowing much-needed social connections for marginalised groups. So how worried should parents be? Blake Montgomery, the Guardian’s US technology editor, looks at what the science says about children and phone usage.

    Annalisa Barbieri, who answers readers’ problems in the Guardian’s Saturday magazine, and her daughter Raffaella explain how they see this fraught debate. They tell Helen Pidd how together they navigated the pitfalls of social media and smartphones without resorting to a ban.

    Three year old girl using an iPhone, UK<br>P9JCRG Three year old girl using an iPhone, UK
    Photograph: Alex Segre/Alamy

    Support The Guardian

    The Guardian is editorially independent. And we want to keep our journalism open and accessible to all. But we increasingly need our readers to fund our work.

    Support The Guardian

    FBI seize BreachForums hacking forum used to leak stolen data

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 15:44:00
    The FBI has seized the notorious BreachForums hacking forum that leaked and sold stolen corporate data to other cybercriminals. [...]...
    Original Article

    BreachForums seizure banner

    The FBI has seized the notorious BreachForums hacking forum that leaked and sold stolen corporate data to other cybercriminals.

    The seizure occurred on Wednesday morning, soon after the site was used last week to leak data stolen from a Europol law enforcement portal.

    The website is now displaying a message stating that the FBI has taken control over it and the backend data, indicating that law enforcement seized both the site's servers and domains.

    "This website has been taken down by the FBI and DOJ with assistance from international partners," reads the seizure message.

    "We are reviewing this site's backend data. If you have information to report about cyber criminal activity on BreachForums, please contact us," continues the seizure banner.

    The seizure message also shows the two forum profile pictures of the site's administrators, Baphomet and ShinyHunters, overlaid with prison bars.

    If law enforcement has gained access to the hacking forum's backend data, as they claim, they would have email addresses, IP addresses, and private messages that could expose members and be used in law enforcement investigations.

    The FBI has also seized the site's Telegram channel and other channels owned by Baphomet, with law enforcement sending messages stating it is under their control.

    Some of the messages posted to the seized Telegram channels by law enforcement came directly from Baphomet's account, likely indicating that the threat actor was arrested and his devices are now in the hands of law enforcement.

    Seized BreachForums Telegram channel
    Seized BreachForums Telegram channel
    Source: BleepingComputer

    In a Telegram message shared with BleepingComputer, the threat actor known as IntelBroker is also claiming that Baphomet was arrested in the law enforcement operation.

    IntelBroker claiming Baphomet was arrested

    The FBI is requesting victims and individuals contact them with information about the hacking forum and its members to aid in their investigation.

    The seizure messages include ways to contact the FBI about the seizure, including an email, a Telegram account, a TOX account, and a dedicated page hosted on the FBI's Internet Crime Complaint Center (IC3).

    "The Federal Bureau of Investigation (FBI) is investigating the criminal hacking forums known as BreachForums and Raidforums," reads a dedicated subdomain on the FBI's IC3 portal.

    "From June 2023 until May 2024, BreachForums (hosted at breachforums.st/.cx/.is/.vc and run by ShinyHunters) was operating as a clear-net marketplace for cybercriminals to buy, sell, and trade contraband, including stolen access devices, means of identification, hacking tools, breached databases, and other illegal services."

    "Previously, a separate version of BreachForums (hosted at breached.vc/.to/.co and run by pompompurin) operated a similar hacking forum from March 2022 until March 2023. Raidforums (hosted at raidforums.com and run by Omnipotent) was the predecessor hacking forum to both version of BreachForums and ran from early 2015 until February 2022."

    This IC3 subdomain hosts a form that victims and other individuals can use to share information about BreachForums and its members.

    When contacted by BleepingComputer about the seizure, both the FBI and the Department of Justice declined to comment.

    The notorious BreachForums

    BreachForums was the successor of a string of hacking forums used to trade, sell, and leak stolen data, as well as sell access to corporate networks and other illegal cybercrime services.

    The first of these sites was known as RaidForums, which initially launched in 2015 and became the largest site for distributing stolen data, and was commonly used by ransomware and extortion groups.

    The site was eventually seized by law enforcement, with the police arresting the owner known as "Omnipotent".

    Soon after, one of its more active members, Pompompurin, created a new forum called 'Breached' to fill the void left behind by RaidForums.

    The site quickly grew in popularity and was used by thousands of members to brag about their cybercrime activities and to leak and sell stolen data.

    However, the site soon drew the ire of law enforcement after one of its members, IntelBroker, leaked the stolen data of D.C. Health Link, a healthcare provider for U.S. House members, their staff, and their families.

    Soon after, Breached was seized by law enforcement, and its admin, Conor Fitzpatrick (aka Pompompurin), was arrested.

    Once again, those in this cybercrime community were left without a home, so one of Breached's previous admins, known as Baphomet, teamed with ShinyHunters, a notorious seller of stolen data, to launch a new site named BreachForums.

    Like the other sites, BreachForums quickly became popular with stolen corporate data being leaked from new breaches, including those on AT&T, 23andMe, Hewlett Packard Enterprise, Home Depot, Dell, PandaBuy, and The Post Millenial.

    Today's seizure message indicates that law enforcement has had access to the site's servers, potentially for a long time, as they monitored threat actors' activities.

    However, the breach that went too far may have been the recent leak of data stolen from Europol's Platform for Experts (EPE) portal by a threat actor known as IntelBroker, forcing law enforcement to take action.

    Banco Santander warns of a data breach exposing customer info

    Bleeping Computer
    www.bleepingcomputer.com
    2024-05-15 15:11:06
    Banco Santander S.A. announced it suffered a data breach impacting customers after an unauthorized actor accessed a database hosted by one of its third-party service providers. [...]...
    Original Article

    Banco Santander warns of a data breach exposing customer info

    Banco Santander S.A. announced it suffered a data breach impacting customers after an unauthorized actor accessed a database hosted by one of its third-party service providers.

    With a strong presence in Spain, the United Kingdom, Brazil, Mexico, and the United States, Banco Santander is one of the largest and most significant banks in the world, known for a diverse range of financial products and services, serving over 140 million customers.

    In a statement published this week, the bank disclosed a data breach incident that has impacted customers and employees in Spain, Chile, and Uruguay.

    “We recently became aware of an unauthorized access to a Santander database hosted by a third-party provider,” reads the statement [PDF].

    The organization said that it took immediate action to contain the incident and block the compromised access to the database. The bank also implemented additional fraud prevention controls to protect affected customers.

    “Following an investigation, we have now confirmed that certain information relating to customers of Santander Chile, Spain, and Uruguay, as well as all current and some former Santander employees of the group, had been accessed” - Banco Santander

    The bank did not disclose any details about the types of data exposed but noted that transaction information or online banking account credentials were not impacted.

    The financial organization stated that all other markets where Santander has a presence remain unaffected by the incident.

    Also, it has been asserted that the bank’s systems and operations in the mentioned countries remain unaffected, so customers may continue to use all services without fear.

    The bank will notify customers and employees directly impacted by the data exposure as well as law enforcement authorities.

    BleepingComputer has contacted Banco Santander requesting information about the third-party service provider, the number of impacted customers, and the type of exposed data but a comment wasn’t immediately available.

    Firefox 126.0 released

    Linux Weekly News
    lwn.net
    2024-05-15 15:03:57
    Version 126.0 of the Firefox browser is out. Changes include improvements to the "copy link without site tracking" feature, support for zstd compression, and a new tracking "feature": "Telemetry was added to create an aggregate count of searches by category to broadly inform search feature developm...
    Original Article

    [Posted May 15, 2024 by corbet]

    Version 126.0 of the Firefox browser is out. Changes include improvements to the "copy link without site tracking" feature, support for zstd compression, and a new tracking "feature": "Telemetry was added to create an aggregate count of searches by category to broadly inform search feature development."


    (Log in to post comments)

    Firefox 126.0 released

    Posted May 15, 2024 14:18 UTC (Wed) by flussence (subscriber, #85566) [Link]

    zstd?! Great, that means we can finally send these browsers images compressed with modern algorithms!

    Telemetry

    Posted May 15, 2024 16:02 UTC (Wed) by coriordan (guest, #7544) [Link]

    I'm surprised. Here's their page with info:

    https://blog.mozilla.org/en/products/firefox/firefox-sear...

    The justification is to help them "continue developing features and products that resonate with our users" and to "provid[e] a browsing experience that is more tailored to your needs", but they don't say how this is true. What if my searches are mostly health/travel/fashion? What features does this help them develop?

    Firefox is a massively important package. One of the most important. I'd love to see a plan to make it more attractive for users. I don't see how this helps. (And I can see how it might have the opposite effect.)

    Maybe this is just poorly communicated. Anyone found any explanations?

    Telemetry

    Posted May 15, 2024 21:47 UTC (Wed) by flussence (subscriber, #85566) [Link]

    My first hunch was to click that anonymous "👤 Mozilla" author link at the top of the blog post and sift through the topics they won't publish under a real person's name; after a few more clicks it turns out they have no problem using their real names most of the time, so this situation is considered by them to be exceptional.

    And in there is a spate of recent deckchair-shuffling announcements, things like this “why we need to track you in countries where it's not outright illegal to behave the way we're doing“, and a whole lot of ingratiating, self-congratulatory LLM sales pitches and propaganda for the Pacific coast's next tab completion incident visible from space. This seems to be the trashcan for C-level “we have no idea how to run a business or even what the company we failed upwards into does, but we want everyone to validate our obsession with these fads we picked up from Linkedin” content.

    Firefox 126.0 released

    Posted May 15, 2024 16:44 UTC (Wed) by wtarreau (subscriber, #51152) [Link]

    If it could make them figure I never ever use the address bar as a search engine and only use it to type or paste addresses, they might figure I'd like to be able to disable this very annoying (for me) feature. You can't type local hostnames anymore as it triggers a search, you need to append a local domain or prepend "http://" on the line. And you must be careful when mistyping something as it immediately triggers a search. I just don't like that and have no use for that. Maybe now it's possible to disable it but I had serached several years ago and didn't find anything.

    Firefox 126.0 released

    Posted May 15, 2024 17:02 UTC (Wed) by frostsnow (subscriber, #114957) [Link]

    I thought 'keyword.enabled' to 'false' did that, but apparently not.

    It'd be nice if every option under 'about:config' linked to its corresponding (preferably embedded) documentation.

    Firefox 126.0 released

    Posted May 15, 2024 17:39 UTC (Wed) by jzb (editor, #7867) [Link]

    This support entry on the Mozilla site suggests three about:config entries to modify to turn off address bar search. I just tried it, the third option (browser.fixup.alternate.enabled) doesn't seem to exist anymore, but I changed the other two to "false" and that seems to have disabled automatic search.

    Instead if you enter a search term (e.g., "platypus") it treats it as a domain name and tries to find it. Can't guarantee that stops all the behavior you're looking to turn off, but it does seem to let you use the address bar just as an address bar.

    Firefox 126.0 released

    Posted May 15, 2024 17:42 UTC (Wed) by bobolopolis (subscriber, #119051) [Link]

    You can also add a forward slash on the end, which I find the easiest: foo/
    I agree with your point though, I'd prefer a way to keep the address and search boxes independent.

    Firefox address bar search suggestions

    Posted May 15, 2024 22:24 UTC (Wed) by djsp (subscriber, #133625) [Link]

    You can keep Firefox from sending your address bar queries to your search engine with a single configuration setting, as explained in their documentation [https://support.mozilla.org/en-US/kb/search-suggestions-f...]. I did that and Firefox at least doesn't show me any suggestions anymore.

    You can add a separate search bar with the traditional behaviour, that is, sending your queries to your search engine as you type, if you wish to have both. I did that too.

    Firefox 126.0 released

    Posted May 15, 2024 22:28 UTC (Wed) by weal (subscriber, #168153) [Link]

    At some point Firefox started using their own DNS as well, even on Debian. I couldn't figure out why some sites would always fail the first hit, and then go through on a reload, while Chrome did not do this. The failures always seemed to happen on sites that were not "aligned" with Mozilla politically.

    Obviously the Mozilla DNS is now on my list of things to turn off immediately after a new install. Everything works better without sending all my request data to Mozilla.

    Firefox 126.0 released

    Posted May 15, 2024 22:38 UTC (Wed) by josh (subscriber, #17465) [Link]

    > The failures always seemed to happen on sites that were not "aligned" with Mozilla politically.

    You are assuming malice or propagating conspiracies where none exist.

    DoH is designed to protect users, from things like ISPs spying on them, or ISPs modifying their DNS responses (e.g. serving ads on DNS lookup failures). If anything, the complaints I've seen about DoH in the past are "I want to modify DNS responses and Mozilla is thwarting me!", e.g. from nanny filters or naive DNS-based adblockers.

    It can certainly cause issues if your local DNS resolves things that global DNS doesn't, or if you want your local DNS to *prevent* resolving things that global DNS *does* resolve. But the servers Mozilla uses for DoH don't hide servers from resolution that other DNS servers resolve.

    Firefox 126.0 released

    Posted May 16, 2024 6:12 UTC (Thu) by oldtomas (guest, #72579) [Link]

    Sorry, josh -- but I think weal has a point (we can't know whether they're right, though).

    This is a pattern which is by now common in surveillance capitalism: everyone cares about your privacy, but just to avoid sharing their surplus on you with other actors.

    That's the same way a farmer cares about their cattle's health: they just don't want to share profits with other parasites.

    This is one of those cases where that crossover of Hanlon's Razor and Clarke's Third Law applies "Any sufficient advanced malice is indistinguishable from stupidity".

    Firefox 126.0 released

    Posted May 16, 2024 10:14 UTC (Thu) by paulj (subscriber, #341) [Link]

    Install tor and dnscrypt-proxy, and configure dnscrypt-proxy to resolve via open DoH hosts over Tor. Configure your system to use 127.1 for DNS (whether that's by NetworkManager, systemd resolvectl or whatever).

    Having your browser switch your DNS from your (often country specific) ISP to a US corporate that - directly or indirectly - is invested in harvesting user search data at scale to sell to other businesses is NOT an improvement.

    Firefox 126.0 released

    Posted May 16, 2024 10:50 UTC (Thu) by josh (subscriber, #17465) [Link]

    Mozilla's deal with their DoH providers prohibits collecting data. I don't trust those companies in most ways, but I trust that they won't violate those agreements.

    Firefox 126.0 released

    Posted May 16, 2024 10:52 UTC (Thu) by atnot (subscriber, #124910) [Link]

    It is worth noting that those agreements are superceded by laws like the CLOUD act.
    However, of course, that applies equally to the ISP provided resolvers you would be using otherwise.

    Firefox 126.0 released

    Posted May 16, 2024 15:26 UTC (Thu) by cesarb (subscriber, #6266) [Link]

    > However, of course, that applies equally to the ISP provided resolvers you would be using otherwise.

    No, it doesn't. The CLOUD act has no power over a local Brazilian ISP. It could, however, have power over the DoH providers Firefox uses by default.

    (Which is probably one of the reasons why AFAIK Firefox does not enable DoH by default in most countries.)

    Firefox 126.0 released

    Posted May 16, 2024 11:33 UTC (Thu) by paulj (subscriber, #341) [Link]

    Is the DoH provider prohibited from collecting data? Is the DoH provider in the set of large tech companies that are invested in harvesting user data for commercial purposes?

    I.e., I did not say it was Mozilla that was the company invested in harvesting the search data. Rather, Mozilla may get paid by someone who is - even if the decision to switch to DoH to such a company is nominally not directly related to that arrangement.

    Firefox 126.0 released

    Posted May 16, 2024 11:43 UTC (Thu) by paulj (subscriber, #341) [Link]

    That is I understood your comment to mean Mozilla is prohibited from getting such data from the DoH provider. If you're saying the DoH provider is also prohibited from data gathering (as another response to you - sibling to mine - has taken), how is that enforced? Firstly, how does the DoH provider know queries are coming from agents under that agreement? Is the DoH provider offering the service on a Mozilla specific IP? Secondly, assuming there is a way for the DoH provider to distinguish the queries covered under the agreement, are there audit agreements in place to verify?

    Firefox 126.0 released

    Posted May 16, 2024 12:06 UTC (Thu) by josh (subscriber, #17465) [Link]

    The DoH provider is prohibited from collecting that data at all. Enforced by contract.

    Firefox 126.0 released

    Posted May 16, 2024 12:18 UTC (Thu) by paulj (subscriber, #341) [Link]

    Can I read the terms of that agreement?

    Firefox 126.0 released

    Posted May 16, 2024 12:19 UTC (Thu) by paulj (subscriber, #341) [Link]

    Firefox 126.0 released

    Posted May 16, 2024 9:59 UTC (Thu) by LtWorf (subscriber, #124958) [Link]

    I switch it to use mullivad dns over https because the italian government keeps being very democratic. Now there is a law that domains need to be blocked within 30 minutes of a report (no provisions for wrong reports).

    Firefox 126.0 released

    Posted May 16, 2024 11:45 UTC (Thu) by rrolls (subscriber, #151126) [Link]

    Ah yes, more Firefox telemetry.

    I'm just glad I'm on Debian and have Arkenfox set up. I'm pretty sure that that combination nukes every bit of unnecessary data collection around.

    (I can never be 100%, of course, but it's the best I've found so far. My other solution is to use Pale Moon, but there's too many sites that don't work nicely in it - entirely the fault of the site, of course, for unnecessarily requiring modern bloat.)

    [$] The state of the page in 2024

    Linux Weekly News
    lwn.net
    2024-05-15 14:34:34
    The advent of the folio structure to describe groups of pages has been one of the most fundamental transformations within the kernel in recent years. Since the folio transition affects many subsystems, it is fitting that the subject was covered at the beginning of the 2024 Linux Storage, Filesystem...
    Original Article

    The page you have tried to view (The state of the page in 2024) is currently available to LWN subscribers only.

    Reader subscriptions are a necessary way to fund the continued existence of LWN and the quality of its content.

    If you are already an LWN.net subscriber, please log in with the form below to read this content.

    Please consider subscribing to LWN. An LWN subscription provides numerous benefits, including access to restricted content and the warm feeling of knowing that you are helping to keep LWN alive.

    (Alternatively, this item will become freely available on May 23, 2024)