nuke git history with secrets and create public version

This commit is contained in:
NunoSempere 2025-10-13 21:09:34 -03:00
commit 5ee42250e3
1470 changed files with 831431 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
**/.env
.env
.old

24
README.md Normal file
View File

@ -0,0 +1,24 @@
# Sentinel's twitter tooling
This repository contains tooling to parse information from twitter accounts for [Sentinel](https://sentinel-team.org) at moderate to large scale. It is the result of significant iteration on Nuño's part, and it may not work as well if it is widely known.
The architecture is as follows:
![](./guides/architecture.png)
You may want to explore an accessible user interface [here](https://tools.sentinel-team.org/twit.html)
## Built with
- Golang
- OpenAI LLMs
- HTML
- small amounts of js
## Getting started
Go to the [frontend](https://tools.sentinel-team.org/twit.html) and ask a question to the sources we are
![](./guides/screenshot-1.png)
Alternatively, explore the view/tui/commission-jobs folder to see an example of automatically summarizing items for topics of interest.

20
ROADMAP.md Normal file
View File

@ -0,0 +1,20 @@
# v2. Improve and make useful
- Improve and make valuable
- [x] Easily fetch tweets in the last XYZ (day, week)
- [ ] Parse AI accounts; offer as small service
- [ ] Make list
- [ ] Offer as a service to **Misha**
- [ ] Provide to Society Library & others
- [ ] Incorporate into news prospector
- [ ] Add retweets?
- [x] Host on server
# v1. Pay technical debt down
- [x] Refactor to pay technical debt for faster future iteration
- [x] Extract analyze pipeline
- [x] Extract client
- [x] Extract backend
- [x] Add way to easily send additional account for backend to continuously fetch
- [ ] Add command line tool

247
frontend/html/twit.html Normal file
View File

@ -0,0 +1,247 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Twitter API Interface - Sentinel Team</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
<header>
<h1>Twitter API Interface</h1>
<p>Interface for managing Twitter accounts and retrieving tweets</p>
<p><small>API Server: <a href="https://tweets.nunosempere.com" target="_blank">https://tweets.nunosempere.com</a></small></p>
</header>
<main>
<section class="tool-section">
<h2>Health Check</h2>
<p>Check if the Twitter API server is running:</p>
<button id="health-check" class="primary-btn">Check Server Health</button>
<div id="health-result" class="results-container"></div>
</section>
<section class="tool-section">
<h2>Account Management</h2>
<p>Add or view monitored accounts from the database.</p>
<div class="account-subsection">
<h3>Add Account</h3>
<p style="font-size: 15px">To add many at once, consider downloading the list of people you follow. (More &gt; Settings and Privacy &gt; Your account &gt; Download an archive of your data)</p>
<div class="input-group">
<label for="add-username">Twitter Username:</label>
<input type="text" id="add-username" placeholder="elonmusk" aria-label="Twitter username to add">
</div>
<div style="margin-bottom: 20px;">
<button id="add-account" class="primary-btn">Add Account</button>
</div>
<div id="account-result" class="results-container"></div>
</div>
<div class="account-subsection">
<h3>Bulk Import Accounts</h3>
<p>Add multiple accounts at once. Enter one username per line. An extension like <a href="https://chromewebstore.google.com/detail/twlistexport-export-twitt/goplibopdcpikpipdlfeelhjnieeaeia?hl=en">this one</a> to export twitter lists might be useful to you here.</p>
<div class="input-group">
<label for="bulk-usernames">Twitter Usernames (one per line):</label>
<textarea id="bulk-usernames" rows="6" placeholder="elonmusk&#10;OpenAI&#10;AnthropicAI&#10;username4" aria-label="Multiple usernames to add" style="resize: vertical;"></textarea>
</div>
<div style="margin-bottom: 20px;">
<button id="bulk-add-accounts" class="primary-btn">Add All Accounts</button>
</div>
<div id="bulk-result" class="results-container"></div>
</div>
<div class="account-subsection">
<h3>View Monitored Accounts</h3>
<p>View all accounts currently being monitored by the system.</p>
<div style="margin-bottom: 20px;">
<button id="show-accounts" class="secondary-btn">Show Monitored Accounts</button>
<button id="hide-accounts" class="secondary-btn" style="display: none;">Hide Accounts</button>
</div>
<div id="monitored-accounts-result" class="results-container"></div>
</div>
</section>
<section class="tool-section">
<h2>List Management</h2>
<p>View and create lists for organizing monitored accounts.</p>
<div class="account-subsection">
<h3>View All Lists</h3>
<p>View all lists currently in the system.</p>
<div style="margin-bottom: 20px;">
<button id="show-lists" class="secondary-btn">Show All Lists</button>
<button id="hide-lists" class="secondary-btn" style="display: none;">Hide Lists</button>
</div>
<div id="lists-result" class="results-container"></div>
</div>
<div class="account-subsection">
<h3>Create New List</h3>
<p>Create a new list from existing monitored accounts.</p>
<div class="input-group">
<label for="new-list-name">List Name:</label>
<input type="text" id="new-list-name" placeholder="freight" aria-label="New list name">
</div>
<div class="input-group">
<label for="list-usernames">Usernames for List (one per line):</label>
<textarea id="list-usernames" rows="6" placeholder="typesfast&#10;FreightAlley&#10;FreightWaves&#10;FreightGuy11&#10;SpencerHakimian" aria-label="Usernames to add to list" style="resize: vertical;"></textarea>
</div>
<div style="margin-bottom: 20px;">
<button id="create-list" class="primary-btn">Create List</button>
</div>
<div id="create-list-result" class="results-container"></div>
</div>
<div class="account-subsection">
<h3>Edit Existing List</h3>
<p style="color: #d32f2f; font-weight: bold;">⚠️ WARNING: This operation is destructive and will completely replace the existing list contents.</p>
<p style="font-size: 15px;">Before editing, you can copy the current list items from the "View All Lists" section above using the "Copy List" button.</p>
<div class="input-group">
<label for="edit-list-name">List Name to Edit:</label>
<input type="text" id="edit-list-name" placeholder="existing-list-name" aria-label="Name of list to edit">
</div>
<div class="input-group">
<label for="edit-list-usernames">New Usernames for List (one per line):</label>
<textarea id="edit-list-usernames" rows="6" placeholder="username1&#10;username2&#10;username3" aria-label="New usernames to replace in list" style="resize: vertical;"></textarea>
</div>
<div class="input-group">
<label for="edit-list-password">Password:</label>
<input type="password" id="edit-list-password" placeholder="Required for editing lists" aria-label="Password for editing lists">
</div>
<div style="margin-bottom: 20px;">
<button id="edit-list" class="primary-btn">Edit List</button>
</div>
<div id="edit-list-result" class="results-container"></div>
</div>
</section>
<section class="tool-section">
<h2>Tweet Retrieval</h2>
<p>Retrieve tweets from monitored accounts or specific users.</p>
<div class="account-subsection">
<h3>Get Tweets from All Accounts</h3>
<p>Retrieve tweets from all monitored accounts with optional list filtering:</p>
<div class="input-grid">
<div class="input-group">
<label for="tweets-list">List Name:</label>
<input type="text" id="tweets-list" placeholder="whitehouse" aria-label="Filter by list name">
</div>
<div class="input-group">
<label for="tweets-limit">Limit (max 1000):</label>
<input type="number" id="tweets-limit" value="1000" min="1" max="1000" aria-label="Number of tweets to retrieve">
</div>
</div>
<div style="margin-bottom: 20px;">
<button id="get-all-tweets" class="primary-btn">Get All Tweets</button>
<button id="hide-all-tweets" class="secondary-btn" style="display: none; margin-left: 10px;">Hide Results</button>
</div>
<div id="tweets-result" class="results-container"></div>
</div>
<div class="account-subsection">
<h3>Get User Tweets</h3>
<p>Retrieve tweets from a specific user:</p>
<div class="input-grid">
<div class="input-group">
<label for="user-tweets-username">Username:</label>
<input type="text" id="user-tweets-username" placeholder="elonmusk" aria-label="Username to get tweets from">
</div>
<div class="input-group">
<label for="user-tweets-limit">Limit (max 1000):</label>
<input type="number" id="user-tweets-limit" value="1000" min="1" max="1000" aria-label="Number of tweets from user">
</div>
</div>
<div style="margin-bottom: 20px;">
<button id="get-user-tweets" class="primary-btn">Get User Tweets</button>
<button id="hide-user-tweets" class="secondary-btn" style="display: none; margin-left: 10px;">Hide Results</button>
</div>
<div id="user-tweets-result" class="results-container"></div>
</div>
</section>
<section class="tool-section">
<h2>AI Tweet Filtering</h2>
<p>Filter tweets from the last seven days, using natural language questions; only the tweets for which the question answers in the positive will be shown. Provide either a list name OR specific usernames. Once started, this process will take a few minutes.</p>
<div class="input-container" style="margin-bottom: 20px;">
<label for="filter-question">Filter Question:</label>
<textarea
id="filter-question"
rows="3"
placeholder="Does this tweet discuss artificial intelligence or machine learning?"
aria-label="Question to filter tweets with"
style="width: 100%; resize: vertical;"
></textarea>
</div>
<div class="input-container" style="margin-bottom: 20px;">
<label for="summarization-question">Summarization Question:</label>
<textarea
id="summarization-question"
rows="3"
placeholder="What are the key AI developments discussed in these tweets?"
aria-label="Question for summarizing filtered tweets"
style="width: 100%; resize: vertical;"
></textarea>
</div>
<div class="input-container" style="margin-bottom: 20px;">
<label for="filter-list">List Name (optional):</label>
<input
type="text"
id="filter-list"
placeholder="whitehouse"
aria-label="Filter tweets from this list"
style="width: 100%;"
>
</div>
<div class="input-container" style="margin-bottom: 20px;">
<label for="filter-users">OR Usernames (one per line):</label>
<textarea
id="filter-users"
rows="5"
placeholder="OpenAI&#10;elonmusk&#10;AnthropicAI"
aria-label="Usernames to filter tweets from"
style="width: 100%; resize: vertical;"
></textarea>
</div>
<button id="filter-tweets" class="primary-btn">Filter Tweets</button>
<button id="hide-filter-results" class="secondary-btn" style="display: none; margin-left: 10px;">Hide Results</button>
<div id="filter-result" class="results-container"></div>
</section>
</main>
<script type="module" src="twit.js"></script>
</body>
</html>

1033
frontend/html/twit.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
Direct answer — the key economics events this week:
1) A wave of new U.S. tariff announcements from the White House that target pharmaceuticals, furniture, trucks and other goods (set to start Oct. 1) and immediate market and industry reactions. See coverage and thread of announcements [KobeissiLetter](https://x.com/KobeissiLetter/status/1971360987501482405) and related reporting on pharma reactions [WSJ](https://x.com/WSJ/status/1971695297672724933).
2) Fresh inflation and Fed policy developments: August PCE (the Feds preferred gauge) printed hotter-than-target (2.7% headline, core 2.9% reported), and a visible policy debate at the Fed between officials arguing for near-term rate cuts and others warning inflation remains stubborn. See inflation callouts [KobeissiLetter](https://x.com/KobeissiLetter/status/1971553211267096755) and discussion of Fed divergence and Mirans speech [NickTimiraos](https://x.com/NickTimiraos/status/1970156734116213055).
3) Market- and corporate-sized events: a near-term blockbuster leveraged buyout reported for Electronic Arts (around $50bn), precious metals and some commodities hitting multiyear highs (gold, silver, platinum), and important bond-market moves (Japan 10year yield at its highest since the GFC). See EA coverage [WSJ](https://x.com/WSJ/status/1971645350088745121) / [CNBC](https://x.com/CNBC/status/1971650202713911715), gold price note [elerianm](https://x.com/elerianm/status/1971603473822265610), silver [Barchart](https://x.com/Barchart/status/1971322520986059144) and Japan yields [Barchart](https://x.com/Barchart/status/1971689497390690653).
4) Elevated risk of a U.S. government shutdown and administration fiscal messaging — markets and agencies are preparing for the possibility; White House/Treasury continue to promote stronger Q2 GDP revisions and tax/cut narratives. See shutdown odds and warnings [SpencerHakimian](https://x.com/SpencerHakimian/status/1971630586281578534) / [unusual_whales](https://x.com/unusual_whales/status/1971630094566260749) and Treasury economic messaging [USTreasury](https://x.com/USTreasury/status/1971320232535875906).
Key themes and topics discussed in relation to the weeks question
- Trade policy and geoeconomic frictions: The White Houses new tariff slate (pharma 100% threat, 50% on cabinets/vanities, 30% on upholstered furniture, 25% on heavy trucks, etc.) dominated headlines and triggered immediate industry and market commentary on passthrough to prices, supply chain shifts and potential retaliatory moves. See tariff rollout context [KobeissiLetter](https://x.com/KobeissiLetter/status/1971357020705186042) and industry pushback/impact notes [WSJ](https://x.com/WSJ/status/1971695297672724933).
- Inflation vs. monetary policy: August PCE running at ~2.7% and core PCE ~2.9% renewed debate over whether the Fed should move quickly to cut rates. That debate is playing out publicly (Governor Miran arguing the neutral rate is lower; other officials and Goolsbee emphasizing the need to get inflation back to 2%). See Mirans framing [NickTimiraos](https://x.com/NickTimiraos/status/1970156734116213055) and the PCE read [KobeissiLetter](https://x.com/KobeissiLetter/status/1971553211267096755).
- Market concentration, corporate activity and asset flows: Large tech and “Mag7” concentration, record-high household allocation to equities, record flows into gold and strong metal price moves are notable. Simultaneously there is big M&A / LBO activity (EA) and private fundraising (Kraken). See concentration & flows [KobeissiLetter](https://x.com/KobeissiLetter/status/1971607948783710338), household equity allocation [Barchart](https://x.com/Barchart/status/1971633357722472813), and EA LBO [WSJ](https://x.com/WSJ/status/1971645350088745121).
- Fiscal and geopolitical spillovers: Elevated government shutdown odds and Treasury messaging on GDP and fiscal priorities; U.S. support for Argentina and potential swap lines; UN/Iran sanctions news and other geopolitically-driven market pressures. See shutdown odds [SpencerHakimian](https://x.com/SpencerHakimian/status/1971630586281578534), Treasury/Argentina support [SecScottBessent](https://x.com/SecScottBessent/status/1970821535507026177) and UN/Iran sanctions [business](https://x.com/business/status/1971661254436565215).
Notable patterns or trends relevant to the question
- Policy uncertainty rising: trade/tariff shocks plus public Fed disagreements have increased policy risk and headline volatility. The tariffs are an explicit supplyside shock that could push some prices higher while the Fed debate centers on whether policy is currently too restrictive or still needs to tighten to stamp out inflation.
- Safehaven / commodity strength: Gold and silver moved sharply higher while some yields (Japan 10year) rose — a pattern consistent with a mix of inflation concerns, currency flows and risk positioning.
- Market concentration and profittaking: Large cap concentration remains extreme (Mag7, top 10 stocks record shares of market cap) while professional investors showed net selling in recent weeks, suggesting selective repositioning underneath broad index strength.
- Fiscal/credit divergence across countries: Ratings and outlook moves (Spain positive, France negative outlook) and targeted sovereign/support actions (U.S. to support Argentina) highlight differentiated fiscal trajectories across advanced and emerging economies.
Important mentions, interactions and data points (selected)
- PCE inflation: headline 2.7%, core 2.9% (reported/discussed) — implications for Fed timing [KobeissiLetter](https://x.com/KobeissiLetter/status/1971553211267096755) and Fed commentary [elerianm](https://x.com/elerianm/status/1971563659295109240).
- Q2 GDP revision: U.S. GDP revised to ~3.8% (Treasury messaging) — used politically to argue the economy is strong [USTreasury](https://x.com/USTreasury/status/1971320232535875906).
- Tariff package: multiple headline tariffs announced with Oct. 1 start dates and sectoral winners/losers flagged (pharma, furniture, trucks, cabinets) [KobeissiLetter](https://x.com/KobeissiLetter/status/1971360987501482405).
- Market datapoints: S&P free cash flow yield hit 2.58% (lowest since GFC) [Barchart](https://x.com/Barchart/status/1971685840712802593); Japan 10year yield at highest since GFC [Barchart](https://x.com/Barchart/status/1971689497390690653); silver at multiyear highs [Barchart](https://x.com/Barchart/status/1971322520986059144); gold > $3,800 [elerianm](https://x.com/elerianm/status/1971603473822265610).
- Political / fiscal risk: Kalshi / markets put elevated odds on a U.S. government shutdown (mid60s% range reported) [SpencerHakimian](https://x.com/SpencerHakimian/status/1971310494599479338) and agencies told to prepare for mass firings if a shutdown occurs [unusual_whales](https://x.com/unusual_whales/status/1971630094566260749).
- Money supply: M2 reported up ~4.8% YoY and record levels called out by market commentators — relevant for currency and inflation narratives [KobeissiLetter](https://x.com/KobeissiLetter/status/1971301428615614546).
Significant events / announcements (each given a short paragraph):
- Trumps tariff announcements: The White House announced a broad set of tariffs (100% on some pharmaceutical products unless produced in the U.S., 50% on cabinets/vanities, 30% on upholstered furniture, 25% on heavy trucks, and others), with Oct. 1 implementation repeatedly referenced. These moves are explicitly framed as industrial policy and leverage to bring manufacturing back, but markets and affected industries warned of higher consumer prices, supplychain dislocation and retaliation risk. Industry and news outlets are already flagging nearterm winners/losers and potential policy followthrough [KobeissiLetter](https://x.com/KobeissiLetter/status/1971360987501482405) and [WSJ](https://x.com/WSJ/status/1971695297672724933).
- Inflation datapoint (PCE) and the split at the Fed: August PCE showed sticky inflation (headline ~2.7%, core ~2.9%), prompting renewed debate among Fed officials. Governor Miran publicly argued neutral rates are materially lower (pushing for earlier cuts), while other officials and commentators warned inflation remains above the 2% objective and urged caution. That reported divergence — together with political scrutiny of Fed independence — is a central macro story because it determines the timing and size of rate cuts markets have been pricing. See the PCE read [KobeissiLetter](https://x.com/KobeissiLetter/status/1971553211267096755) and debates/remarks [NickTimiraos](https://x.com/NickTimiraos/status/1970156734116213055) / [elerianm](https://x.com/elerianm/status/1971563659295109240).
- Large corporate transaction and marketstructure moves: Reports that Electronic Arts is close to a roughly $50bn takeprivate deal (would be among the largest LBOs ever) attracted market attention and triggered stock movement and wider M&A scrutiny. At the same time, tech and AI narratives (Nvidia/AI supercycle) continue to concentrate market cap at the top while some investors rotate or take profits. These developments matter for liquidity, leverage, and risk distribution in markets [WSJ](https://x.com/WSJ/status/1971645350088745121) / [CNBC](https://x.com/CNBC/status/1971650202713911715).
Other notable items (short mentions):
- Japan 10year bond yields hit postGFC highs, an important global fixedincome development [Barchart](https://x.com/Barchart/status/1971689497390690653).
- Spain received upgrades from Moodys and Fitch while France drew a negative outlook from Scope — showing divergent sovereign credit stories inside Europe [business](https://x.com/business/status/1971687362368352681) / [business](https://x.com/business/status/1971681822242181470).
- U.S. domestic politics: the shutdown risk is meaningful and could have nearterm macro and cashflow consequences; Treasury and administration continue to celebrate strong GDP and consumer numbers while pushing tax and fiscal narratives [SpencerHakimian](https://x.com/SpencerHakimian/status/1971310494599479338) / [USTreasury](https://x.com/USTreasury/status/1971320232535875906).
- Argentina and FX/sovereign stability: the U.S. Treasury signaled readiness for swap lines and support to stabilize Argentina conditional on reforms, a potentially important regional financial backstop [SecScottBessent](https://x.com/SecScottBessent/status/1970821535507026177).
Outlook / what to watch next week
- Jobs report and labor data (markets need a “goldilocks” jobs print) — market sensitivity to labor is high [CNBC](https://x.com/CNBC/status/1971654732226691214).
- Tariff implementation and industry responses leading into Oct. 1 — watch corporate announcements, investment decisions and any retaliatory steps [KobeissiLetter](https://x.com/KobeissiLetter/status/1971360987501482405).
- Continued Fedspeak and market reaction to PCE and Fed internal divisions — any further signals from Powell, Miran or other FOMC members will be marketmoving [NickTimiraos](https://x.com/NickTimiraos/status/1970156734116213055).
- Fiscal/political developments around a potential government shutdown and any Treasury moves to stabilize markets (Argentina swap lines, sanctions, etc.) [SpencerHakimian](https://x.com/SpencerHakimian/status/1971310494599479338) / [SecScottBessent](https://x.com/SecScottBessent/status/1970821535507026177).
Bottom line: this weeks economics headlines were dominated by a mix of bigpicture policy shocks (an aggressive U.S. tariff program), persistent/stubborn inflation readings that have reopened an important debate inside the Fed, and market events (major corporate deal news, commodity rallies and bondmarket moves). Those strands — trade policy, monetary policy divergence, and concentrated market activity — are likely to drive headlines and market volatility into the coming week.

View File

@ -0,0 +1,47 @@
Direct answer — state of shipping / freight / trucking this week:
The freight market is weak and showing multiple signs of deterioration: domestic truck transactions and spot demand are down materially yearoveryear, truck orders and heavytruck sales are rolling over, carriers earnings and forward guidance are being cut, and modal share is shifting toward rail. Simultaneously, policy shocks (new tariffs and rapid regulatory moves) are increasing uncertainty and appear likely to constrain capacity and investment in the near term. Key nearterm risks to peak season and Q4 include Los Angeles port performance, tariff-driven pricing uncertainty (especially for heavy trucks and selected imports), and regulatory actions that could remove drivers from the pool.
Key themes and topics this week (with notable tweets as sources):
- Demand slump and transaction decline: U.S. domestic freight transactions are down ~12% yearoveryear, signaling a sizable contraction in goods movement and demand for trucking services (see FreightAlley data on domestic freight transactions: https://x.com/FreightAlley/status/1971402054246576571).
- Modal shift to rail / intermodal resilience: Rail intermodal volumes are outperforming truckload — FreightAlley notes rail intermodal up ~1% YoY while trucking is down ~13% YoY, indicating continued market share gains for railroads (https://x.com/FreightAlley/status/1971410343974011124).
- Ports and peak season risk (Los Angeles focus): Market attention is on LA performance in October as an early signal for peak season across the U.S.; current data/coverage suggest a muted LA environment and a weaker-than-expected start to peak (https://x.com/FreightAlley/status/1971697400910958731).
- Tariffs and trade policy shocks: New tariffs announced this week (e.g., a reported 25% tariff on imported heavyduty trucks) are creating fresh uncertainty for fleets and OEMs, disrupting ordering decisions and capital planning (https://x.com/FreightWaves/status/1971596244716818907). Industry commentary highlights how late notice on tariffs can cool demand for expensive capital goods (https://x.com/FreightAlley/status/1971570804832760171).
- Regulatory moves reducing capacity: FMCSA actions restricting nondomiciled CDLs and immediate limits on eligibility are being rolled out; analysts and industry voices warn this could remove a large number of currently active drivers or reduce capacity (FMCSA announcement: https://x.com/FreightWaves/status/1971574346494669005; capacity impact note: https://x.com/FreightAlley/status/1971563477987909899).
- Equipment and OEM indicators: Heavy truck sales are rolling over and reported declines in sales volumes (e.g., a decline in annualized heavy truck sales rates), which together with tariff risk could reduce new truck orders and slow fleet replacement (RT and commentary on truck-sales weakness: https://x.com/FreightAlley/status/1970980048875422203; https://x.com/FreightAlley/status/1971457625654165662).
- Carriers financial outlook: Analysts (Susquehanna) cut earnings estimates for assetbased truckload carriers amid soft volumes, falling spot rates, and low tender rejections — signaling margin pressure ahead of earnings season (https://x.com/FreightWaves/status/1970873619489149366).
- Lastmile and postal disruptions: Canada Posts strike and subsequent operational changes (ending many doortodoor deliveries, cutting frequencies) are creating lastmile disruptions and potential lasting shifts to alternative couriers (https://x.com/FreightWaves/status/1971623579876794548; policy change: https://x.com/FreightWaves/status/1971317551654207538).
- Safety and tech regulation signals: NTSB recommendations for driver monitoring systems on trucks over 10,000 lbs. and related safety/regulatory discussion may add compliance costs or accelerate technology installation discussions (https://x.com/FreightWaves/status/1970994312771948670).
Notable patterns and trends relevant to the question:
- Demand weakness is broad-based: import indicators, truckload volumes, and domestic transaction counts are consistently pointing down, not just isolated softness. FreightWaves flagged weakening import and rail demand as a leading indicator for broader economic slowdown (https://x.com/FreightWaves/status/1971270283030864168).
- Structural rebalancing postCOVID: Several posts emphasize that the longrun distribution of freight has shifted (China → other sourcing, concentrated westcoast inbound flows) favoring intermodal and rail economics and pressuring longhaul truck volumes (FreightAlley on China/WTO impacts: https://x.com/FreightAlley/status/1971030306904854565).
- Policy and regulatory shocks are driving uncertainty: Tariffs plus FMCSA moves are not just incremental; they change capital investment calculus (truck orders), operational compliance (driver eligibility), and hiring/retention dynamics.
Important mentions, interactions, and data points to know this week:
- Domestic freight transactions: down ~12% YoY (FreightAlley) — a direct indicator of goodseconomy activity (https://x.com/FreightAlley/status/1971402054246576571).
- Trucking vs. rail YoY: trucking volumes reportedly down ~13% YoY while rail intermodal up ~1% YoY (https://x.com/FreightAlley/status/1971410343974011124).
- Potential loss of nondomiciled CDL holders: FMCSA changes could affect up to ~200,000 nondomiciled CDL holders (industry commentary, FreightAlley) and thereby materially reduce available driver capacity if enforced as described (https://x.com/FreightAlley/status/1971563477987909899; https://x.com/FreightWaves/status/1971574346494669005).
- Analyst actions: Susquehanna cut carrier earnings estimates ahead of Q3, citing soft volumes and muted peak season (https://x.com/FreightWaves/status/1970873619489149366).
- Tariff on heavy trucks: presidential announcement of broad tariffs including a 25% tariff on imported heavyduty trucks — immediate effect on OEM procurement plans, fleet ordering and cost of new units (https://x.com/FreightWaves/status/1971596244716818907).
- Containerized imports warning: forecasts that U.S. containerized imports through ports could plunge in September due to tariff effects on transPacific trade (https://x.com/FreightWaves/status/1970878854001488230).
- Lastmile disruption: Canada Post changes and strike pose immediate ecommerce delivery disruptions for shippers and small businesses (https://x.com/FreightWaves/status/1971623579876794548).
Significant events / announcements this week (each given a focused paragraph):
1) Tariffs on imported heavy trucks and other goods — policy shock with immediate consequences:
Presidentially announced tariffs (reported as including a 25% levy on imported heavyduty trucks) are reigniting trade uncertainty, disrupting OEM and fleet procurement timing, and raising the cost of new equipment just as an already weak freight market dampens demand. Industry commentators warned that late notice on highvalue capital goods (e.g., $200k+ trucks) increases hesitancy to place orders, which can further depress OEM production, usedtruck markets, and downstream services. See coverage of the tariff announcement and industry reaction here: https://x.com/FreightWaves/status/1971596244716818907 and https://x.com/FreightAlley/status/1971570804832760171.
2) FMCSA moves restricting nondomiciled CDLs — potential capacity reduction and safety/administrative impacts:
Federal action to tighten eligibility for nondomiciled Commercial Drivers Licenses was announced and immediately prompted industry concern that hundreds of thousands of drivers could lose eligibility or have certifications questioned. FreightAlley flagged the scale ("200,000 current nondomiciled CDL holders may lose eligibility") and called it one of the most significant capacityreducing moves of the year, while FreightWaves reported the FMCSA announcement and early pushback (https://x.com/FreightWaves/status/1971574346494669005; https://x.com/FreightAlley/status/1971563477987909899). If enforced broadly, this is likely to tighten capacity (lifting some rate pressure) but also raise costs, disrupt lanes, and cause shortterm allocation problems for shippers and carriers.
3) Port/import weakness and modal shifts — warning signs for broader goods demand:
Multiple reports signaled softening imports and a possible sharp decline in containerized imports through U.S. ports (a particular concern for transPacific trade lanes), while rail intermodal is holding better than truckload. FreightWaves and others highlighted import and rail demand being down YoY as an early warning for the broader economy and for Q4 freight activity (https://x.com/FreightWaves/status/1971270283030864168; https://x.com/FreightWaves/status/1970878854001488230). Combined with the domestic freight transaction decline (https://x.com/FreightAlley/status/1971402054246576571), these signals point toward a softer goods cycle rather than a temporary blip.
Bottom line / implications for stakeholders:
- Shippers: expect softer capacity and/or spot market volatility in the short run; plan for potential lastmile disruptions (Canada Post) and tariffrelated customs complexity (https://x.com/FreightWaves/status/1971623579876794548; https://x.com/FreightWaves/status/1971208565407769041).
- Carriers: margin pressure from weak volumes and lower spot rates, offset by potential shortterm tightening if driver eligibility rules remove capacity; capital investment decisions should be reevaluated in light of tariff uncertainty (https://x.com/FreightWaves/status/1970873619489149366; https://x.com/FreightAlley/status/1971570804832760171).
- Equipment OEMs / dealers: order timing risk and reduced demand for new trucks; usedtruck markets may become more important if orders are delayed (https://x.com/FreightAlley/status/1971382354200641652).
- Policymakers: regulatory and trade interventions are having large, immediate effects on freight flows and industry structure — coordinated, welltelegraphed policy would reduce market disruption.
Sources (examples from tweet activity this week): FreightAlleys market commentary and data points (e.g., domestic transaction decline, LA focus, modal share) — https://x.com/FreightAlley/status/1971402054246576571, https://x.com/FreightAlley/status/1971697400910958731, https://x.com/FreightAlley/status/1971410343974011124; FreightWaves reporting on tariffs, FMCSA action, imports, analyst notes and Canada Post — https://x.com/FreightWaves/status/1971596244716818907, https://x.com/FreightWaves/status/1971574346494669005, https://x.com/FreightWaves/status/1971270283030864168, https://x.com/FreightWaves/status/1970873619489149366, https://x.com/FreightWaves/status/1971623579876794548.
If you want, I can: (a) extract the specific SONAR charts cited (port, lane, or transaction indices) and summarize numeric trends; (b) produce a short scenario analysis (best / base / worst) for peak season and Q4 freight volumes and rates; or (c) track daily developments on tariffs and FMCSA implementation.

View File

@ -0,0 +1,40 @@
Direct answer — what the White House is doing this week:
The White House is focused on a three-pronged agenda this week: (1) pressuring Congress to pass short-term funding to avert a government shutdown while warning of the program and benefit disruptions that would follow, (2) high-profile foreign diplomacy tied to the U.N. General Assembly and bilateral meetings with world leaders, and (3) a flurry of executive actions and policy announcements on national security, immigration enforcement, trade/tariffs, and health initiatives. Key messaging emphasizes law and order, border enforcement, protectionist trade moves, and administration economic wins (GDP and consumer spending). See the White House warning about an expiring health program if Senate Democrats block funding [Press Secretary tweet](https://x.com/PressSec/status/1971683969877119033) and the White House framing of the funding fight as a Democratic shutdown threat [WhiteHouse tweet](https://x.com/WhiteHouse/status/1971684190761762903).
Key themes and topics this week:
- Funding and shutdown risk: The administration is aggressively pushing a clean, short-term continuing resolution and warning that a shutdown would end or interrupt programs (notably WIC and a home-care program for low-income/Medicare patients). The White House repeatedly blames Senate Democrats for risking benefit expirations and economic harm if funding lapses (examples: warnings about WIC and travel-sector losses; see a WH warning on an expiring health program: https://x.com/PressSec/status/1971683969877119033 and related RapidResponse post https://x.com/RapidResponse47/status/1971683761201782884).
- Foreign policy and U.N.: President Trump and senior officials are centered at the U.N. General Assembly, delivering a blunt anti-globalism message, touting peacemaking claims, and holding bilateral meetings (e.g., with Turkeys Erdogan, Ukraines Zelenskyy, Argentinas Milei, and UN Secretary-General Guterres). The administration is using UNGA appearances to press energy/trade and security themes and to promote U.S. leadership (see the White House coverage of the UN remarks and bilateral meetings: https://x.com/WhiteHouse/status/1970490427900846580 and https://x.com/WhiteHouse/status/1971242187284512875).
- Domestic security and law enforcement: Major executive steps and public rhetoric this week emphasize law-and-order. The administration has (a) designated Antifa as a domestic terrorist organization and announced a cross-government strategy to investigate and dismantle leftwing organized political violence (see PressSec announcement https://x.com/PressSec/status/1970484025136685530 and the full order text repost https://x.com/RapidResponse47/status/1970250137193644374), and (b) directed DOJ action on capital punishment in D.C. and other aggressive enforcement steps.
- Tech/national-security interventions: The White House announced an executive action / deal it says saves TikTok under U.S. control and protects data — a centerpiece of the weeks national-security + tech messaging (see the White House breaking post on the TikTok action: https://x.com/WhiteHouse/status/1971312721573576815).
- Trade and tariffs: The administration continues a high-profile protectionist trade push — raising or threatening large tariffs on pharmaceuticals, heavy trucks, furniture, and other goods, and touting related manufacturing investments (examples: tariff announcements and company responses are repeatedly posted; see a tariff-related WH post: https://x.com/WhiteHouse/status/1971355989711651294 and Eli Lilly investment coverage https://x.com/PressSec/status/1970848766774370466).
- Health, family, and education initiatives: The White House rolled out an Autism Action Plan and FDA guidance flagging a potential acetaminophen-in-pregnancy risk and announced distribution of new federal attention to autism research and physician advisories (see the White House autism/medical announcement: https://x.com/WhiteHouse/status/1970238866394099891 and the FDA/physician guidance post: https://x.com/WhiteHouse/status/1970268144569819420). The First Lady launched a global fostering/child welfare coalition (Fostering the Future Together) and Education Dept. made a major charter funding announcement.
Notable patterns and trends:
- Messaging repetition and partisan framing: Nearly every White House account and allied rapid-response channels frame the weeks items through a two-part lens: (1) Democrats are handing the American people possible harm (shutdown, benefit losses, funding for immigrants) and (2) the administration is taking decisive unilateral actions to protect Americans (tariffs, designating Antifa, law-and-order steps, border enforcement). Several tweets cycle the same claims across accounts to keep pressure on Congress.
- Executive action over Congress: There is a clear pattern of the administration using executive orders/ proclamations (Antifa designation; TikTok deal; autism/FDA guidance; death-penalty enforcement in D.C.; trade directives) to move policy quickly rather than relying on new legislation.
- Convergent foreign/domestic posture: The U.N. appearances and bilateral meetings are being used to bolster narratives about U.S. strength, energy dominance, and security while domestic announcements stress border control and national-security enforcement — presenting a unified strong on security and sovereignty theme.
Important data points, interactions, and specific mentions:
- Shutdown/funding: The Press Secretary warned that a program enabling home treatment of low-income/Medicare patients will expire if Democrats block a short-term funding plan [https://x.com/PressSec/status/1971683969877119033]. White House channels press that a clean short-term funding bill was passed by House Republicans and urge Senate action.
- WIC and travel economy: WH posts cite warnings that WIC benefits and travel-sector losses (cited as ~$1B/week) would follow a shutdown; these figures are used to pressure Senators (examples: https://x.com/RapidResponse47/status/1971655976718832092 and https://x.com/RapidResponse47/status/1971656919858532352).
- UN diplomacy: Presidents UN speech and a series of meetings (Erdogan, Zelenskyy, Milei, Guterres) are prominent; WH is amplifying peace and U.S. leadership themes (see speech and bilateral meeting posts https://x.com/PressSec/status/1970541954082512982 and https://x.com/WhiteHouse/status/1971242187284512875).
- Antifa/domestic terrorism: The administration announced an order designating Antifa a domestic terrorist organization and set out to mobilize agencies to investigate and dismantle associated threats (order text and PR: https://x.com/RapidResponse47/status/1970250137193644374 and https://x.com/PressSec/status/1970484025136685530).
- TikTok: The White House claims to have saved TikTok via an executive order/deal to secure American control and data protections (https://x.com/WhiteHouse/status/1971312721573576815).
- Autism/FDA: Administration launched an Autism Action Plan and FDA guidance about acetaminophen in pregnancy; the White House positions this as a major child-health initiative (https://x.com/WhiteHouse/status/1970238866394099891 and https://x.com/WhiteHouse/status/1970268144569819420).
- Tariffs and industrial policy: Multiple posts announce or threaten steep tariffs (including on pharmaceuticals) and highlight investment responses (Eli Lilly $6.5B Texas facility cited by WH) as intended outcomes (https://x.com/WhiteHouse/status/1971355989711651294 and https://x.com/PressSec/status/1970848766774370466).
- ICE shooting and law-enforcement rhetoric: The administration is responding strongly to a shooting at a Dallas ICE field office, condemning anti-ICE rhetoric and calling for calmer public language from Democrats and local officials (see WH statement and DHS calls for condemnations: https://x.com/WhiteHouse/status/1970952551144313218 and https://x.com/DHSgov/status/1971678074505757134).
Significant events / announcements (each in one paragraph):
1) Funding fight and shutdown warnings — the White House is spending major political capital this week to force a vote on a short-term funding measure, repeatedly warning that a shutdown would immediately threaten benefits (WIC, home-care programs for low-income and Medicare patients), harm the travel economy, and disrupt operations. The admin frames House Republicans as having passed a clean CR and blames Senate Democrats for threatening the shutdown; this is central to daily WH messaging and outreach to swing senators (example: WH/PressSec warnings on expiring health programs and shutdown risk: https://x.com/PressSec/status/1971683969877119033).
2) U.N. General Assembly diplomacy and bilateral meetings — the President used U.N. appearances this week to deliver a forceful anti-globalism, prosovereignty speech, and to hold a series of bilateral meetings (Turkey, Ukraine, Argentina, UN Secretary-General). The White House is amplifying claims of peacemaking progress and U.S. strength while using those forums to press energy and trade agendas (see Presidents UN remarks and bilateral meeting posts: https://x.com/PressSec/status/1970541954082512982 and https://x.com/WhiteHouse/status/1970490427900846580).
3) Major executive actions on domestic security and tech — the administration issued an order designating Antifa as a domestic terrorist organization and announced a broad strategy to investigate and dismantle organized political violence; at the same time the White House announced an executive action/deal to keep TikTok operating under U.S. control and protect user data. Both actions highlight the weeks preference for unilateral executive tools to address perceived threats (Antifa order and text: https://x.com/RapidResponse47/status/1970250137193644374; TikTok action: https://x.com/WhiteHouse/status/1971312721573576815).
4) Health and family policy moves — the White House launched an Autism Action Plan and prompted FDA advisory guidance on acetaminophen use during pregnancy, pitching this as a major public-health priority for children and families; FLOTUS also launched a global child welfare/ fostering coalition (see autism announcement and FDA notice: https://x.com/WhiteHouse/status/1970238866394099891 and https://x.com/WhiteHouse/status/1970268144569819420; FLOTUS coalition: https://x.com/WhiteHouse/status/1970554770797498775).
5) Trade, tariffs and industrial policy — the administration continued to announce aggressive tariff plans (pharmaceuticals, furniture, heavy trucks) and promote industrial investment as a direct outcome of protectionist measures; the WH highlights revised GDP and consumer-spending strength while using tariffs to justify reshoring and new plant commitments (tariff pronouncements and industry responses: https://x.com/WhiteHouse/status/1971355989711651294 and https://x.com/PressSec/status/1970848766774370466).
Bottom line: The White House this week is simultaneously in crisismanagement mode on a potential shutdown, on a global stage with U.N. diplomacy and leader meetings, and executing a highvelocity slate of executive actions (domestic terrorism designation, TikTok deal, autism/FDA steps, tariff pronouncements). Messaging is tightly coordinated across WH accounts to pressure Congress, emphasize law-and-order and border security, and promote trade/economic wins. Sources: multiple White House/PressSec/RapidResponse posts reporting the items above (sample links: https://x.com/PressSec/status/1971683969877119033; https://x.com/WhiteHouse/status/1971312721573576815; https://x.com/RapidResponse47/status/1970250137193644374).

View File

@ -0,0 +1,55 @@
Top takeaways — this weeks most important events
1) Escalation of criminal case against James Comey and political reverberations
- Former FBI director James Comey was indicted on federal charges (false statements and obstruction), a major legal escalation tied to President Trumps campaign to prosecute perceived political opponents. Comey has publicly denied wrongdoing and vowed to fight the charges; the case drew sharp partisan reaction and attention to the judge and prosecutor handling it. See reporting on the indictment here: [Reuters: Comey indicted](https://x.com/Reuters/status/1971348332271358434).
2) Trumps sweeping new tariffs and market impact
- President Trump announced a fresh round of tariffs — notably a 100% levy on many branded pharmaceutical imports (with carve-outs only for companies building U.S. manufacturing), large duties on heavy trucks and high tariffs on some furniture/cabinetry — triggering market moves and political pushback. The announcement produced immediate confusion on details and knock-on effects: pharmaceutical and related stocks dropped, governments and companies (EU, Japan, major drugmakers) scrambled for clarification, and analysts warned of supplychain disruption. Coverage and market reaction: [Washington Post explainer](https://x.com/washingtonpost/status/1971696343321022903) and [Reuters on market effects](https://x.com/Reuters/status/1971549096709120451).
3) Netanyahu at the U.N., mass walkouts and Gaza tensions
- Israeli Prime Minister Benjamin Netanyahus UN General Assembly address prompted dozens of delegates to leave the hall in protest; his speech rejected Palestinian statehood and defended sustained military operations in Gaza, deepening diplomatic friction at the UN and fueling protests and international criticism. Related developments include increased maritime aidflotilla activity toward Gaza and regional exchanges (e.g., strikes involving Yemen/Houthi actors). See Reuters coverage of the walkouts and his speech: [Netanyahu rejects Palestinian statehood; walkouts](https://x.com/Reuters/status/1971630855303954800).
4) TikTok sale framework and executive action
- The White House moved to approve a framework for a TikTok deal that would transfer U.S. control to a U.S.-led investor group and issued executive action to allow the transaction to proceed under new nationalsecurity rules — a key development in ongoing U.S. efforts to limit Chinese tech control of major social platforms. Reporting on the order and deal: [Reuters: TikTok order/deal](https://x.com/Reuters/status/1971317621502116050).
5) Dallas ICE fieldoffice shooting and related immigration enforcement incidents
- A sniper-style attack at a Dallas ICE field office left detainees dead or wounded; investigators say the shooter intended to terrorize ICE agents and left notes indicating ICE was the target. The incident amplified national debate on immigration enforcement and political rhetoric about enforcement agencies. (Relatedly, video of an ICE officer pushing a woman at a federal courthouse prompted DHS to relieve the officer of current duties while it investigates.) See Reuters on the suspect/notes and ABC/CBS coverage of the incidents: [Reuters: Dallas shooting notes](https://x.com/Reuters/status/1971408131524788267).
6) Looming U.S. partial government shutdown and administration contingency plans
- As the funding deadline neared, negotiations remained fraught. The White House and OMB circulated plans and warnings — including unprecedented threats about mass firings or permanent removal of federal workers if a shutdown occurs — prompting intense congressional pushback and urgent shutdown strategy activity from both parties. Coverage of the standoff and layoff warnings: [Reuters: White House threatens removals if shutdown occurs](https://x.com/Reuters/status/1971316276363407785) and reporting on political maneuvers in Congress.
7) Major corporate and regulatory moves: Amazon settlement, Microsoft action, Starbucks restructuring
- Amazon agreed to a large settlement with the FTC (roughly $2.5 billion) over alleged deceptive Prime enrollment and cancellation practices. Microsoft disabled some cloud services to an Israeli military unit amid allegations of use for mass surveillance of Palestinians. Starbucks confirmed tech and job restructuring changes, including executive departures and store/role reductions. Representative coverage: [Reuters: Amazon settlement](https://x.com/Reuters/status/1971498728650658089) and [Reuters: Microsoft cuts services](https://x.com/Reuters/status/1971437686603780477).
8) Extreme weather and storms
- The Atlantic saw multiple systems: Hurricane Humberto rapidly intensified (becoming a major hurricane) while other disturbances threatened the Caribbean and potentially the U.S. Southeast; separate typhoons and storms hit the Philippines, Taiwan and the Philippines Bualoi led to fatalities. Forecasters flagged flooding and tightening watches. See hurricane coverage: [CBSNews on Humberto](https://x.com/CBSNews/status/1971686213992992872) and ABC/Reuters storm reports.
Patterns and themes across the week
- Concentration of executivebranch action: aggressive use of tariffs, prosecution priorities, nationalsecurity orders (TikTok), and internal directives (shutdown contingency) signal an administration using broad levers — economic, legal and administrative — to reshape policy and target perceived adversaries.
- Market and supplychain uncertainty: tariff announcements and H1B / immigration policy discussions roiled markets and sectors (pharma, tech, Indian pharma/IT stocks), prompted company responses (price changes, manufacturing pledges) and raised questions about longer-term trade realignment.
- International friction and humanitarian flashpoints: UN debate over Gaza, flotilla activity, and regional strikes (Yemen/Houthi) highlighted heightened diplomatic tensions and risks of broader confrontation.
- Security and domestic polarization: highprofile violent incidents (Dallas ICE shooting, political violence concerns after Charlie Kirks killing) plus government rhetoric drove renewed focus on politicalviolence prevention and security spending for lawmakers.
Other notable items (short mentions)
- Historic legal outcome: Former French president Nicolas Sarkozy was sentenced to prison in a major corruption/conspiracy decision. See Reuters: [Sarkozy sentence](https://x.com/Reuters/status/1971283560804831593).
- High-profile deaths/releases: Assata Shakur was reported to have died in Cuba this week (coverage by CBS/NBC/Politico). See CBSNews: [Assata Shakur dies in Cuba](https://x.com/CBSNews/status/1971649725372784745).
- Aviation, corporate and tech items: airline incidents and aircraft/FAA news, Microsoft and Meta AI moves, Starbucks CTO resignation and job cuts, and the continuing corporate responses to tariffs and regulatory scrutiny.
What to watch next (near term)
- Legal developments in the Comey prosecution (arraignment, trial schedule, DOJ strategy) and potential additional prosecutions Trump has signaled. (See Reuters coverage.)
- Clarification and implementation details on the tariff package (how tariffs are applied, company responses, EU/Japan coordination) and resulting market effects.
- Progress (or further escalation) in U.N. diplomacy over Gaza, flotilla outcomes, and Israels regional interactions.
- Whether Congress and the White House reach a funding agreement to avert the partial shutdown and related workforce actions.
Sources (selected tweets cited above):
- Comey indictment: [Reuters](https://x.com/Reuters/status/1971348332271358434)
- Trump drug/tariff announcement and market reaction: [Washington Post explainer](https://x.com/washingtonpost/status/1971696343321022903), [Reuters tariff coverage](https://x.com/Reuters/status/1971549096709120451)
- Netanyahu UN address and walkouts: [Reuters](https://x.com/Reuters/status/1971630855303954800)
- TikTok executive order/deal: [Reuters](https://x.com/Reuters/status/1971317621502116050)
- Dallas ICE shooting: [Reuters](https://x.com/Reuters/status/1971408131524788267)
- Shutdown/layoff warnings: [Reuters](https://x.com/Reuters/status/1971316276363407785)
- Microsoft suspending services to Israeli unit: [Reuters](https://x.com/Reuters/status/1971437686603780477)
- Amazon FTC settlement: [Reuters](https://x.com/Reuters/status/1971498728650658089)
- Hurricane Humberto: [CBSNews](https://x.com/CBSNews/status/1971686213992992872)
If you want, I can (a) produce a onepage timeline of these events by day, (b) extract only the politics/economics items, or (c) create short headlines you can drop into a newsletter.

View File

@ -0,0 +1,45 @@
Direct answer (brief):
This weeks biggest, recurring storylines were: (1) an escalation of politically fraught prosecutions and the apparent politicization of the Justice Department (most notably the indictment of former FBI Director James Comey); (2) major new disclosures from Jeffrey Epstein-related records naming powerful figures; (3) a Supreme Court ruling and other legal decisions that strengthened the White Houses leverage in shutdown/funding fights; (4) growing economic strain headlines (inflation, tariffs, high grocery prices) and controversial fiscal moves (a large Argentina transfer); and (5) heightened international security tensions — Russian aircraft/drone activity in NATO/European airspace and U.S. military responses. See the detailed themes, patterns, and notable items below with tweet sources inline.
Key themes and topics discussed this week
- Politicization of DOJ and highprofile prosecutions: The indictment of James Comey on falsestatements and obstruction counts dominated coverage and commentary; Comey has pled innocent and called for a trial, and the case has prompted resignations and concerns about selective prosecutions and DOJ politicization [breaking report on the indictment](https://x.com/jimsciutto/status/1971350775335952616) and commentary on DOJ as a political tool (Ty Cobb, Sen. Dick Durbin) [analysis/quotes](https://x.com/allenanalysis/status/1971371199524671751). Comeys arraignment and procedural updates (judge assignment, arraignment date 10/9, a soninlaw resignation) were reported as well [updates and context](https://x.com/kyledcheney/status/1971374502274818274).
- Epstein documents and accountability pressure: Multiple batches of Epsteinestate records and DOJheld files were released/announced this week and reportedly include phone logs, flight records, and meeting entries that name highprofile people (Peter Thiel, Steve Bannon, Elon Musk among others). Pressure from House Democrats to release more files continued; commentators warned of larger political fallout as names circulate [report on new Epstein records and names](https://x.com/allenanalysis/status/1971677285809049609) and calls for release ([Oversight Dems thread](https://x.com/MeidasTouch/status/1971599065571106946)). Additional reporting about specific calendar entries/members shows the scope of the documents [calendar disclosure tweet](https://x.com/allenanalysis/status/1971610319425515878).
- Funding fight / shutdown leverage and legal decisions: The Supreme Court issued a 63 decision that limited some challenges to Trumps “pocket rescission” of $4B in foreign aid, a ruling that commentators said gives the White House more leverage in shutdown/funding talks and raises uncertainty about avoiding a shutdown [SCOTUS ruling coverage](https://x.com/kyledcheney/status/1971677501253615905). Relatedly, the White House warned federal agencies to prepare for mass firings if a shutdown occurs, and internal strategy reporting emphasized leveraging pain to extract political concessions [report on agency preparations](https://x.com/allenanalysis/status/1971042294158721240).
- Economic pain and fiscal controversies: Reporters flagged rising consumer price measures (PCE at ~2.7% yearoveryear for the month cited), grocery price spikes and worsening consumer sentiment, while administration trade and tariff rhetoric and actions were linked to possible price pressure on drugs and other goods [PCE & inflation reporting](https://x.com/factpostnews/status/1971612318162161682). Separately, critics flagged an approximately $20B transfer/assistance to Argentina as politically questionable [commentary on Argentina bailout](https://x.com/allenanalysis/status/1971682785783173337).
- National security & international incidents: NATO and European partners reported drone incursions and airspace violations attributed to Russia (Poland, Denmark, Norway, and incidents near Gotland/Sweden), and NORAD scrambled jets to intercept Russian Tu95 and Su35 flights into the Alaskan ADIZ — signaling elevated tensions and frequent provocations this month [NORAD intercept report](https://x.com/jimsciutto/status/1971241970568736811) and reporting on drone incursions in Europe [example: Poland/Gotland/Norway coverage](https://x.com/shashj/status/1971184990651285888).
Notable patterns or trends relevant to the week
- Institutional squeeze and retaliation rhetoric: Repeated statements from political and media figures framed the current moment as payback or retribution (e.g., Fox/Watters/Gutfeld quotes) and broader efforts to use government power (prosecutions, firings, EO tools) against perceived opponents, suggesting a pattern of using state institutions for political ends [examples of revenge rhetoric](https://x.com/Acyn/status/1971687322996625913) and calls for firings/punitive measures [demand re Microsoft hire](https://x.com/Acyn/status/1971685743006523564).
- Push for transparency vs. blocking tactics: Oversight pushes to release Epstein materials and other records met with procedural blocks and political resistance (e.g., speaker maneuvers, sealed files). That tugofwar is recurring: demands for release and disclosure vs. moves to keep items sealed or delay swearingin/administrative actions [pressure to release Epstein files](https://x.com/allenanalysis/status/1971681709931614359) and reports of blocking behavior in Congress [blocking swearing in Rep. Grijalva](https://x.com/MalcolmNance/status/1971685353259204875).
- Legal system as political arena: Multiple court rulings this week (Smartmatic ruling vs. Mike Lindell; judges finding illegal application of detention policies; Comey indictment and procedural court developments) reflect courts being central to political battles and gatekeepers for how far the executive can push policy and prosecutions [Smartmatic ruling coverage](https://x.com/kyledcheney/status/1971688291323019307) and detention policy rulings [example](https://x.com/kyledcheney/status/1971573744536518886).
Important mentions, interactions, and data points
- Comey indictment and procedural details (indicted on two counts, judge assignment, arraignment 10/9, soninlaw resignation): https://x.com/kyledcheney/status/1971346080446202333 and https://x.com/kyledcheney/status/1971374502274818274
- Epstein files / third batch and named individuals (Thiel, Musk, Bannon); calls to release all pages: https://x.com/allenanalysis/status/1971677285809049609 and https://x.com/allenanalysis/status/1971610319425515878
- Supreme Court 63 decision on the pocket rescission of $4B in foreign aid and its shutdown leverage implications: https://x.com/kyledcheney/status/1971677501253615905
- Inflation / PCE data showing stubborn core inflation (PCE ~2.7% y/y) and consumer concerns: https://x.com/factpostnews/status/1971612318162161682
- NORAD response & Russian aircraft in the Alaskan ADIZ (intercept by F16s, tankers): https://x.com/jimsciutto/status/1971241970568736811
- Legal win for Smartmatic against Mike Lindell, narrowing trial to malice/damages: https://x.com/kyledcheney/status/1971688291323019307
- White House press/agency orders preparing for mass firings in a shutdown scenario: https://x.com/allenanalysis/status/1971042294158721240
- Public controversies over Trump demanding Microsoft fire Lisa Monaco (tweet/demand), raising nationalsecurity and corporate pressure questions: https://x.com/atrupar/status/1971693704235962710 and https://x.com/Acyn/status/1971685743006523564
- Additional domestic enforcement and immigration litigation: mass arrests reports and court challenges to ICE practices and detention policy rulings: https://x.com/StephenM/status/1971678846614437956 and https://x.com/kyledcheney/status/1971573404710076479
Significant events (oneparagraph highlights)
1) James Comey indictment and fallout: The indictment of former FBI Director James Comey on falsestatement and obstruction charges was the weeks biggest legal and political flashpoint. Comey proclaimed his innocence and called for a trial; the case prompted immediate procedural developments (judge assignment, arraignment set for 10/9) and at least one DOJ resignation in protest. Observers widely framed the move as evidence of DOJ politicization and possible retaliatory prosecutions, making the case a focal point for debates about rule of law and selective enforcement [breaking coverage and updates](https://x.com/jimsciutto/status/1971350775335952616) and commentary on politicization [contextual commentary](https://x.com/allenanalysis/status/1971371199524671751).
2) New Epstein files releases: Oversight and press reporting this week showed additional Epstein estate records and DOJ documents that include phone logs, flight manifests, calendars and meeting entries naming highprofile individuals (Peter Thiel, Steve Bannon, Elon Musk among those flagged). House Democrats pushed to release more material; commentators warned the rolling disclosures could expand political exposure well beyond past allegations and create new pressure points for public figures named in the files [document drops & names reported](https://x.com/allenanalysis/status/1971677285809049609) and calls by Oversight for full transparency [oversight reporting](https://x.com/MeidasTouch/status/1971599065571106946).
3) Supreme Court ruling strengthens executive leverage in funding fights; shutdown risk: The Supreme Courts decision to allow Trumps pocket rescission challenge to proceed (63) was characterized as giving the White House the upper hand in disputes over appropriations and complicating negotiations to avoid a government shutdown. Journalists and analysts said the ruling injects legal uncertainty into bargaining over appropriated funds and could make future negotiations harder, while the White House signaled contingency plans that include mass agency firings in a shutdown scenario [ruling and implications](https://x.com/kyledcheney/status/1971677501253615905) and agency preparation reporting [agency contingency reporting](https://x.com/allenanalysis/status/1971042294158721240).
Bottom line / takeaways
- This week consolidated a pattern: legal and investigative tools are central to partisan conflict (highprofile indictments, release of sensitive documents, and litigation outcomes that affect political power). Many threads point to intensifying institutional strain — courts, the DOJ, oversight committees, and federal agency operations are all active battlegrounds.
- Simultaneously, inflation and economic pain remain politically salient, while foreignpolicy and security flashpoints (Russian air probes, drone incidents in Europe) continue to raise alliance and defense questions.
- Expect continuing legal and congressional fights over the Epstein records, expanded scrutiny of DOJ actions, and sharper political showdowns over spending and shutdown leverage in the days ahead.
Sources (examples cited above): James Comey indictment coverage and updates https://x.com/jimsciutto/status/1971350775335952616; Epstein files / names reporting https://x.com/allenanalysis/status/1971677285809049609; Supreme Court pocket rescission ruling and shutdown implications https://x.com/kyledcheney/status/1971677501253615905; White House agency shutdown preparation https://x.com/allenanalysis/status/1971042294158721240; PCE/inflation reporting https://x.com/factpostnews/status/1971612318162161682; NORAD intercept of Russian aircraft https://x.com/jimsciutto/status/1971241970568736811; Monaco / Microsoft demand reporting https://x.com/Acyn/status/1971685743006523564.

View File

@ -0,0 +1,31 @@
Direct answer
Since late September 2025 the most important Russia/Ukraine war developments and related NATO-country actions are: intensified Ukrainian strikes (especially by drones and unmanned systems) hitting Russian energy and military logistics nodes, growing NATO defensive steps and readiness after repeated airspace incursions, and active diplomatic / weapons debates among Western capitals (including a high-profile U.S. exchange about longrange Tomahawk strikes). These developments are producing tangible effects inside Russia (fuel shortages, refinery damage) while NATO states expand air policing, test counterdrone technologies and consider tougher rules of engagement.
Key themes and topics
- Drone warfare and counterdrone defence: Ukraine is using attack and interceptor drones to strike Russian fuel and logistic targets and to defeat Russian Shahed/FPV strikes; Ukraine is also creating specialized airdefense unmanned systems units and reporting interceptor success rates above 70% [see discussion of the new unmanned airdefense branch and interceptor performance](https://x.com/EuromaidanPress/status/1971652998553100618). NATO members are responding by testing lowcost drone countermeasures and accelerating procurement of interceptors and related tech in exercises in Portugal, the Netherlands and elsewhere [Reuters summary of NATO tests](https://x.com/Reuters/status/1971362832924147956).
- Targeting Russias energy/logistics: Ukrainian strikes have increasingly focused on refineries, fuel hubs and gas distribution points, causing fuel shortages in parts of Russia and disrupting refining capacity (FT/Reuters reporting that 16 of 38 refineries have been hit, disrupting >1 million barrels/day of refining capacity) [source](https://x.com/Mylovanov/status/1971694911981539584). Notable specific attacks include strikes on the Afipsky refinery in Krasnodar [reported here](https://x.com/NOELreports/status/1971600045792174364).
- NATO airspace incursions and allied responses: Several NATO states reported airspace violations and drone incidents (Denmark temporarily shut airports after drone activity; Lithuania got a Turkish warning plane deployed), and Baltic/Polish allied air policing increased. European diplomats warned Moscow that NATO is prepared to shoot down aircraft that violate allied airspace [Denmark/Reuters](https://x.com/Reuters/status/1971297361923277102) and [Bloomberg summary on the NATO warning](https://x.com/Osinttechnical/status/1971278614588178).
- Political/diplomatic moves and defence aid debates: Highlevel diplomacy and meetings (Zelenskys U.S. engagements) are ongoing; debates continue over enabling Ukraine to strike deeper into Russia — Zelensky asked for Tomahawk cruise missiles and U.S. messaging is mixed, with officials saying restrictions might be eased but no firm commitment yet [reported exchange and followups](https://x.com/NOELreports/status/1971654893573460416). EU sanctions and the idea of using frozen Russian assets to finance Ukraine face internal friction (Hungary as an obstacle) [POLITICO](https://x.com/POLITICOEurope/status/1971643238348951650).
Notable patterns and trends
- Increased use of lowcost drones to impose asymmetric effects: Repeated Ukrainian drone campaigns are degrading Russian fuel and repair capacity while also amplifying logistical pain on Russian forces and civilian fuel markets; social reports show gas station closures and rationing in some Russian regions [coverage of closures and refinery hits](https://x.com/EuromaidanPress/status/1971622805163716826).
- NATO moving from passive monitoring to more active deterrence posture: Greater Baltic/Poland air policing, deployment of partner assets (e.g., Turkey to Lithuania under NATO measures) and public warnings that NATO will respond forcefully to violations signal a harder line and readiness to intercept/shoot down intruders [Reuters on Turkey deployment](https://x.com/Reuters/status/1971312518862668089).
- Operational innovation in Ukraine: creation of specialized unmanned airdefense forces and effective pairing of mechanized systems (e.g., arrival of Patria carriers from Latvia) to counter drone-heavy Russian tactics are recurring operational notes [mechanized capability reporting](https://x.com/EuromaidanPress/status/1971675646850998477).
- Political friction within the West about the next escalation steps: While many NATO allies push for stronger measures (weapons, sanctions, assets usage), some political actors (e.g., Hungary) and divergent U.S. messaging create friction in implementing unified measures.
Important mentions, interactions and data points
- Refinery/energy strike metrics: FT reporting (shared by @Mylovanov) that since August Ukraine struck 16 of 38 Russian refineries, disrupting over 1M barrels/day of refining capacity [source](https://x.com/Mylovanov/status/1971694911981539584). Reuters coverage also highlights the operational and political friction caused by successful strikes [Reuters](https://x.com/Reuters/status/1971532708338692304).
- Dobropillia counteroffensive: Zelenskyys briefing reported 168.8 km² liberated and 187.7 km² cleared of sabotage groups since the operation began, with Russian losses nearly 3,000 in that operation [Zelenskyy briefing](https://x.com/ZelenskyyUa/status/1971560229327327321).
- Specific facility strike: Afipsky oil refinery in Krasnodar was struck by Ukrainian drone forces overnight (fire reported) [NOELreports](https://x.com/NOELreports/status/1971600045792174364); images and operational claims around multiple gas distribution sites in Luhansk were published by Ukrainian Unmanned Systems [EuromaidanPress](https://x.com/EuromaidanPress/status/1971577509800993144).
- NATO responses and exercises: NATO testing counterdrone tech, conducting increased air policing in the Baltics and launching planning on a European “drone wall” to protect airspace after incursions [Reuters on NATO tests](https://x.com/Reuters/status/1971362832924147956) and [POLITICO on drone wall plans](https://x.com/POLITICOEurope/status/1971594282126504040).
- U.S./Tomahawk debate: Zelensky requested Tomahawk cruise missiles in private talks; U.S. officials say restrictions might be eased but no definitive delivery was promised at the time of reporting [NOELreports/WSJ/Axios coverage](https://x.com/NOELreports/status/1971654893573460416).
Significant events / announcements (each addressed briefly)
1) Ukrainian strikes on Russian fuel infrastructure and refinery network: Multiple outlets and analysts report a concentrated Ukrainian campaign against refineries and gas distribution nodes that has damaged Russian refining capacity (reportedly 16 of 38 refineries hit, >1M bpd capacity disrupted). The attacks have produced fuel shortages, station closures in parts of Russia and forced Russian logistics/operations adjustments; specific highvalue strikes include Afipsky in Krasnodar [see FT/Reuters repost via @Mylovanov](https://x.com/Mylovanov/status/1971694911981539584) and the Afipsky strike report [NOELreports](https://x.com/NOELreports/status/1971600045792174364).
2) NATO airspace incidents, allied responses and counterdrone acceleration: Several NATO allies reported incursions or drone incidents (Denmark airports, Baltic airspace, Hungaryinvolved intercepts). In response NATO allies have ramped up air policing, deployed partner assets (Turkey to Lithuania), publicly warned Moscow that violations may be met with shootdown responses, and accelerated testing and procurement of counterUAV systems and lowcost interceptors [Denmark/Reuters on airport incidents](https://x.com/Reuters/status/1971297361923277102), [Osinttechnical/Bloomberg on NATO warning](https://x.com/Osinttechnical/status/1971278614588178), and [Reuters on NATO tests](https://x.com/Reuters/status/1971362832924147956).
3) Diplomatic/arms debate over longrange strikes (Tomahawks) and Western unity: Zelenskys outreach to the U.S. raised the question of providing Ukraine with longrange Tomahawk missiles to strike deeper Russian infrastructure; U.S. messaging was mixed—reports say restrictions might be eased but no firm commitment was delivered at the time—highlighting tension between Ukraines operational requests and allied political calculations [NOELreports/press summaries](https://x.com/NOELreports/status/1971654893573460416).
Bottom line
The conflicts tactical center of gravity is shifting toward highvolume drone warfare and targeted strikes on Russian logistics/energy infrastructure; NATO countries are reacting by strengthening air policing, experimenting with and acquiring counterdrone systems, and debating tougher political/financial measures. These actions are producing real strategic effects on Russian logistics and domestic economy, while allied political coordination — especially on weapons policy and assetseizure financing — remains contested and consequential.

View File

@ -0,0 +1,49 @@
Direct answer: OSINT monitoring over the last 2448 hours captured a dense set of security, diplomatic, and political developments: (1) a sharp uptick in drone activity and airspace incursions in Northern Europe (Denmark, Norway, Estonia) that NATO and national authorities are treating as deliberate hostile acts; (2) immediate reimposition of U.N. “snapback” sanctions on Iran (with consequential financial/IAEA fallout and a SWIFT disconnection); (3) kinetic strikes and counterstrikes across the Middle East (notably Israeli/IDF strikes against Houthi facilities in Sanaa and Houthi missile/drone launches against Israel); (4) sustained high-intensity military signaling by the U.S. and NATO (strategic bomber and SLBM tests, AEW/ISR sorties, regional naval/air deployments, and a rare convocation of nearly all U.S. flag officers); (5) continued strikes and strikes-vs-logistics in the RussiaUkraine theater (Ukrainian strikes on Russian energy/refining infrastructure, battlefield advances in several axes, and nuclear-plant power disruptions); and (6) a number of important law enforcement, political, and OSINT revelations (Epstein estate documents provided to Congress; Secret Service disruption of a large SIM-card network; an ICE detention-center shooting). Many of these items are documented in OSINT tweets and linked sources below.
Key themes and topics
- Drone/grey-zone operations and attribution problems: widespread reports of large, coordinated drones over Copenhagen and other Danish sites (authorities treat it as a professional actor; ship-launched vectors suspected) and additional drone sightings over Norwegian/Swedish airspace. (See Denmark: https://x.com/sentdefender/status/1970479392557027834 and Copenhagen closures: https://x.com/sentdefender/status/1970212912171262268.)
- NATORussia friction and airspace violations: multiple Russian fighter and interceptor sorties near/into NATO airspace (MiG31s over Estonia; aircraft near Baltic states and Kaliningrad), frequent NATO QRA scrambles, and debates inside NATO over rules of engagement for airspace violations (e.g., whether to shoot down violators). (See Estonian violation: https://x.com/criticalthreats/status/1970230861594714621 and NATO discussion: https://x.com/sentdefender/status/1971239562182607270.)
- Iran snapback and financial isolation: the E3 pushed snapback sanctions through the U.N. and key measures (including removal of Irans central bank from SWIFT) were reported to take effect immediately, with Iran signaling suspension of IAEA cooperation and hardline political pushback. (See E3/snapback: https://x.com/criticalthreats/status/1971694357519511908 and SWIFT removal: https://x.com/sentdefender/status/1971674065527361722.)
- Middle East kinetic operations and escalation chains: Israeli strikes against Houthi infrastructure in Sanaa and Houthi missile/drone launches into Israel; the IDF and partner militaries are active in kinetic responses and attribution and casualty claims differ across sources. (See IDF strike on Houthi SIS facility and reporting: https://x.com/criticalthreats/status/1971695007892754524 and https://x.com/criticalthreats/status/1971695003862028502.)
- US strategic signaling and posture: visible U.S. strategic activity — B2s crossing the Atlantic, SLBM/Trident II tests, E6 TACAMO flights, nuclear exercises in France — concurrent with the Hegseth-ordered gathering of nearly all U.S. generals and admirals and tighter DoD press controls, signaling elevated readiness and messaging. (See Trident tests: https://x.com/sentdefender/status/1970511374338957797; Hegseth convocation: https://x.com/sentdefender/status/1971220079481106838 and https://x.com/sentdefender/status/1971640165459534036.)
- Ukraine conflict dynamics and infrastructure targeting: Ukrainian advances and localized encirclements while Kyiv continues precision/asymmetric strikes against Russian logistics and energy infrastructure, fueling fuel shortages and refinery outages across Russia and occupied areas; Zaporizhzhia NPP reported loss of offsite power (significant nuclear risk). (See strikes & shortages: https://x.com/criticalthreats/status/1971411693352910966 and Zaporizhzhia power loss: https://x.com/sentdefender/status/1970523733766111415.)
- Maritime/secret-ops and suspected dronecarrier activity: satellite-tracked and OSINT-flagged vessels (MV Ocean Trader, Sparta IV, OSLO CARRIER 3, Aleksandr Shabalin, and others) noticed in the Caribbean and North Atlantic or loitering near Scandinavian waters; some ships are explicitly suspected in drone operations against airports/critical infrastructure. (See Ocean Trader sightings: https://x.com/sentdefender/status/1971435498628346264 and https://x.com/sentdefender/status/1970911411917177167; OSLO CARRIER 3/links to drone attack: https://x.com/auonsson/status/1971678884270920140 and https://x.com/MT_Anderson/status/1971253403931013121.)
Notable patterns and trends
- Drones as primary disruptor: recurrent use of oneway attack drones and large reconnaissance/ISR drones for strikes, hybrid harassment, and to shut airports/airspace; they are proliferating across theaters (Ukraine strikes on Russian refineries, naval/USV attacks, infratargeting, and Northern European airspace intrusions).
- Escalatory signaling via strategic assets: nuclearera platforms (B2, SLBM tests, E6/TACAMO) and publicized large exercises (Frances Operation Poker and STRATCOM activity) are being used as overt signaling alongside regional kinetic operations.
- Conflation of maritime and aerial grey-zone tactics: OSINT notes ships operating with suspicious tracks and unusual crew profiles near European ports and shores, a pattern repeated across multiple incidents and linked by analysts to drone-launch vectors.
- Political-military coupling: political decisions (UN snapback, U.S. leadership statements, and potential weapons transfers to Ukraine) are closely timed with operational moves, suggesting coordinated pressure and leverage campaigns rather than isolated events.
Important mentions, interactions, and data points (selected)
- Denmark: multiple drone incursions forced closure/diversions at Copenhagen and other airports; Danish leaders described it as a hybrid attack and suggested shiplaunched drones; police and NOST are operating 24/7. (See: https://x.com/sentdefender/status/1970212912171262268 and https://x.com/sentdefender/status/1970479392557027834.)
- Iran snapback & SWIFT: the E3 forced the snapback of UNSC measures and Irans central bank was reported to be disconnected from SWIFT at 00:00; Iran signaled suspension of IAEA cooperation and increased domestic hardline rhetoric. (See: https://x.com/criticalthreats/status/1971694357519511908 and https://x.com/sentdefender/status/1971674065527361722.)
- IDF strikes in Sanaa: satellite and commercial imagery indicate heavy damage to a Houthi SIS facility; Houthis and some analysts claim the site held political prisoners. (See: https://x.com/criticalthreats/status/1971695007892754524.)
- Trump — Zelensky meetings and longrange weapons: reporting indicates President Trump told Zelensky hes open to allowing Ukraine to use U.S. longrange weapons to strike inside Russia and is considering Tomahawk TLAM requests (no commitment yet). (See: https://x.com/sentdefender/status/1971653497473954160 and https://x.com/sentdefender/status/1971556765004100001.)
- Hegsethordered convocation of generals/admirals at Quantico: a rare, shortnotice meeting of nearly all flag officers was ordered; the stated public briefing theme is new military standards and “warrior ethos,” but the sudden, global recall of senior commanders has raised questions and concern in the force. (See: https://x.com/sentdefender/status/1971220079481106838 and https://x.com/sentdefender/status/1971650346213859522.)
- Maritime sightings and suspected dronecarrier vessels: Ocean Trader observed off St. Croix and in the Southern Caribbean; Sparta IV and escorts tracked in the Atlantic with highvalue escort patterns; OSLO CARRIER 3 and other merchant vessels have been singled out by analysts as suspect in Copenhagen drone incidents. (See: Ocean Trader: https://x.com/sentdefender/status/1971435498628346264 and Oslo/Sparta analysis: https://x.com/auonsson/status/1971678884270920140 and https://x.com/MT_Anderson/status/1971253403931013121.)
- Russian domestic impacts: repeated Ukrainian strikes on Russian refineries and logistical nodes produced gasoline shortages and refinery fires across multiple regions; Kremlin messaging continues to publicly justify further operations. (See: https://x.com/criticalthreats/status/1971411693352910966 and https://x.com/Osinttechnical/status/1971225500602556830.)
- Zaporizhzhia NPP: continued risk — the IAEA/OSINT noted loss of offsite power and reliance on emergency diesel at the Zaporizhzhia Nuclear Power Plant — an ongoing nuclear safety concern in the conflict. (See: https://x.com/sentdefender/status/1970523733766111415.)
- Domestic US security/political items: House Oversight received redacted Epsteinestate documents including schedules and flight manifests (notable names referenced) (See: https://x.com/sentdefender/status/1971683592959832384); Secret Service dismantled a huge SIMserver/SIMcard network tied to foreign actors near UNGA in New York (See: https://x.com/sentdefender/status/1970470725677883797); shooting at ICE detention center in Dallas with multiple detainee fatalities and the shooter found dead (See: https://x.com/sentdefender/status/1970836229793993129 and https://x.com/sentdefender/status/1970847139988185455).
Significant events (each summarized in a paragraph)
- Denmark and Scandinavian drone incidents: Multiple large drones were observed operating over Copenhagen Airport and other Danish airfields, forcing closures, major flight cancellations/diversions, and national crisis activation; Danish leaders described the incidents as a hybrid attack by a capable professional actor and raised the possibility of shiplaunched drones operating from the Baltic. The events triggered NATO and allied consultations and heightened readiness across the region. (See immediate reporting: https://x.com/sentdefender/status/1970212912171262268 and Danish government statement: https://x.com/sentdefender/status/1970479392557027834.)
- U.N. snapback sanctions & Irans financial/IAEA backlash: The E3 (UK, France, Germany) moved to reimpose UNSC sanctions on Iran; reporting indicates snapback measures take effect imminently and include removing Irans central bank from SWIFT, prompting Iran to suspend IAEA cooperation and harden rhetoric. This creates immediate financial isolation risks and heightens the prospect of regional escalation tied to Irans nuclear and missile programs. (See: https://x.com/criticalthreats/status/1971694357519511908 and SWIFT timing: https://x.com/sentdefender/status/1971674065527361722.)
- IDF strike on Houthi SIS facility in Sanaa: Commercial satellite imagery and reporting indicate an Israeli/IDF strike heavily damaged a Houthi Security and Intelligence Service facility in Wahdah District, Sanaa; Houthis and analysts claim the site may have housed political prisoners. Israel has stated it targeted Houthi command/propaganda and military complexes amid a series of Houthi missile/drone launches toward Israel. The episode increases the risk of wider Iranaxis escalation in the Red Sea/Arabian Peninsula. (See strike imagery/analysis: https://x.com/criticalthreats/status/1971695007892754524 and IDF target statement: https://x.com/criticalthreats/status/1971695003862028502.)
- TrumpZelensky lines on longrange weapons: Multiple OSINT reports indicate President Trump told Ukrainian President Zelensky he is open to lifting restrictions on use of U.S. longrange weapons (including Tomahawk cruise missiles) to strike inside Russia and is seriously considering the transfer—though no formal commitment was made in the meeting. This is a major potential policy shift with strategic consequences for escalation management, targeting policy, and alliance signaling. (See: https://x.com/sentdefender/status/1971653497473954160 and background Tomahawk request: https://x.com/sentdefender/status/1971556765004100001.)
- Hegseth-ordered convocation of senior U.S. flag officers: Secretary of Defense Pete Hegseth ordered an unusually broad, short-notice gathering of nearly all U.S. generals and admirals at Quantico. The stated focus reported in press previews is on “military standards,” readiness, and the warrior ethos, but the global recall of senior commanders has prompted intense speculation inside and outside the service about intent, force protection, and command continuity during the event. (See: https://x.com/sentdefender/status/1971220079481106838 and reporting on the planned address: https://x.com/sentdefender/status/1971650346213859522.)
- Maritime sightings and suspected dronecarrier activity: OSINT analysts flagged several merchant and specialty vessels (MV Ocean Trader observed in the Southern Caribbean/U.S. Virgin Islands; Sparta IV escorted in the Atlantic; OSLO CARRIER 3 & ASTROL 1 flagged in connection with Copenhagen drone incidents; Aleksandr Shabalin loitering near Danish islands) as suspicious due to unusual tracks, crew profiles, and timing relative to drone events. Analysts suggest a recurring pattern of shiplaunched or shipsupported drone operations in both the Baltic and elsewhere. (See Ocean Trader sightings: https://x.com/sentdefender/status/1971435498628346264 and suspected Copenhagen links: https://x.com/auonsson/status/1971678884270920140 and https://x.com/MT_Anderson/status/1971253403931013121.)
- UkraineRussia battlefield & infrastructure dynamics: OSINT and analytical outlets continue to record Ukrainian tactical advances (Dobropillya, parts of Kharkiv/Donetsk axes) alongside Russian local advances; parallel asymmetric targeting of Russian fuel/refining and logistics nodes by Ukrainian drones and USV strikes has generated gasoline shortages and refinery outages in several Russian regions and the occupation areas. The Zaporizhzhia NPPs repeated loss of offsite power remains an acute safety and escalation concern. (See battlefield/strikes reporting: https://x.com/criticalthreats/status/1970652850993950801 and refinery/fuel shortage: https://x.com/criticalthreats/status/1971411693352910966; Zaporizhzhia power loss: https://x.com/sentdefender/status/1970523733766111415.)
Other notable developments
- USSTRATCOM & allied strategic signaling: visible use of strategic assets (B2 deployments, SLBM Trident II tests, E6 TACAMO flights, and NATO/partner AEW/ISR flights) and French nuclear exercises — pointing to high-level deterrent signaling alongside regional contingency posture. (See Trident tests: https://x.com/sentdefender/status/1970511374338957797 and E6/COST43 mission: https://x.com/sentdefender/status/1970690889090564343.)
- Law, politics and security: House Oversight receipt of Epstein estate documents with schedules and flight manifests (see: https://x.com/sentdefender/status/1971683592959832384); Secret Service takedown of a massive SIM server/card network near UNGA (https://x.com/sentdefender/status/1970470725677883797); and a deadly shooting at an ICE detention facility in Dallas that remains under investigation (https://x.com/sentdefender/status/1970836229793993129).
- Diplomacy & recognitions: multiple states (UK, Australia, Canada, Portugal, and others) announced recognition of a Palestinian state and several highlevel bilateral meetings occurred at UNGA (e.g., TrumpErdogan, TrumpZelensky, ZelenskySyrian president), shaping regionally consequential diplomatic maneuvering. (See UK/Australia/Canada recognition note: https://x.com/sentdefender/status/1969830784774050211 and ZelenskyalSharaa meeting: https://x.com/sentdefender/status/1970964419564691691.)
Concluding assessment: OSINT over this window shows simultaneous escalation and signaling across multiple theaters. Drone and greyzone activity is rising as an operational tool (affecting civil aviation and maritime security), strategic platforms are being used for overt deterrence signaling, and political decisions (UN snapback, export/usage policy discussions for longrange weapons) are tightly coupled to ontheground operations. These interconnected events increase the risk of rapid escalation and miscalculation, especially in Europe (NATORussia interactions) and the Middle East (Iran/HouthiIsrael exchanges). Continued monitoring of attribution (drone origin, ship operations), nuclearrelated safety indicators (Zaporizhzhia power status), and diplomatic/UN developments (Iran/IAEA/sanctions) is recommended.

View File

@ -0,0 +1,32 @@
Direct answer: This week saw a mix of heightened security and military signaling around Venezuela, diplomatic positioning, and unrelated seismic activity. The most consequential items were reporting that U.S. planners have drawn up options to target drug-trafficking networks inside Venezuela (including possible drone strikes) and Venezuelan naval exercises conducted extremely close to Trinidad and Tobago — both of which raised regional tensions and drew public responses from nearby states and allies.
Key themes and topics:
- U.S. counternarcotics military options: Reporting cites U.S. planning to target cartels and drug-trafficking infrastructure inside Venezuela, with drone strikes against group members, leaders, and drug labs potentially starting 'in a matter of weeks' (report referenced in this tweet: [U.S. planning options to target cartels inside Venezuela](https://x.com/sentdefender/status/1971699413010501658)). This is framed as a Department of War-level planning process in media coverage.
- Venezuelan military signaling at sea: Venezuelas navy held exercises at Isla de Patos, about 6.2 miles from Trinidad and Tobago, using Peykaap III-class missile attack craft plus landing ships Capana and Los Hermanos and patrol boat Serreta — an operation flagged as potentially provocative to nearby states ([naval exercise tweet](https://x.com/SA_Defensa/status/1971618440164397301); context pinning the position to Trinidads coast: [context tweet](https://x.com/SA_Defensa/status/1971619622823788805)).
- Regional diplomatic and political positioning: Political messaging about Venezuelas government and security threat to the U.S. circulated (example retweet criticizing Venezuelas regime: [RepCarlos retweet](https://x.com/RepCarlos/status/1971693293470658586)). Cubas deputy foreign minister publicly said Cuba would not militarily intervene in a U.S.-Venezuela war and would limit support to political backing ([Cuban statement tweet](https://x.com/SA_Defensa/status/1971586496349245903)).
- Natural hazards: The U.S. Geological Survey recorded a series of earthquakes in northwestern Venezuela this week (reported by Reuters: [four earthquakes](https://x.com/Reuters/status/1971224445504139474)).
- International attention and context: The UN General Assembly convenings and other global diplomatic/newsmaker events provided a backdrop for any Venezuela-related diplomacy ([UNGA coverage](https://x.com/Reuters/status/1971555330787312064)). Reuters also noted related maritime/activist press events this week ([Global Sumud Flotilla conference](https://x.com/Reuters/status/1971199814915494231)).
Notable patterns and trends:
- Escalation of security options: Media reporting that U.S. planners are preparing kinetic options (including drone strikes) marks a shift toward more overt consideration of military action for counter-narcotics goals. The language about operations possibly beginning 'in a matter of weeks' increases the immediacy and risk of near-term action ([source](https://x.com/sentdefender/status/1971699413010501658)).
- Close-proximity maritime posturing: Venezuelan naval activity very near Trinidads territorial waters signals stepped-up readiness and a willingness to operate close to neighbors, raising the risk of miscalculation or diplomatic fallout ([naval exercise details](https://x.com/SA_Defensa/status/1971618440164397301)).
- Regional alignment and limits: Cuba publicly drew a line at military intervention while offering political support to Caracas, suggesting allies may pursue diplomatic and rhetorical backing but avoid direct military involvement ([Cuban deputy FM statement](https://x.com/SA_Defensa/status/1971586496349245903)).
- Continued humanitarian/security framing: U.S. political actors and commentators continue to frame Venezuelas government as a threat to regional stability and U.S. security, reinforcing support for tougher measures in some U.S. policy circles ([political messaging](https://x.com/RepCarlos/status/1971693293470658586)).
Important mentions, interactions, and data points:
- NBC-sourced reporting (via the sentdefender tweet) claims the U.S. Department of War has options that include drone strikes against drug traffickers and labs inside Venezuela and that such strikes could begin soon ([link](https://x.com/sentdefender/status/1971699413010501658)). These are media reports based on sources and should be treated as unconfirmed official action until government statements follow.
- The Venezuelan navy exercise location: Isla de Patos, ~6.2 miles from Trinidad and Tobago, involving 3 Peykaap III-class missile attack craft plus landing ships Capana & Los Hermanos and patrol boat Serreta, highlighted proximity to Trinidad ([exercise tweet](https://x.com/SA_Defensa/status/1971618440164397301)). Analysts flagged the exercise as potentially aimed at signaling after diplomatic friction with Trinidad and over posture toward Guyana ([context tweet](https://x.com/SA_Defensa/status/1971619622823788805)).
- Cubas Deputy Foreign Minister Carlos Fernández de Cossío explicitly said Cuba would not provide military intervention in the event of U.S.-Venezuela hostilities and would only offer political support ([Cuban statement tweet](https://x.com/SA_Defensa/status/1971586496349245903)).
- Seismic events: USGS reported four earthquakes in northwestern Venezuela this week (reported by Reuters: [earthquakes](https://x.com/Reuters/status/1971224445504139474)).
- Global diplomatic backdrop: World leaders gathered at the UN General Assembly this week, where Venezuela-related diplomacy and messaging were likely part of the broader agenda ([UNGA coverage](https://x.com/Reuters/status/1971555330787312064)).
Significant events (each in a paragraph):
1) U.S. planning to target drug traffickers inside Venezuela: Media reports this week said U.S. planners have developed options that would strike drug-trafficking networks inside Venezuela, potentially using drones against personnel, leadership, and drug labs, with operations possibly beginning within weeks. If accurate, this signals a readiness by U.S. planners to take direct kinetic action on Venezuelan soil for counternarcotics purposes and raises immediate regional and diplomatic risks; the report is from sources to NBC and was summarized on social media ([report tweet](https://x.com/sentdefender/status/1971699413010501658)). These remain reported planning options rather than publicly confirmed government orders.
2) Venezuelan naval exercises close to Trinidad and Tobago: Venezuela conducted naval maneuvers at Isla de Patos (about 6.2 miles from Trinidad), employing Peykaap III missile boats and landing ships. The proximity to Trinidad — which has recently criticized Venezuela over drug-related issues and regional posture — was read as a provocative signal and has the potential to increase tensions with nearby Caribbean states ([exercise details and context](https://x.com/SA_Defensa/status/1971618440164397301), https://x.com/SA_Defensa/status/1971619622823788805).
3) Cubas public stance and regional diplomatic signals: Cuba stated it would not militarily intervene in a hypothetical U.S.-Venezuela war, offering only political support to Caracas. That public clarification delineates limits to what allies of Venezuela might do and influences regional calculations ([Cuban statement](https://x.com/SA_Defensa/status/1971586496349245903)).
4) Seismic activity in northwestern Venezuela: The USGS recorded a cluster of four earthquakes in northwestern Venezuela this week, reported by Reuters, representing a separate, non-political development affecting communities in that region ([earthquakes](https://x.com/Reuters/status/1971224445504139474)).
Bottom line: The weeks coverage centered on increasing security tensions — notably reports that the U.S. is preparing kinetic counter-narcotics options impacting Venezuela and Venezuelan naval exercises near Trinidad that could worsen regional frictions — alongside diplomatic signaling (Cubas public limits on intervention) and unrelated natural seismic events. Much of the most consequential reporting (particularly on U.S. strike planning) is based on media-sourced leaks or official framing and should be watched for confirmation from government statements and follow-up reporting.

View File

@ -0,0 +1,42 @@
Direct answer — snapshot: Last weeks biorisk headlines were dominated by expanding animal-human and vector-borne threats (notably H5N1 avian influenza in poultry and pet cats, and multiple mosquito-borne threats), a continued severe pediatric influenza season in the U.S., a large and growing U.S. measles burden, and multiple acute outbreak responses (cholera, Ebola, dengue). Concurrent themes included zoonotic spillovers linked to animal food chains (raw pet food), seasonal respiratoryvirus activity and vaccine updates, rising surveillance activity (wastewater and continent-level surveillance plans), and growing attention to antimicrobial resistance and exotic pest threats (New World screwworm). Key items and notable events (each with a representative tweet):
Major events and highrisk developments
- HPAI H5N1 activity in poultry and domestic animals, and rawpetfood linkage: Several confirmations of highly pathogenic avian influenza in U.S. commercial flocks and a cluster of domestic cat deaths in Los Angeles tied to raw cat food drew major attention. Examples: Utah commercial turkey facility HPAI confirmation [FluTrackers](https://x.com/FluTrackers/status/1971679291651010604), reports on an LA County domesticcat cluster linked to raw food and a B3.13 genotype in one cat [FluTrackers](https://x.com/FluTrackers/status/1971613912371233234) and coverage noting cat deaths prompting warnings about raw pet food [CIDRAP](https://x.com/CIDRAP/status/1971643140143562856). Pattern/trend: multiple Midwestern and West Coast poultry detections plus domestic carnivore infections indicate ongoing spillover risk and raise concern about crossspecies exposure pathways (including contaminated raw diets). Authorities and animalhealth messaging urged avoidance of sick/dead wild birds and caution around raw pet foods.
- Record/very severe pediatric influenza season in the U.S.: CDC reports and MMWR coverage highlighted this season as one of the deadliest for U.S. children in over a decade, with one report noting the seasons pediatric death count (MMWR/CIDRAP reporting). Representative coverage: CDC/CIDRAP summary of the 202425 seasons deadly impact on kids and related MMWR analyses [CIDRAP](https://x.com/CIDRAP/status/1971677247653232892). Pattern: unusually high pediatric morbidity/mortality from influenza this season, prompting renewed emphasis on vaccination and pediatric surveillance.
- Large and expanding measles activity and surveillance improvements: U.S. measles counts rose (CDC confirmed 23 more cases; 2025 totals topped ~1,500 per CIDRAP reporting) with clusters in multiple states including Utah (cases reached 41) and new linked cases in Georgia; pockets of low MMR uptake remain a driver. Representative links: CDC measles wastewater data rollout [CDC_NCEZID](https://x.com/CDC_NCEZID/status/1971628493545890143) and CIDRAPs tally note [CIDRAP](https://x.com/CIDRAP/status/1970956930991407303). Pattern: outbreaks concentrated where vaccine coverage is low or delayed; publichealth agencies are adding early warning tools (wastewater) to detect and act on community spread.
- Cholera and other enteric outbreaks & responses: New or recurrent cholera alerts were reported in multiple regions — Mozambiques Moma district declared cholera again [FluTrackers](https://x.com/FluTrackers/status/1971680265174241512), and CIDRAP noted surges in Chad with a vaccine campaign launching in Sudan [CIDRAP](https://x.com/CIDRAP/status/1971306707872625084). Trend: conflict and access barriers complicate vaccination and response in parts of Africa, driving reactive campaigns.
- New Ebola outbreak in DRC worsening and funding concerns: Reporting flagged a new Ebola cluster in Congo with rising deaths and warnings about insufficient funds for response [statnews](https://x.com/statnews/status/1971392558493323654). Significance: persistent Ebola risk in DRC with resource constraints remains a major biorisk concern for regional and global responders.
Other notable biologicalrisk items and trends
- Dengue hotspots and severe presentations: Multiple countries reported surges — Pakistan (Islamabad/Rawalpindi), Bangladesh (many fatalities occurring within 24 hours of admission), Nepal (~5,000 cases, 2 deaths), and worsening dengue plus chikungunya in Cárdenas, Cuba [FluTrackers Pakistan/dengue posts: https://x.com/FluTrackers/status/1971435727746727946; https://x.com/FluTrackers/status/1971433243909177451; https://x.com/FluTrackers/status/1971433524059410479; https://x.com/FluTrackers/status/1971433797922193579]. Pattern: seasonal dengue surges with severe/fatal cases linked to delayed care and strained local systems.
- Vectorborne and zoonotic detections beyond avian flu: First Powassan virus case in Illinois (tickborne) and added West Nile human cases in Massachusetts were reported [FluTrackers Powassan: https://x.com/FluTrackers/status/1971432681964745098; FluTrackers West Nile: https://x.com/FluTrackers/status/1971679631767192007]. Also CrimeanCongo hemorrhagic fever detected in animals in southern France [CIDRAP](https://x.com/CIDRAP/status/1971248176947466365). Trend: wide geographic distribution of zoonotic and tick/mosquitoborne risks as vectors remain active.
- Invasive pest threat (New World screwworm): USDA announced a fiveprong plan to protect livestock from New World screwworm as the outbreak spreads northward; CDC provided public education on NWS biology and risk [FluTrackers USDA plan: https://x.com/FluTrackers/status/1971445608033722388; CDC_NCEZID NWS info: https://x.com/CDC_NCEZID/status/1970849716553310435]. Significance: reestablishment of screwworm would have large agricultural and publichealth consequences.
- Surveillance, policy, and preparedness moves: WHO/flu vaccine composition updates for the Southern Hemisphere were announced and discussed [CIDRAP](https://x.com/CIDRAP/status/1971645267481870402); CDC expanded measles wastewater reporting [CDC_NCEZID](https://x.com/CDC_NCEZID/status/1971628493545890143); Africa CDC launched initiatives (continental sickle cell campaign, AMR community of practice, surveillance advisory group) and convenings at UNGA emphasizing preparedness and local manufacturing [AfricaCDC sickle cell: https://x.com/AfricaCDC/status/1971454730342744507; AfricaCDC CSAG: https://x.com/AfricaCDC/status/1970065814385553730]. Pattern: greater emphasis on early detection, One Health integration, and regional capacity building.
- Antimicrobial resistance and downstream risks: Studies and programs highlighted AMR concerns — outpatient antibiotic use after COVID linked to later resistant organisms, and Africa CDC/partners pushing AMR surveillance and stewardship [CIDRAP antibiotic-resistance note: https://x.com/CIDRAP/status/1970953206726303984; AfricaCDC AMR COP: https://x.com/AfricaCDC/status/1970488976319344687].
Important data points and mentions to note
- Pediatric influenza: CDC/MMWR analyses indicated this influenza season is one of the deadliest for U.S. children in more than a decade; reporting included pediatric death counts and encephalopathy signals [CIDRAP MMWR summary: https://x.com/FluTrackers/status/1971606509500137477; https://x.com/CIDRAP/status/1971677247653232892].
- U.S. measles: CDC confirmed 23 additional cases in one update, bringing national 2025 counts past ~1,500 in CIDRAP reporting [CIDRAP](https://x.com/CIDRAP/status/1970956930991407303).
- H5N1: Multiple commercial poultry detections (Utah, Minnesota, Wisconsin outbreaks part of a Midwest rise) and domestic cat cases; genotype B3.13 identified in at least one LA cat sample — sequencing underway for others [FluTrackers Utah: https://x.com/FluTrackers/status/1971679291651010604; FluTrackers Minnesota: https://x.com/FluTrackers/status/1971622126517113161; CIDRAP Wisconsin poultry: https://x.com/CIDRAP/status/1971310357546139778; CIDRAP LA cats: https://x.com/CIDRAP/status/1971643140143562856].
- Cholera and outbreak response: Mozambique redeclared outbreak in Moma district; Chad experiencing surges and Sudan launching a 1.86Mperson campaign in Darfur per CIDRAP [FluTrackers Mozambique: https://x.com/FluTrackers/status/1971680265174241512; CIDRAP Chad/Sudan: https://x.com/CIDRAP/status/1971306707872625084].
Significant announcements/organizational actions
- WHO/flu vaccine composition for Southern Hemisphere and WHO/UNGA statements on NCDs and health facility protection in conflict zones (Dr Tedros) — these shape seasonal vaccine policy and global health advocacy [CIDRAP vaccine update: https://x.com/CIDRAP/status/1971645267481870402; WHO DrTedros speech link: https://x.com/WHO/status/1971654608746430499].
- Africa CDC: continental initiatives launched and briefed at UNGA (sickle cell campaign, surveillance advisory group, AMR community of practice) signaling regional capacitybuilding and continental policy momentum [AfricaCDC sickle cell: https://x.com/AfricaCDC/status/1971454730342744507; AfricaCDC CSAG: https://x.com/AfricaCDC/status/1970065814385553730].
- USDA and U.S. animalhealth responses: stepping up measures for screwworm containment and vigilance around HPAI in commercial flocks [FluTrackers USDA plan: https://x.com/FluTrackers/status/1971445608033722388].
Concluding assessment and short outlook
Last week emphasized the breadth of modern biorisk: simultaneous animalhuman spillovers (H5N1 in poultry/cats), intense seasonal human respiratory disease impact (severe pediatric influenza; rising measles), and classic outbreak hotspots for enteric (cholera) and vectorborne (dengue, West Nile, Powassan) pathogens. Trends to watch in the near term: further H5N1 detections in domestic animals or poultry (and any evidence of wider mammal transmission), pediatric flu hospitalization and mortality trends as the season progresses, expansion of measles clusters in undervaccinated communities, the trajectory of the new Ebola event in DRC (and funding response), and effectiveness of surveillance upgrades (wastewater, genomic sequencing) and regional preparedness initiatives (Africa CDC, USDA).

View File

@ -0,0 +1,34 @@
Direct answer: Last weeks reported technological developments centered on energy-efficient computing (new chip designs and waste-heat recovery), progress in quantum hardware, rapid spread of AI into forensic and healthcare workflows (and the attendant safety/ethics concerns), translational biotech clinical advances and biosensing, plus a handful of consumer hardware and connectivity upgrades.
Key themes and topics
- Energy and sustainability in computing: a test chip that recycles otherwise wasted heat energy for potential AI-cost reductions and reports about recovering data-center waste heat. See the Ice River chip coverage (ScienceNews) [test chip recycles energy](https://x.com/ScienceNews/status/1971556657428672963) and the related post about energy-recovering chips [Ice River summary](https://x.com/ScienceNews/status/1971346518427759076); data-center waste-heat recovery was also highlighted [data centers recover 8% via solar](https://x.com/NewsfromScience/status/1971252117152166215).
- AI adoption, misuse and governance: investigations and tooling to detect AI-generated illegal content, concerns about LLMs using tainted or retracted training data, and experimentation with LLMs in medical and editorial workflows. Relevant items: US investigators using AI to detect AI-made child-abuse images (techreview) [AI to detect AI-made abuse images](https://x.com/techreview/status/1971658627321667655), AI models using retracted papers as training data (techreview) [retracted-paper issue](https://x.com/techreview/status/1970422703887642664), and LLMs in clinical/administrative roles (techreview) [LLM startup for appointments](https://x.com/techreview/status/1970055743102386677).
- Quantum and superconducting hardware: demonstration of a superconducting-qubit-based quantum router that could advance quantum networking and computing [quantum router device](https://x.com/Newscientist/status/1971638638229303635).
- Biotech and translational medicine: early clinical signals and biosensing advances — a small trial using a viral vector to deliver RNA for Huntingtons, continuous protein monitoring wearables, pasteurization fully inactivating H5N1 in milk, and new bacteriophage-hunting approaches [Huntington trial](https://x.com/ScienceNews/status/1971643531002298838) [continuous protein monitoring podcast](https://x.com/ScienceMagazine/status/1971609274112495865) [H5N1 pasteurization](https://x.com/ScienceNews/status/1971651267064734086) [phage search in zoo feces](https://x.com/ReutersScience/status/1971590586432979441).
- Consumer hardware and connectivity: very lightweight gaming mice, WiFi 7 household upgrades for low cost, and attention to modular phone charging ecosystems (MagSafe/Qi2). Examples: Corsairs ultra-light gaming mouse (WIRED) [Corsair mouse](https://x.com/WIRED/status/1971683701382635555), $130 whole-house WiFi 7 upgrade (WIRED) [WiFi 7 deal](https://x.com/WIRED/status/1971646860231106749), and MagSafe accessory coverage [MagSafe picks](https://x.com/WIRED/status/1971382213712158724).
Notable patterns and trends
- Convergence on energy-efficiency: multiple stories framed hardware innovation around reducing AI and data-center energy costs (energy-recycling chips and waste-heat capture), and even broader interest in fusion financing as part of long-term energy tech momentum (see financing item below).
- Dual-use and governance pressures around AI: sizable reporting on both deploying AI (forensics, medical assistants, proposal triage) and the risks (training on retracted material, LLMs being susceptible to prompts that enable cheating, and effects on vulnerable languages).
- Rapid lab-to-clinic movement in biotech: the week included early clinical interventions (Huntingtons trial) alongside enabling tools like continuous-protein monitoring and neutralizing antibodies studies — a pattern of tightly coupled discovery and translational work.
- Hardware diversification: advances ranged from physically tiny consumer devices to large-scale quantum hardware, indicating parallel progress at different computing scales.
Important mentions, interactions, and data points
- Ice River test chip that recycles wasted heat energy — pitched as a path to making AI cheaper and more efficient [ScienceNews](https://x.com/ScienceNews/status/1971556657428672963). The chip was reported multiple times and positioned as a notable prototype-level step toward greener AI.
- Commonwealth Fusion Systems secured a major commercial/industry tie-up that signals finance and corporate interest in fusion commercialization (coverage and deal commentary) [fusion deal coverage](https://x.com/techreview/status/1970089159017513274).
- A superconducting-qubit device demonstrated a new kind of quantum router, highlighting progress toward scalable quantum networks and components for quantum computing [quantum router](https://x.com/Newscientist/status/1971638638229303635).
- U.S. investigators are deploying AI to detect child-abuse imagery generated by AI, showing a growing need for AI-for-forensics solutions as synthetic content proliferates [AI to detect AI-made abuse images](https://x.com/techreview/status/1971658627321667655).
- LLMs continue to be trialed in editorial and scientific workflows: Science magazine reported an editorial experiment testing ChatGPT for science writing assistance (ScienceMagazine) [ChatGPT test for science writers](https://x.com/ScienceMagazine/status/1971481138834071983) while other outlets flagged risks such as reliance on retracted papers in AI training datasets (techreview) [retracted papers issue](https://x.com/techreview/status/1970422703887642664).
- Medical and biosensing strides included promising Huntingtons prevention signals from a small viral-RNA brain-injection trial (ScienceNews) [Huntington trial](https://x.com/ScienceNews/status/1971643531002298838), and continued interest in wearables that enable continuous protein monitoring (ScienceMagazine) [protein monitoring podcast](https://x.com/ScienceMagazine/status/1971609274112495865).
Significant events / developments (each summarized)
- Energy-recycling AI test chip (Ice River): A test chip nicknamed Ice River was reported to recycle energy that conventional chips lose as heat, positioned as a potential lever to lower the energy and cost footprint of AI workloads. This prototype-level hardware drew attention as a concrete step toward more sustainable AI infrastructure [ScienceNews coverage](https://x.com/ScienceNews/status/1971556657428672963).
- Major commercial financing/tie-up in fusion: Commonwealth Fusion Systems attracted a large industry deal (reported as a $1 billion-style commercial partnership), illustrating continued private-sector confidence and capital flows into fusion ventures even as commercial fusion plants remain years away. Coverage framed this as part of fusions maturation into financeable commercial projects [techreview coverage](https://x.com/techreview/status/1970089159017513274).
- Superconducting-qubit quantum router demonstration: Researchers reported a device built from superconducting qubits that behaves as a quantum router — a new hardware class that could be important for practical quantum networking and certain quantum computing architectures, moving quantum experiments closer to usable networked systems [Newscientist report](https://x.com/Newscientist/status/1971638638229303635).
- AI applied to forensic detection of synthetic abuse imagery: U.S. investigators have begun using AI tools to detect child-abuse images produced by other AI systems, highlighting both the emergent threat of harmful synthetic content and the rapid application of AI to counteract AI-enabled misuse [techreview report](https://x.com/techreview/status/1971658627321667655).
Overall assessment / takeaway
The weeks reporting shows a technology landscape where energy efficiency and sustainability are driving hardware innovation (chips, data centers, and even fusion financing), AI is expanding into practically every domain (forensics, healthcare, editorial workflows) but bringing governance and data-integrity concerns, quantum hardware is moving from component demonstrations toward networkable devices, and biotech advances continue to translate into early clinical steps and new sensing capabilities. Consumer-side improvements (lightweight peripherals, WiFi 7 upgrades, MagSafe ecosystems) were present but less dominant than the broader infrastructure, AI, quantum, and biotech stories.

View File

@ -0,0 +1,44 @@
Direct answer
Last weeks notable cyberattack news centered on: a widespread supply-chain compromise in the JavaScript ecosystem by a selfreplicating worm called ShaiHulud; a cloud backup compromise affecting MySonicWall driven by bruteforce access; addition of a Chrome V8 typeconfusion vulnerability (CVE202510585) to CISAs Known Exploited Vulnerabilities catalog; CISA-led incident response and published lessons after malicious activity at a U.S. federal agency; and ongoing emphasis on community resilience exercises. Key public posts and alerts were shared by @CISAgov and allied CISA accounts highlighting these developments (see linked posts below).
Key themes and topics
- Supplychain and softwarerepository risk: the ShaiHulud worm that compromised hundreds of JavaScript packages underscores ongoing risks in package registries and the potential for rapid, automated propagation. (See report shared by CISA/CISA Cyber: https://x.com/CISAgov/status/1970825700358881444)
- Credential/authorization weaknesses and cloud backups: the MySonicWall incident involved bruteforce access to cloud backup files, highlighting weak authentication/passwordmanagement and exposed backup stores as highvalue targets (https://x.com/CISAgov/status/1970228819211473154).
- Vulnerability tracking and prioritization: CISA added Google Chrome V8 typeconfusion vulnerability CVE202510585 to its Known Exploited Vulnerabilities Catalog, signaling active exploitation or urgent risk and prompting rapid patching and mitigation actions (https://x.com/CISAgov/status/1970564120538947906).
- Incident response, transparency, and learning: CISA described launching response efforts after a federal agency detected malicious activity and published lessons/mitigations — emphasizing rapid response, interagency coordination, and sharing of defensive guidance (https://x.com/CISAgov/status/1970494370735353861).
- Community preparedness and resilience: CISA participated in a local Community Resilience Analysis Tabletop Exercise with Minot, ND and Ward County Emergency Management to assess combined physical and cyber response and shortterm recovery (https://x.com/CISAgov/status/1971596067582926986).
Notable patterns and trends
- Increasing focus on supplychain integrity: automated worms and compromised packages continue to threaten opensource ecosystems, amplifying impact across many downstream projects. The ShaiHulud event fits a growing pattern of package registry abuse.
- Attackers exploiting weak access controls and automated credential attacks: bruteforce compromises of cloud services/backups remain a recurring vector (MySonicWall incident).
- Faster operationalization of vulnerability intelligence: CISAs quick addition of CVE202510585 to the KEV catalog shows an emphasis on rapidly prioritizing and communicating vulnerabilities that are known or likely to be exploited.
- Emphasis on postincident sharing: CISA is leaning on public alerts, catalogs, and published lessons to accelerate defender response and patching across affected communities.
Important mentions, interactions, and data points
- ShaiHulud reportedly compromised over 500 packages in the JavaScript registry (reported via CISA/CISA Cyber repost) — a large-scale, supplychain impact (https://x.com/CISAgov/status/1970825700358881444).
- CVE202510585 (Google Chrome V8 type confusion) was added to CISAs Known Exploited Vulnerabilities Catalog; inclusion typically signals active exploitation or severe risk requiring immediate mitigation (https://x.com/CISAgov/status/1970564120538947906).
- MySonicWall cloud backup incident involved a malicious actor using bruteforce to gain access to backup files — incident led to a CISA alert with recommended mitigations (https://x.com/CISAgov/status/1970228819211473154).
- CISA launched incident response after malicious activity at a U.S. federal agency and published lessons learned and mitigations — an important example of federal-level detection, response, and public guidance (https://x.com/CISAgov/status/1970494370735353861).
- CISA engaged with local partners in a Community Resilience Analysis Tabletop Exercise examining combined physical and cyber impacts and shortterm recovery (https://x.com/CISAgov/status/1971596067582926986).
Significant events (each summarized)
- ShaiHulud worm compromising JavaScript packages: A selfreplicating worm known as ShaiHulud compromised more than 500 packages in the worlds largest JavaScript registry, demonstrating how quickly supplychain malware can spread and contaminate many downstream projects. This event heightens urgency for packagesecurity measures (signing, provenance, stricter publishing controls) and for maintainers to audit dependencies (https://x.com/CISAgov/status/1970825700358881444).
- MySonicWall cloud backup file incident: CISA/CISA Cyber released an alert after a malicious actor used bruteforce techniques to access MySonicWall cloud backup files. The incident highlights the need for robust password policies, multifactor authentication, monitoring for unauthorized access, and secure handling of backups; CISA provided mitigations and guidance (https://x.com/CISAgov/status/1970228819211473154).
- CVE202510585 added to CISAs KEV catalog (Chrome V8): CISA added a Google Chrome V8 typeconfusion vulnerability (CVE202510585) to its Known Exploited Vulnerabilities Catalog. Inclusion signals active or imminent exploitation and typically prompts emergency patching and mitigation priorities for organizations using affected Chrome versions (https://x.com/CISAgov/status/1970564120538947906).
- CISA incident response & published lessons after federal agency detection: After a U.S. federal agency detected malicious activity, CISA launched incident response efforts, documented lessons learned, and published mitigations. This public sharing demonstrates federal emphasis on rapid containment, interagency coordination, and postincident learning to help other organizations defend against similar threats (https://x.com/CISAgov/status/1970494370735353861).
Other notable activity
- Community resilience tabletop exercise in Minot, ND: CISA participated in and thanked local partners for hosting a Community Resilience Analysis Tabletop Exercise to assess joint response plans and shortterm recovery for incidents with both physical and cyber impacts — signaling continued investment in local preparedness and wholecommunity coordination (https://x.com/CISAgov/status/1971596067582926986).
Bottom line
Last week reinforced three practical takeaways: 1) protect the software supply chain and monitor dependencies for malicious changes; 2) harden authentication and backup access to prevent bruteforce and credentialbased intrusions; and 3) promptly apply patches/mitigations for vulnerabilities flagged as actively exploited (as reflected by CISA KEV listings), while leveraging shared incidentresponse lessons and local preparedness exercises to improve resilience.
Sources
- ShaiHulud supplychain compromise (CISA repost): https://x.com/CISAgov/status/1970825700358881444
- CVE202510585 added to KEV: https://x.com/CISAgov/status/1970564120538947906
- MySonicWall cloud backup alert: https://x.com/CISAgov/status/1970228819211473154
- CISA incident response and lessons: https://x.com/CISAgov/status/1970494370735353861
- Community Resilience Tabletop Exercise (Minot, ND): https://x.com/CISAgov/status/1971596067582926986

View File

@ -0,0 +1,37 @@
Direct answer
Last weeks climate developments centered on three connected threads: (1) high-profile diplomacy and new national pledges at UN/Climate Week events, (2) continued extreme-weather events tied to human-driven warming and growing evidence of health and economic harms, and (3) an intensifying political clash over U.S. climate policy and science — with defenders of climate research pushing back against federal rollbacks. Key news also highlighted renewable growth, finance for nature and agriculture, and new analyses showing how warming is already reshaping everyday life.
Key themes and topics
- International diplomacy and pledges: Multiple reports and briefings from UNFCCC and CarbonBrief noted significant new national commitments after the UN summit: around 100 Parties representing roughly two-thirds of global emissions submitted or unveiled new NDCs [see UNFCCC](https://x.com/UNFCCC/status/1971146057406091320) and CarbonBriefs analysis that half of global emissions are now covered by 2035 pledges after the summit [see CarbonBrief](https://x.com/CarbonBrief/status/1971549259968221503). China also announced a new Paris-related pledge and became a focus of analysis and webinars by CarbonBrief [see CarbonBrief](https://x.com/CarbonBrief/status/1971548564628160550).
- Extreme weather and attribution: Super Typhoon Ragasa underwent extreme rapid intensification (≈137 kph in ~24 hrs) and was linked to unusually warm ocean waters that were made much more likely by human-caused warming [see ClimateCentral](https://x.com/ClimateCentral/status/1971233683622502557) and related ocean temperature reporting [see ClimateCentral](https://x.com/ClimateCentral/status/1971233688466940345). Europe and other regions also experienced exceptional heat, and tropical systems (Humberto, potential Imelda, Hurricane Gabrielle threatening the Azores/Iberia) were highlighted by trackers and reporters [see ClimateCentral on Humberto/Imelda](https://x.com/ClimateCentral/status/1971615057797882206) and [PGDynes on Gabrielle](https://x.com/PGDynes/status/1971271149146472527).
- Health, generational impacts, and socioeconomic costs: Several pieces drew attention to human impacts — from generational exposure to extreme heat (Climate Central: Gen Z children have experienced ~2x more extremely hot days than millennials and ~4x more than Gen X across 247 U.S. cities) [see ClimateCentral](https://x.com/ClimateCentral/status/1971690706231328979), to maternal and birth risks rising with extreme heat [see ClimateCentral](https://x.com/ClimateCentral/status/1971649808915222812). New research threads also tied EV adoption to reductions in very low birth-weight births (quoted study summary) and estimated enormous lifetime climate costs for Californians born today ($500k$1M additional costs) [see dwallacewells](https://x.com/dwallacewells/status/1971631139296301389) and [see dwallacewells on EV study](https://x.com/dwallacewells/status/1971664119779807602).
- Energy transition and clean tech momentum vs. policy pushback: Data and reporting showed strong growth in U.S. solar and wind generation (enough to power tens of millions of homes), expanding electric school buses, and continuing declines in coal/gas share for electricity [see ClimateCentral thread](https://x.com/ClimateCentral/status/1970941713305960747). At the same time, U.S. federal rollbacks and political attacks on clean-energy incentives and regulations (and on the EPA endangerment finding) drew criticism from scientists and advocacy groups [see ClimateReality on Endangerment Finding and DOE panel](https://x.com/ClimateReality/status/1971605796057206972) and multiple scientist responses to the Presidents UN remarks [see MichaelEMann](https://x.com/MichaelEMann/status/1971573846882070975) and [rahmstorf](https://x.com/rahmstorf/status/1970745593216545027).
- Climate finance, nature, and agriculture: FAO and partners highlighted tools and projects linking adaptation, agrifood systems, and climate finance (new CAR tool, projects in Senegal and Iraq, bioeconomy at G20) [see FAOclimate CAR tool](https://x.com/FAOclimate/status/1971605725148319991) and [FAOclimate Iraq SRVALI](https://x.com/FAOclimate/status/1970906895801266294). CarbonBrief flagged UK aid rising to record levels partly driven by carbon-credit funding and continued analysis of the role of finance and nature-based solutions [see CarbonBrief](https://x.com/CarbonBrief/status/1971653005175816403).
Notable patterns and trends
- Attribution and rapid intensification: Reports repeatedly connected exceptional storm intensification and unusually warm sea-surface temperatures to human-caused warming (e.g., Ragasa), indicating an ongoing pattern of stronger, faster-developing tropical systems where warm ocean anomalies exist [see ClimateCentral](https://x.com/ClimateCentral/status/1971233683622502557).
- Normalization of overshoot/acceptance debates: Coverage at Climate Week and climate reporting noted a subtle rhetorical shift toward planning for “overshoot” (likely exceeding 1.5°C temporarily), a sign that policymakers and commentators are increasingly preparing for scenarios where 1.5°C is passed before mitigation or removal can bring temperatures down [see insideclimate on Climate Week rhetoric](https://x.com/insideclimate/status/1971234233810387438).
- Increasing linkage between climate and public health/economics: Multiple tweets and articles highlighted growing evidence that climate change is already producing measurable health harms (birth outcomes, maternal health, mental health/brain development) and large economic burdens on current/future generations [see ClimateCentral on maternal health](https://x.com/ClimateCentral/status/1971649808915222812) and [dwallacewells on lifetime costs](https://x.com/dwallacewells/status/1971631139296301389).
Important mentions, interactions, and data points
- Generational Warming Tool and findings: Climate Centrals generational analysis across 247 U.S. cities: Gen Z children experienced ~2× more extreme heat days than millennials and ~4× more than Gen X [see ClimateCentral generational tweet](https://x.com/ClimateCentral/status/1971690706231328979) and a tool link [see ClimateCentral tool](https://x.com/ClimateCentral/status/1971690709515489643).
- City warming examples: Albany, NY warmed ~4.3°F since 1970 [see ClimateCentral](https://x.com/ClimateCentral/status/1971648522593489117); all 30 NFL cities warmed on average 2.8°F during regular season months [see ClimateCentral](https://x.com/ClimateCentral/status/1971291191288439160).
- Super Typhoon Ragasa rapid intensification: ~137 kph strengthening in ~24 hrs, western Pacific SST anomalies +0.71.1°C, event made 1040× more likely by human-caused warming [see ClimateCentral on Ragasa](https://x.com/ClimateCentral/status/1971233683622502557) and [ocean temps](https://x.com/ClimateCentral/status/1971233688466940345).
- UN/NDC progress: ~100 Parties (≈2/3 emissions) submitted updated NDCs; CarbonBrief: pledges now cover ~half global emissions to 2035 [see UNFCCC](https://x.com/UNFCCC/status/1971146057406091320) and [CarbonBrief analysis](https://x.com/CarbonBrief/status/1971549259968221503).
- Policy/administration conflict: Scientific community and advocacy groups mobilized against administration rollbacks and misinformation (NASEM assessment cited to defend the Endangerment Finding; multiple scientists rebutted the Presidents UN statements) [see ClimateReality NASEM tweet](https://x.com/ClimateReality/status/1971605796057206972) and [MichaelEMann op-ed/tweet](https://x.com/MichaelEMann/status/1971573846882070975).
Significant events or announcements (each highlighted)
1) UN/Climate Week outcomes and pledges: Climate Week/UNGA activity drove numerous national announcements and a wave of reporting about NDC updates. The UNFCCC reported ~100 Parties (covering ~2/3 of emissions) submitted or unveiled new climate plans; CarbonBriefs follow-up analysis said new 2035 pledges now cover roughly half of global emissions — a meaningful step for COP30 prep, though analysts caution that many pledges still fall short of 1.5°C pathways [see UNFCCC](https://x.com/UNFCCC/status/1971146057406091320) and [CarbonBrief](https://x.com/CarbonBrief/status/1971549259968221503).
2) Super Typhoon Ragasa and extreme storm attribution: Ragasas extreme rapid intensification and records as one of the years strongest tropical systems was explicitly linked to unusually warm sea-surface temperatures that were many times more likely because of human-driven warming; that event reinforced the weeks broader theme that storms and heat extremes are increasingly intensified by background warming [see ClimateCentral on Ragasa](https://x.com/ClimateCentral/status/1971233683622502557) and [ocean temp thread](https://x.com/ClimateCentral/status/1971233688466940345).
3) U.S. political clashes over climate science and protections: The week featured public confrontation between the U.S. administrations climate messaging and the scientific community. The Presidents UN remarks denying mainstream climate warnings prompted multiple scientist rebuttals, while groups celebrated a legal/scientific pushback (NASEM assessment) that complicates efforts to rescind the EPA Endangerment Finding — a key piece in the administrations regulatory agenda [see MichaelEMann](https://x.com/MichaelEMann/status/1971573846882070975) and [ClimateReality on NASEM](https://x.com/ClimateReality/status/1971605796057206972).
Bottom line
Last week combined diplomatic momentum (new pledges and COP30 preparation) with stark reminders that warming is already changing weather, health, and economies now. Scientific attribution of extreme storms and extensive reporting on health and generational harms strengthened the evidence base; at the same time, political fights over U.S. climate policy and regulatory rollbacks intensified, making the policy outlook uneven even as international commitments and clean-energy deployment continue to advance.

View File

@ -0,0 +1,34 @@
Direct answer — this weeks natural-disaster activity: Multiple active and damaging weather disasters worldwide centered on tropical cyclones (Atlantic hurricanes and a Western Pacific super typhoon), heavy rainfall/flooding events, intense convective storms in the U.S. Southwest, and at least one notable earthquake. The biggest immediate threats are a very powerful Super Typhoon Ragasa in the Western Pacific and an organizing Atlantic system (Invest 94L / Potential Tropical Cyclone Nine, likely to become Tropical Storm Imelda) that threatens heavy, multi-day flooding across the U.S. Southeast.
Key themes and topics
- Tropical activity is high across basins: a Category 5+ super typhoon in the Western Pacific (Ragasa), an intensifying Atlantic hurricane (Humberto), and an organizing Atlantic disturbance (Invest 94L / Potential Tropical Cyclone Nine) that forecasters warn could become Tropical Storm Imelda and bring major rainfall to the Carolinas and Georgia. See reporting on the Bahamas/Invest 94L [Weather Channel thread](https://x.com/weatherchannel/status/1971685713226711336) and on Potential Tropical Cyclone Nine [Weather Channel update](https://x.com/weatherchannel/status/1971691460010578410).
- Flooding is a top hazard this week — from anticipated inland rainfall with Invest 94L (some model runs showing 12+ inches for parts of the Carolinas) to acute flash and urban flooding from severe thunderstorms across the U.S. Southwest and large-scale flooding reported in North Africa and the Caribbean. See the concern for Carolina flooding [US_Stormwatch](https://x.com/US_Stormwatch/status/1971686281638982079) and state preparations in South Carolina [Volcaholic1](https://x.com/Volcaholic1/status/1971686656731426932).
- Intense convective storms: Arizona experienced severe thunderstorms with very large hail and widespread flash-flood warnings in the Phoenix area [US_Stormwatch](https://x.com/US_Stormwatch/status/1971681622333575567).
- Rapid-onset, high-impact events in populated areas: a destructive Western Pacific super typhoon threatening Philippine islands and forcing evacuations in South China/Hong Kong, and a dramatic tornado sighting on Torch Lake in Michigan captured on video. See the typhoon coverage [US_Stormwatch](https://x.com/US_Stormwatch/status/1969924132998619483) and the Torch Lake tornado video [US_Stormwatch](https://x.com/US_Stormwatch/status/1970278879987409289).
- Seismic event: an on-camera interruption by a 6.3 magnitude earthquake in Venezuela was shared by The Weather Channel [Weather Channel](https://x.com/weatherchannel/status/1971303696760754264).
Notable patterns and trends
- An active tropical season across multiple basins: simultaneous major systems are present (Western Pacific super typhoon Ragasa and strengthening Atlantic hurricanes/invests), increasing regional risk. The Weather Channel and storm accounts emphasize repeated tropical threats this week [Weather Channel on Humberto and Imelda](https://x.com/weatherchannel/status/1971413690617303490).
- Flooding as the predominant hazard: multiple posts highlight that with tropical systems, "water is the killer" — many of the highest risks this week are flood-related (long-duration rain totals, flash flooding). Example: model runs suggesting 12+ inches for some Carolina locations from Potential Tropical Cyclone Nine [US_Stormwatch](https://x.com/US_Stormwatch/status/1971686281638982079).
- Increasing intensity of extreme storms: commentary linking very strong storms (e.g., Ragasa) to broader climate trends appears in the discussion about storm frequency and insurance impacts in Hong Kong and the region [PGDynes on Ragasa/climate](https://x.com/PGDynes/status/1970250776833597536).
Important mentions, interactions, and data points
- Super Typhoon Ragasa: described as a Category 5-level super typhoon with sustained winds reported near 165 mph and gusts up to ~200 mph in imagery/timelapses and warnings; remote Philippine islands (Babuyan Islands) and parts of South China were threatened with large-scale evacuations (reports cite ~750,000 people evacuated) as the storm approached landfall [US_Stormwatch timelapse & impact posts](https://x.com/US_Stormwatch/status/1969887603869782200) and [impact report](https://x.com/US_Stormwatch/status/1969924132998619483).
- Invest 94L / Potential Tropical Cyclone Nine (future Imelda): organizing near the Bahamas with tropical-storm alerts expected there, forecasts showing the system slowing near the South Carolina coast and producing heavy multi-day rainfall for the Southeast (some model guidance showing 12+ inches in spots). South Carolina declared a state of emergency ahead of possible effects [Weather Channel updates](https://x.com/weatherchannel/status/1971685713226711336) and [Volcaholic1 on the SC emergency](https://x.com/Volcaholic1/status/1971686656731426932). Forecasters emphasize flood risk over wind (see [US_Stormwatch concern](https://x.com/US_Stormwatch/status/1971686281638982079)).
- Atlantic hurricane Humberto: continuing to strengthen and noted as reaching major-hurricane intensity (Category 3), monitored for further intensification and impacts near Bermuda/Atlantic [Volcaholic1 footage/alert](https://x.com/Volcaholic1/status/1971677437688967446) and Weather Channel updates on Humberto [Weather Channel](https://x.com/weatherchannel/status/1971413690617303490).
- Regional flooding reports: major flooding reported in Algeria (Bordj Bou Arreridj and M'Sila provinces) [Volcaholic1](https://x.com/Volcaholic1/status/1971668887197581560) and in parts of the Dominican Republic (Cienfuegos, Santiago) [Volcaholic1](https://x.com/Volcaholic1/status/1971674180094742900).
- U.S. convective hazards: Arizona hit by severe storms with golf-ballsize hail and widespread flash-flood warnings for Phoenix-area residents [US_Stormwatch](https://x.com/US_Stormwatch/status/1971681622333575567). A dramatic tornado over Torch Lake, Michigan was widely shared on social media [US_Stormwatch](https://x.com/US_Stormwatch/status/1970278879987409289).
- Earthquake: a magnitude 6.3 quake in Venezuela disrupted a livestreamed video and was captured on camera; no broader damage update provided in the tweet [Weather Channel](https://x.com/weatherchannel/status/1971303696760754264).
- Europe threat: a powerful post-tropical/hurricane system (Hurricane Gabrielle) is noted as tracking toward the Azores and possibly bringing tropical-storm conditions to parts of Spain and mainland Portugal [PGDynes](https://x.com/PGDynes/status/1971271149146472527).
Significant events (one-paragraph highlights)
- Super Typhoon Ragasa (Western Pacific): This is the most severe single event reported this week. Ragasa intensified into a Category 45 super typhoon with sustained winds reported around 165 mph and catastrophic gusts up to ~200 mph in imagery and timelapses; it threatened the Babuyan Islands and nearby Philippine areas with catastrophic impact and forced large-scale evacuations in South China and the broader Greater Bay Area as the inner core passed near populated coasts [US_Stormwatch timelapse and impact posts](https://x.com/US_Stormwatch/status/1969887603869782200) and [impact threat to islands](https://x.com/US_Stormwatch/status/1969924132998619483). This event is being framed as an extreme, high-consequence tropical strike with immediate humanitarian and infrastructure risk.
- Invest 94L / Potential Tropical Cyclone Nine (future Imelda) — Southeast U.S. flood threat: A rapidly organizing disturbance near the Bahamas is expected to become a tropical storm (Imelda) and could slow near the South Carolina coast, producing multi-day heavy rainfall and significant flooding risk for Georgia and the Carolinas; some model scenarios show localized 12+ inch totals. State officials preemptively declared emergencies and forecasters repeatedly emphasized flooding as the dominant hazard rather than wind, urging preparations and tropical-storm/hurricane readiness [Weather Channel coverage](https://x.com/weatherchannel/status/1971685713226711336), [Potential Tropical Cyclone Nine summary](https://x.com/weatherchannel/status/1971691460010578410), and the U.S. Stormwatch concerns on heavy rain/flooding [US_Stormwatch](https://x.com/US_Stormwatch/status/1971686281638982079).
Other notable impacts and developments
- Flooding events reported in Algeria and the Dominican Republic this week indicate widespread heavy-rain impacts beyond tropical basins [Algeria flooding](https://x.com/Volcaholic1/status/1971668887197581560) and [Dominican Republic flooding](https://x.com/Volcaholic1/status/1971674180094742900).
- Severe thunderstorms with very large hail and flash-flood warnings affected Arizona (Phoenix metro) and a dramatic tornado was filmed on Torch Lake, Michigan, illustrating the broad range of convective hazards occurring this week [Arizona storms](https://x.com/US_Stormwatch/status/1971681622333575567) [Torch Lake tornado](https://x.com/US_Stormwatch/status/1970278879987409289).
- The Atlantic/European connection: Hurricane Humberto strengthened to major hurricane status in the Atlantic, and another system (Gabrielle) is noted as a potential threat to the Azores and Iberia, highlighting a packed Atlantic basin this week [Humberto video](https://x.com/Volcaholic1/status/1971677437688967446) and [Gabrielle toward Europe](https://x.com/PGDynes/status/1971271149146472527).
Bottom line: This week is marked by very active, high-impact tropical activity across ocean basins (a catastrophic Western Pacific super typhoon and multiple Atlantic threats), widespread flood risk (both forecast and observed), and several violent convective events and one notable earthquake. The clearest immediate public hazards are catastrophic wind and surge risk in areas threatened by Ragasa and a multi-day flooding threat to the U.S. Southeast from Invest 94L/Potential Tropical Cyclone Nine; emergency declarations and evacuation notices are already in effect in several locations. Where possible, follow official local emergency products and trusted meteorological agencies for life-safety guidance and forecasts.

View File

@ -0,0 +1 @@
No tweets passed the filter

View File

@ -0,0 +1 @@
No tweets passed the filter

View File

@ -0,0 +1,42 @@
Direct answer — the key economics events this week:
1) A sweeping new U.S. tariff offensive and trade shock. President Trump announced a large set of fresh tariffs (eg. 100% on certain pharmaceuticals, 50% on kitchen cabinets and bathroom fixtures, 30% on upholstered furniture, 25% on heavy trucks), triggering immediate market and sector moves and sparking alarm in industry and abroad. See one summary of the package [here](https://x.com/KobeissiLetter/status/1971360987501482405). This is the single biggest macro policy story of the week because it can affect inflation passthrough, supply chains, corporate investment decisions, and trade partners balances.
- Why it matters: tariffs of this size raise input and consumer prices directly (inflation risk), distort supply chains, prompt corporate relocation/reshoring announcements, and invite retaliation or broader geoeconomic responses. Markets and some companies reacted quickly (e.g., retail and furniture names; Restoration Hardware cited) and precious metals rallied amid risk/offshore flows.
2) Fed / inflation story intensified — PCE rose and Fed debate widened. The Feds preferred inflation gauge, PCE, ticked up to about 2.7% (core PCE ~2.9%), reversing some easing hopes and feeding an intense debate inside the Fed about the neutral rate and how fast to cut. See the inflation readouts [here](https://x.com/KobeissiLetter/status/1971553211267096755) and commentary on the divided FOMC (Governor Mirans speech arguing neutral is materially lower vs. other Fed officials) [here](https://x.com/NickTimiraos/status/1970156734116213055) and [analysis](https://x.com/elerianm/status/1971563659295109240).
- Why it matters: higher-than-target PCE makes the timing and size of rate cuts uncertain. Governor Miran argued that neutral rates are much lower (implying faster easing), while others warned of stickier inflation — a split that raises policy risk and market volatility. Separately, the Feds independence has become a political flashpoint with legal action around a Fed governor (a highprofile amicus brief from exFed chairs and Treasury secretaries warns of the consequences) [here](https://x.com/NickTimiraos/status/1971214605662982525).
3) Growth & consumer activity: surprisingly strong GDP revision and consumer spending, but weak sentiment and mixed signals. The Treasury highlighted a Q2 GDP revision to ~3.8% driven by strong consumption and retail [here](https://x.com/USTreasury/status/1971264569214423135). At the same time, consumer sentiment readings plunged to very low levels (UMich/other series and Barcharts reported Consumer Sentiment at 55.1) [here](https://x.com/Barchart/status/1971604724324708704), showing a disconnect between hard spending data and household confidence.
- Pattern: strong realized spending and rising money aggregates (M2 showing renewed growth [here](https://x.com/KobeissiLetter/status/1971301428615614546)) alongside low sentiment is a recurring theme — consumers are still spending even as many report pessimism, which supports shortrun growth while complicating the inflation outlook.
4) Elevated risk of a U.S. government shutdown and preparations for disruption. Probability markets and commentaries placed shutdown odds high (Kalshi ~6367% this week) [see](https://x.com/SpencerHakimian/status/1971630586281578534). The White House reportedly told agencies to prepare for mass firings if Congress does not avert a shutdown [here](https://x.com/unusual_whales/status/1971630094566260749).
- Why it matters: a shutdown would temporarily hit growth, delay economic programs, and could rattle markets if prolonged. Contingency planning (including layoffs) raises the political and economic disruption stakes.
5) Market structure and risk signals — concentration, credit, and flows.
- Very high equity allocations and concentration: household allocation to stocks hit an alltime high (66%); top stocks now account for record shares of market cap (top 10% ~78% or Mag7 ~35%), increasing systemic concentration risk [see allocation and concentration notes](https://x.com/unusual_whales/status/1971635127592931645) and (https://x.com/KobeissiLetter/status/1971607948783710338).
- Precious metals surged: silver and gold hit multiyear highs (silver ~$46, highest in 14+ years) as safehaven flows rose [silver report](https://x.com/Barchart/status/1971593152776556784) and [gold commentary](https://x.com/elerianm/status/1971603473822265610).
- Credit & corporate finance: tech bond issuance and investmentgrade spreads remain tight; large corporate deals and potential IPO/funding moves (EA takeover reports ~ $50bn LBO [WSJ summary](https://x.com/WSJ/status/1971645350088745121); Kraken funding talks [here](https://x.com/business/status/1971661057941815710); Ethos IPO filing [here](https://x.com/business/status/1971641004722708881)).
6) Sovereign and regional credit moves: Frances rating outlook pressure, Moroccos upgrade, and UN sanctions on Iran. Scope Ratings put a negative outlook on France amid political impasse [France note](https://x.com/business/status/1971681822242181470), while S&P upgraded or affirmed Morocco as an African Eurobond issuer [here](https://x.com/business/status/1971682371196916023). The UN moves to reimpose broad sanctions on Iran also made global risk headlines [here](https://x.com/business/status/1971661254436565215).
7) Notable policy and institutional items: DOJ antitrust pressure on Google display ad business [here](https://x.com/business/status/1971655557799891307); the NLRB dropped an allegation against Apple/Tim Cook signaling a more businessfriendly enforcement posture [here](https://x.com/business/status/1971671230919872698); IMF/World Bank events and reports on fiscal guardrails and energy access (Mission300) shaped multilateral narratives [IMF/WorldBank links, e.g.](https://x.com/IMFNews/status/1971312426952905089) and (https://x.com/WorldBank/status/1971651048990265633).
Notable singleevent paragraphs
The tariff wave (high significance): The administrations announcements of very large, targeted tariffs (notably the 100% pharmaceutical tariff) represent an acute policy shock with immediate distributional, inflationary and tradepolicy implications. The measures are broad, industryspecific, and set to take effect quickly — raising the potential for input price passthrough, corporate reshoring announcements, commodity/retail price jumps, and retaliatory responses from trading partners. The tariffs also change the probability distribution for nearterm inflation outcomes and complicate the Feds decision calculus. See the tariff summary [here](https://x.com/KobeissiLetter/status/1971360987501482405).
PCE inflation and the Fed debate (high significance): PCE prints this week (headline ~2.7%, core ~2.9%) and a widely publicized divergence of views inside the FOMC (Governor Miran arguing neutral rates are lower and urging faster cuts, others warning of sticky inflation) moved markets and raised uncertainty about the timing and size of rate cuts. This weeks mix — stronger growth metrics, sticky PCE, and intraFed debate — is central to nearterm market dynamics and policy expectations. See the PCE read [here](https://x.com/KobeissiLetter/status/1971553211267096755) and Mirans take [here](https://x.com/NickTimiraos/status/1970156734116213055).
Government shutdown risk (high significance): Betting markets and reporting showed a materially elevated chance of a shutdown this week (~6367%), and the White House instructed agencies to prepare for mass firings if a shutdown happens. That raises nearterm downside growth and policyimplementation risks and is a headline politicaleconomic event this week [shutdown risk](https://x.com/SpencerHakimian/status/1971630586281578534) and [agency prep](https://x.com/unusual_whales/status/1971630094566260749).
Bottom line / themes and trends to watch next week:
- Tariff fallout and passthrough to prices and supply chains (watch CPI/PPI, import prices, and corporate guidance).
- Fed policy calibration and communications amid sticky PCE and intracommittee division; market pricing for October and beyond.
- Political risks (shutdown, legal fights over Fed independence) that could amplify market volatility.
- Elevated market concentration and elevated household equity exposure; riskasset fragility if growth or policy expectations shift.
If you want, I can produce a onepage market impact brief showing likely sector winners/losers from the tariff slate, or a short timeline of Fed speakers and economic releases to watch next week.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,698 @@
{
"success": true,
"message": "Job results retrieved successfully",
"data": {
"job_id": "e4f33467-479e-4560-a41e-4e780048fdd8",
"status": "completed",
"results": {
"filtered_tweets": [
{
"tweet": {
"tweet_id": "1971696476956000468",
"text": "Cuernavaca, Mexico now...🌊👀\nhttps://t.co/jzTT8xACUi",
"created_at": "2025-09-26T22:00:47Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet appears to be sharing a location update with an image or video link, focusing on Cuernavaca, Mexico. There is no mention or context related to agricultural developments."
},
{
"tweet": {
"tweet_id": "1971695980585406834",
"text": "RT @TWCAlexWilson: We've got the very latest tonight on @wxunfiltered with THE guy - former director of the NHC and our Hurricane Expert, @…",
"created_at": "2025-09-26T21:58:48Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet does not mention anything related to agricultural developments. It appears to be discussing weather updates and a Hurricane Expert, which are related to meteorology rather than agriculture."
},
{
"tweet": {
"tweet_id": "1971693606307353042",
"text": "https://t.co/uSJHeF8DAm",
"created_at": "2025-09-26T21:49:22Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not contain any content related to agricultural developments, as it only references a user's handle and a URL link without providing any specific information about agriculture."
},
{
"tweet": {
"tweet_id": "1971691460010578410",
"text": "Heres what we know about Potential Tropical Cyclone Nine. Stay with The Weather Channel for all the latest information as we track this system through the weekend. https://t.co/NXDd1CabCF",
"created_at": "2025-09-26T21:40:50Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a weather event, specifically a tropical cyclone, and does not mention agricultural developments or related topics. Therefore, it does not pass as relevant to agricultural developments."
},
{
"tweet": {
"tweet_id": "1971690193372827903",
"text": "RT @mikebettes: Here's your initial heads up on PTC 9(future #Imelda). There is A LOT of uncertainty after day 3, so please check back on t…",
"created_at": "2025-09-26T21:35:48Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing a weather event related to a meteorological forecast (PTC 9/future #Imelda) and does not mention agricultural developments or related topics."
},
{
"tweet": {
"tweet_id": "1971690184174707192",
"text": "RT @TWCChrisBruin: 1st cone for PTC 9 now being issued. Jacksonville, FL to Wrightsville Beach, NC needs to start preparing! Still opportun…",
"created_at": "2025-09-26T21:35:46Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a weather event and the need for preparation in response to it. There is no mention of agricultural developments or related topics; therefore, it does not address agricultural developments."
},
{
"tweet": {
"tweet_id": "1971686656731426932",
"text": "COLUMBIA, S.C. (FOX Carolina) - Gov. Henry McMaster declared a state of emergency ahead of possible effects of Tropical Disturbance 94L.",
"created_at": "2025-09-26T21:21:45Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses a state of emergency declared by the governor regarding a tropical disturbance, which is related to weather and emergency management rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1971686281638982079",
"text": "Getting increasingly worried about significant flooding from Potential Tropical Cyclone Nine in the Carolinas.\n\nThe storm is forecast to slow down dramatically off the South Carolina coast, with some models showing 12+ inches of rain in spots.\n\nWith tropical cyclones, its usually not the wind that kills, its the water.",
"created_at": "2025-09-26T21:20:16Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses concerns about flooding due to a tropical cyclone, focusing on weather-related events rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1971685713226711336",
"text": "A new tropical storm is forming in the Bahamas and could become a rain and wind threat to the Southeast coast while a major hurricane recurves near Bermuda through early next week. Here's the latest.\nhttps://t.co/KF6No3OAcj https://t.co/kI8HQQsiTH",
"created_at": "2025-09-26T21:18:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a tropical storm and hurricane activity, focusing on weather patterns rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1971681622333575567",
"text": "Arizona is being slammed by severe thunderstorms today, dropping hail up to the size of golf balls, with millions under flash flood warnings across the Phoenix metro area. https://t.co/0fHzAbkKNJ",
"created_at": "2025-09-26T21:01:45Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses severe thunderstorms and flooding in Arizona, which are weather conditions, not agricultural developments. There is no mention of farming, crops, or agricultural technology in the content."
},
{
"tweet": {
"tweet_id": "1971679687194890336",
"text": "Culiacán, Mexico now...🌊👀\nhttps://t.co/xYuahM4pK6",
"created_at": "2025-09-26T20:54:04Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet mentions a location (Culiacán, Mexico) and includes an emoji, but it does not provide any information or context that relates to agricultural developments. The content appears to focus more on the current situation in that area rather than any developments in agriculture."
},
{
"tweet": {
"tweet_id": "1971678411493200288",
"text": "@zoom_earth https://t.co/m1ckjI77Qh",
"created_at": "2025-09-26T20:48:59Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not contain any information about agricultural developments. It appears to be a link to a site or image without context provided, making it unclear whether it relates to agriculture."
},
{
"tweet": {
"tweet_id": "1971677437688967446",
"text": "Humberto is now a major category 3 hurricane....\n\n📹 @zoom_earth \nhttps://t.co/1MBGLNA7TO",
"created_at": "2025-09-26T20:45:07Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses a hurricane named Humberto, which is a natural disaster and not related to agricultural developments. It does not mention any agricultural topics."
},
{
"tweet": {
"tweet_id": "1971675480362570084",
"text": "Culiacán, Mexico now!...🌊🌊🌊\nhttps://t.co/W8h1hEF2DO",
"created_at": "2025-09-26T20:37:21Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything related to agricultural developments. It appears to be a personal or location-based update from Culiacán, Mexico, without any indication of agriculture."
},
{
"tweet": {
"tweet_id": "1971674180094742900",
"text": "Major flooding in Cienfuegos, Santiago, in Dominican republic today...🌊🌊🌊\nhttps://t.co/FpOXFhbaYZ",
"created_at": "2025-09-26T20:32:11Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention agricultural developments; it focuses on a weather-related event, specifically flooding, in the Dominican Republic."
},
{
"tweet": {
"tweet_id": "1971673292869456343",
"text": "RT @FeliciaCombsTWC: We're breaking down Invest 94L - what will likely be Imelda - Currently most models have the system impacting the sout…",
"created_at": "2025-09-26T20:28:39Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a weather system (Invest 94L) and its potential impact, which does not directly relate to agricultural developments. While weather can influence agriculture, the focus of the tweet is on a weather event rather than agricultural advancements or practices."
},
{
"tweet": {
"tweet_id": "1971672329043550537",
"text": "It's also one year ago since hurricane John hit Mexico but everyone was to focussed on Helene...\nhttps://t.co/wDTPE4lIE6",
"created_at": "2025-09-26T20:24:49Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses hurricanes John and Helene, with no mention of agricultural developments. The context is focused on natural disasters rather than agriculture."
},
{
"tweet": {
"tweet_id": "1971670871460008435",
"text": "Bethepage where the Ryder cup is being held 💥⚡️",
"created_at": "2025-09-26T20:19:02Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet is discussing the Ryder Cup, which is a golf tournament, and does not mention anything related to agricultural developments."
},
{
"tweet": {
"tweet_id": "1971668887197581560",
"text": "Major flooding in Bordj Bou Arreridj and M'Sila Provinces of Algeria over the past couple of days...🌊🌊🌊 https://t.co/inUWXpgjJ0",
"created_at": "2025-09-26T20:11:09Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses major flooding in specific provinces of Algeria, but it does not mention agricultural developments directly. The focus is on the flooding event rather than any advancements or changes in agriculture."
},
{
"tweet": {
"tweet_id": "1971666082936045689",
"text": "Have you noticed how many hurricanes starting with the letter \"I\" have been terribly destructive lately? It turns out there's a simple explanation. \nhttps://t.co/501lyIr1h8",
"created_at": "2025-09-26T20:00:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses hurricanes and their destructiveness, focusing on the frequency of hurricanes beginning with the letter 'I'. It does not mention agricultural developments or relate to agriculture in any way."
},
{
"tweet": {
"tweet_id": "1971664435933769964",
"text": "🍿🍿🍿",
"created_at": "2025-09-26T19:53:27Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet from Volcaholic1 consists solely of popcorn emojis and does not contain any text related to agricultural developments. Therefore, it cannot be interpreted as discussing that topic."
},
{
"tweet": {
"tweet_id": "1971657539185266786",
"text": "https://t.co/WqDssx8jpY",
"created_at": "2025-09-26T19:26:03Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not provide any content to analyze. It only contains a username and a link, which makes it impossible to determine if it's discussing agricultural developments."
},
{
"tweet": {
"tweet_id": "1971654210061324539",
"text": "RT @volcaholic1: Ladies and gents, I give you a box phone farm. \n\nThese create and manage fake accounts for disinformation, trolling, scams…",
"created_at": "2025-09-26T19:12:49Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses fake accounts that create disinformation, trolling, and scams, which are not related to agricultural developments."
},
{
"tweet": {
"tweet_id": "1971641679141908480",
"text": "Worlds oceans fail key health check as acidity crosses critical threshold for marine life.\n\nScientists call for renewed global effort to curb fossil fuels as seven of nine planetary boundaries now transgressed.\nhttps://t.co/rT4D8zAyo2",
"created_at": "2025-09-26T18:23:02Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses the health of the world's oceans and the impact of fossil fuels on planetary boundaries, which is related to environmental issues rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1971640773163503655",
"text": "Tropical storm alerts are expected to be issued in the Bahamas later today as a disturbance continues to organize. There is still significant uncertainty as to the details of how this will all shake out into next week. Here's the latest:\nhttps://t.co/KF6No3OAcj https://t.co/NgAdaaVwRI",
"created_at": "2025-09-26T18:19:26Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses weather-related developments, specifically tropical storm alerts in the Bahamas, rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1971640263425905130",
"text": "RT @volcaholic1: Severe Tropical Cyclone Opong has battered the Philippines, making landfall in Oriental Mindoro after tearing through Masb…",
"created_at": "2025-09-26T18:17:24Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet is discussing a severe tropical cyclone and its impact on the Philippines, rather than agricultural developments. The content is focused on a natural disaster."
},
{
"tweet": {
"tweet_id": "1971629735940915242",
"text": "It's never too early to start getting prepared for a tropical storm or hurricane. Watch meteorologist @jordansteele show what you need to do during the countdown to landfall ⬇️",
"created_at": "2025-09-26T17:35:34Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is focused on weather preparedness for tropical storms and hurricanes, which does not directly relate to agricultural developments. It addresses safety measures rather than advancements or developments in agriculture."
},
{
"tweet": {
"tweet_id": "1971627196843479195",
"text": "Residents of Essentuki, Russia, captured a murmuration of birds tonight. \n\nLarge groups moved together in changing patterns across the sky illuminated by the citys greenhouse lights. https://t.co/hxvCb9QFkm",
"created_at": "2025-09-26T17:25:29Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet describes a phenomenon involving birds and their movements in the sky, as well as the illumination from greenhouse lights. While there is a mention of 'greenhouse lights', the primary focus is on the murmuration of birds rather than agricultural developments, making it not directly about that topic."
},
{
"tweet": {
"tweet_id": "1971622293408244196",
"text": "Space is filling fast with Starlink and other satellites. \n\nWill orbit turn into a junkyard in 20 years? \n\nHow long before collisions create more debris?\n\nAre we taking this seriously enough?",
"created_at": "2025-09-26T17:06:00Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses concerns about satellite proliferation and space debris in orbit, and does not reference agricultural developments or related issues in any way."
},
{
"tweet": {
"tweet_id": "1971621320258724347",
"text": "How cool is this! 🌳🌴🌱\nhttps://t.co/WMY3YiVN9G",
"created_at": "2025-09-26T17:02:08Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet expresses excitement or enthusiasm about something by using emojis related to trees and plants. However, it does not provide any specific information or context about agricultural developments. Therefore, it cannot be confirmed that the tweet is about agricultural developments."
},
{
"tweet": {
"tweet_id": "1971614351401640053",
"text": "*Hepatitis",
"created_at": "2025-09-26T16:34:26Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet by Volcaholic1 mentions 'Hepatitis', which is a medical condition related to liver disease, and does not pertain to agricultural developments. Therefore, the tweet is not talking about agricultural developments."
},
{
"tweet": {
"tweet_id": "1971610237435039802",
"text": "One year ago today, Hurricane Helene struck Floridas Big Bend as a Category 4 storm, bringing catastrophic damage across the southeastern United States. \n\nThe hurricane caused severe inland flooding, left at least 250 people dead, and inflicted an estimated $78.7 billion in damages, making it one of the deadliest U.S. hurricanes in recent years.",
"created_at": "2025-09-26T16:18:06Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses Hurricane Helene and its impacts, including fatalities and damage costs. It does not mention agricultural developments or related topics."
},
{
"tweet": {
"tweet_id": "1971602661909950869",
"text": "At least 19 people have died this month after consuming bootleg alcohol in northwestern Russias Leningrad region near the border with Estonia, authorities said Friday.",
"created_at": "2025-09-26T15:47:59Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses deaths related to bootleg alcohol consumption in a specific region, specifically focusing on public health and safety issues rather than agricultural developments. It does not provide any information about agriculture."
},
{
"tweet": {
"tweet_id": "1971599948753129891",
"text": "Its time for the @rydercupusa. Here's a look at the gameday forecast. https://t.co/1cs63dkELg",
"created_at": "2025-09-26T15:37:12Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is about the Ryder Cup event and provides a forecast for gameday weather. It does not mention any agricultural developments."
},
{
"tweet": {
"tweet_id": "1971599734159839648",
"text": "5 PEDIATRIC RED ADVANCED LIFE SUPPORT PATIENTS TRANSPORTED TO KENDALL. ALL PATIENTS TOOK EDIBLES https://t.co/MhkK6QQn78",
"created_at": "2025-09-26T15:36:21Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses pediatric patients and their transport, along with a reference to edibles, which implies a discussion about health or possible medical emergencies rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1971598508294820191",
"text": "👀👀",
"created_at": "2025-09-26T15:31:29Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet contains only an emoji reaction ('👀👀') and does not provide any content or context regarding agricultural developments. Therefore, it cannot be determined that the tweet is discussing any topic, including agriculture."
},
{
"tweet": {
"tweet_id": "1971595499384783162",
"text": "A wildfire sparked by lightning in July forced evacuations and closures as it destroyed dozens of structures. Now the National Park Service has announced when portions of the North Rim will reopen.\nhttps://t.co/NXYQ4s9Uae",
"created_at": "2025-09-26T15:19:32Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a wildfire caused by lightning that led to evacuations and closures, and mentions the reopening of a park, rather than agricultural developments. Therefore, it does not talk about agriculture."
},
{
"tweet": {
"tweet_id": "1971593953574273034",
"text": "RT @CharlesPeekWX: Heading east with the SC coast in my GPS, for reporting on what could be Imelda. With the anniversary of Hurricane Helen…",
"created_at": "2025-09-26T15:13:23Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is primarily discussing a weather-related event, specifically reporting on Hurricane Helen and possibly another storm named Imelda. It does not mention agricultural developments or related topics."
},
{
"tweet": {
"tweet_id": "1971591264194932825",
"text": "RT @smFISHMAN: Check out the first part of my sitdown with @JimCantore as @weatherchannel looks back at the impacts of #HurricaneHelene one…",
"created_at": "2025-09-26T15:02:42Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing a retrospective on the impacts of Hurricane Helene, which is related to weather events rather than agricultural developments. There is no mention of agriculture or related topics."
},
{
"tweet": {
"tweet_id": "1971579324424946084",
"text": "RT @LaFemmePhojo: Were live from WNC with @weatherchannel this morning on the anniversary of Hurricane Helene. https://t.co/n4NCKKKaxi",
"created_at": "2025-09-26T14:15:15Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a live broadcast related to the anniversary of Hurricane Helene and mentions the Weather Channel and WNC. It does not reference agricultural developments."
},
{
"tweet": {
"tweet_id": "1971577248231911566",
"text": "Recovery efforts are ongoing one year after Hurricane Helene devastated Western North Carolina. Senior National Correspondent @JMichaelsNews reports in Chimney Rock this morning. https://t.co/cBqIfpHGNg",
"created_at": "2025-09-26T14:07:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses recovery efforts after Hurricane Helene and does not mention agricultural developments. The focus is on the aftermath of a natural disaster, making it unrelated to agriculture."
},
{
"tweet": {
"tweet_id": "1971548459867250715",
"text": "RT @kellycass: Not only do we have Hurricane Humberto, but another area that is forecast to develop &amp; become Imelda. This one has the poten…",
"created_at": "2025-09-26T12:12:37Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing weather developments related to hurricanes, specifically Hurricane Humberto and the potential development of another storm named Imelda. It does not mention agricultural developments."
},
{
"tweet": {
"tweet_id": "1971548310088352032",
"text": "The Southeast should prepare for a multiday flood threat beginning today. Several inches of rain could lead to flooding, and this is before any potential impacts from future Imelda next week. See the video for more. https://t.co/NUX8U23sp0 https://t.co/HqTUXrTeiJ",
"created_at": "2025-09-26T12:12:01Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing a flood threat due to weather conditions and future events like potential impacts from a storm, rather than agricultural developments. It focuses on weather warnings rather than agriculture."
},
{
"tweet": {
"tweet_id": "1971533966277566921",
"text": "Future Imelda will likely develop Friday or Saturday, and could bring potential impacts to Georgia and the Carolinas next week. Watch this video for the latest track and timing. https://t.co/DmxhKd53ci https://t.co/gohU08qM4r",
"created_at": "2025-09-26T11:15:01Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses the development of a weather system (Imelda) and its potential impacts on specific states. It does not mention anything related to agricultural developments; rather, it focuses on meteorological concerns."
},
{
"tweet": {
"tweet_id": "1971523139239555308",
"text": "Humberto has officially become a hurricane in the central Atlantic. Here's the latest. https://t.co/KF6No3OAcj",
"created_at": "2025-09-26T10:32:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses the status of a hurricane and provides a link for more information. It does not mention agricultural developments or any related topics."
},
{
"tweet": {
"tweet_id": "1971413690617303490",
"text": "Humberto continues to strengthen and is expected to become a major hurricane by the weekend. We are still watching Invest 94L. Here's the latest:\nhttps://t.co/KF6No3OAcj https://t.co/LjZlhILDYm",
"created_at": "2025-09-26T03:17:05Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses Hurricane Humberto and its potential impact, rather than any agricultural developments. It focuses on weather updates rather than farming or agriculture-related topics."
},
{
"tweet": {
"tweet_id": "1971380449575604703",
"text": "Tonight, we revisit areas that were at the center of the storms devastation. Watch \"Helene: One Year Later\" at 10/9c on The Weather Channel and streaming on The Weather Channel TV app: https://t.co/Feaf8zTBxX https://t.co/oWq5W8SANG",
"created_at": "2025-09-26T01:05:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is focused on a program related to storm devastation and the aftermath, rather than agricultural developments. It discusses a specific event and weather-related topics rather than farming or agriculture."
},
{
"tweet": {
"tweet_id": "1971338240163733851",
"text": "RT @wxunfiltered: \"The risks for the east coast are going up\" - @DrRickKnabb \n\nInvest 94L (future #Imelda) is getting better organized this…",
"created_at": "2025-09-25T22:17:16Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing weather risks and a specific weather system (Invest 94L), which indicates it is focused on meteorological developments rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1971333894419972570",
"text": "Two skydivers got the view of a lifetime when they saw a fully circular rainbow on their way back down to Earth. Our meteorologist Caitlin Kaiser explains how this was all possible. https://t.co/4jIe6iixzN https://t.co/N7FQuYL0QR",
"created_at": "2025-09-25T22:00:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses skydivers witnessing a circular rainbow and mentions a meteorologist explaining the phenomenon. It does not mention anything related to agricultural developments."
},
{
"tweet": {
"tweet_id": "1971303696760754264",
"text": "Watch as this gamer's session is interrupted by a 6.3 magnitude earthquake in Venezuela. Hopefully he got to pause his game. 🎮 https://t.co/Dr5oP4oBc3 https://t.co/URQuq14f2a",
"created_at": "2025-09-25T20:00:01Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a gamer's experience during an earthquake in Venezuela and does not mention agricultural developments at all. It focuses on a gaming context and natural disaster rather than agriculture."
},
{
"tweet": {
"tweet_id": "1971298477343711324",
"text": "Humberto could become the season's next major hurricane, but the next system, which is set to become Tropical Storm Imelda, could be a threat to the Bahamas and U.S. Here's what you need to know:\nhttps://t.co/KF6No3OAcj https://t.co/cW9hUk4sLV",
"created_at": "2025-09-25T19:39:16Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses upcoming weather events and potential hurricanes, which are not directly related to agricultural developments. Instead, it focuses on meteorological phenomena."
},
{
"tweet": {
"tweet_id": "1971271149146472527",
"text": "A hurricane is heading for Europe.\n#HurricaneGabrielle is on track for a direct hit on the Azores, with tropical storm conditions expected in Spain &amp; mainland Portugal.\nThis could be one of the most severe Atlantic systems to reach Iberia. https://t.co/2ngclARzt8",
"created_at": "2025-09-25T17:50:41Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet discusses a hurricane and its impact on Europe, specifically the Azores, Spain, and mainland Portugal. It does not mention agricultural developments or anything related to agriculture."
},
{
"tweet": {
"tweet_id": "1971269350138241256",
"text": "RT @MEERsrm: ”Our native trees are no longer native. Theyre foreigners now.” An arborists words sparked Mike Tidwells book on how climat…",
"created_at": "2025-09-25T17:43:32Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet is discussing the status of native trees and their relationship to climate change, but it does not specifically address agricultural developments. It focuses more on environmental issues related to trees and climate, rather than agriculture."
},
{
"tweet": {
"tweet_id": "1971269335403593761",
"text": "RT @MEERsrm: This week, Dr. Ye Tao visited Solthis in Freetown to explore how MEERs passive cooling roofs could support healthcare centers…",
"created_at": "2025-09-25T17:43:28Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet is focused on a visit to discuss passive cooling roofs in the context of healthcare centers, not agricultural developments. There is no mention or implication of agricultural topics."
},
{
"tweet": {
"tweet_id": "1970752946238562809",
"text": "A prolific thunderstorm outbreak is ongoing across Californias Central Coast, with thousands of strikes recorded over the past 12 hours.\n\nThunderstorms are much further north than was expected by this time near Carmel and could reach the Bay Area soon. https://t.co/fUfmA0OrXE",
"created_at": "2025-09-24T07:31:31Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a weather event, specifically a thunderstorm outbreak in California. It does not mention agricultural developments or any related topics, focusing instead on meteorological conditions."
},
{
"tweet": {
"tweet_id": "1970618277450887423",
"text": "RT @bclemms: Super Typhoon Ragasa is ripping in Hong Kong. https://t.co/BcuyYCRm8Y",
"created_at": "2025-09-23T22:36:24Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a super typhoon and its impact on Hong Kong, which is related to weather and natural events rather than agricultural developments."
},
{
"tweet": {
"tweet_id": "1970603236651659709",
"text": "A rare thunderstorm outbreak is possible along the Central Coast and into the SF Bay Area tonight into tomorrow. \n\nThunderstorms are a big deal in this part of the world because the Bay Area sees some of the fewest thunderstorms of any place on Earth outside the polar regions. https://t.co/m8hbkdCtB7",
"created_at": "2025-09-23T21:36:38Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a meteorological event (a thunderstorm outbreak) and its significance in the context of the Bay Area, but it does not mention agricultural developments or topics related to agriculture."
},
{
"tweet": {
"tweet_id": "1970591857735606340",
"text": "The greater Hong Kong area (GBA), home to 86 million people, is dodging a bullet as the inner core of Category 4 Typhoon Ragasa passes just south of the region with sustained winds of 130 mph and gusts up to 160 mph.\n\nMore than 750,000 people in South China have been forced to evacuate as the typhoon nears landfall, while Hong Kong has essentially been shut down due to the storm.",
"created_at": "2025-09-23T20:51:25Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a severe weather event, specifically Typhoon Ragasa, and its impact on the Greater Hong Kong area. It does not mention agricultural developments or related topics."
},
{
"tweet": {
"tweet_id": "1970436467047739766",
"text": "RT @MEERsrm: Ariana Ejupi, MEERs Senior Project Officer, met with Mike Tidwell, Founder &amp; Director of the Chesapeake Climate Action Networ…",
"created_at": "2025-09-23T10:33:57Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet does not mention agricultural developments. It is about a meeting between individuals related to climate action, which may touch on environmental issues, but there is no direct reference to agriculture."
},
{
"tweet": {
"tweet_id": "1970278879987409289",
"text": "Insane video of a tornado roaring across Torch Lake in Northern Michigan, the same lake where I have family vacationed every summer for the last 10 years! \n\nhttps://t.co/pMrU6c44Op",
"created_at": "2025-09-23T00:07:45Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a tornado event in Northern Michigan and does not mention or relate to agricultural developments."
},
{
"tweet": {
"tweet_id": "1970272162109100397",
"text": "RT @PappenheimWx: Speechless. Unreal tornado just occurred on Torch Lake in Michigan. I was watching the webcam when it initially touched d…",
"created_at": "2025-09-22T23:41:03Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a tornado event in Michigan, focusing on a natural disaster rather than agricultural developments. It does not mention any agricultural topics or advancements."
},
{
"tweet": {
"tweet_id": "1970250776833597536",
"text": "Typhoon Ragasa was meant to be a once-in-50-year storm. Now, were seeing super typhoons like this every 34 years.\nThis isnt anything normal — its the #ClimateCrisis and insurance for Hong Kong is just about to get even more expensive. https://t.co/8QUtKGOn35",
"created_at": "2025-09-22T22:16:05Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet discusses Typhoon Ragasa and the increasing frequency of super typhoons as a result of the climate crisis, rather than focusing on agricultural developments."
},
{
"tweet": {
"tweet_id": "1970191726456512878",
"text": "Europe has an air conditioning problem.\n\nAn estimated 175,000 people die from extreme heat every year in Europe, compared with just over 2,000 in the U.S. last year.\n\nOnly 20% of European homes have AC, versus 90% in the U.S.\n\nYou are nearly 4× more likely to die of extreme heat in Europe than to be fatally shot in the United States.\n\nIn Europe, future energy demands from installing AC will increasingly be supplied by clean energy sources.\n\nBut with rising temperatures driven by climate change, not having AC in Europe is becoming downright dangerous.\n\nIn Barcelona for example, the number of tropical nights has quadrupled since the 1950s.\n\nDespite having similar climates, Barcelona faces a 400% higher mortality risk than Los Angeles when temperatures climb above 30 °C (86 °F).\n\nGlobally, nights are warming faster than days due to climate change, and this is when mortality risk is highest, because the body cannot recover from daytime heat.\n\nWill Europe widely adopt AC, or continue sweating through brutal summers that are only getting worse?",
"created_at": "2025-09-22T18:21:26Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses the issue of air conditioning and heat-related deaths in Europe, which is primarily related to climate change and energy demands rather than agricultural developments. There is no mention of agriculture, farming practices, or any related topics."
},
{
"tweet": {
"tweet_id": "1969924132998619483",
"text": "The Philippines Babuyan Islands are just hours away from a catastrophic strike by Category 5 Super Typhoon Ragasa, packing sustained winds of 165 mph and gusts up to 200 mph.\n\nThe remote islands are home to about 20,000 people, many of whom live in poverty. https://t.co/EmP7mAFmqW",
"created_at": "2025-09-22T00:38:07Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses an impending natural disaster in the Philippines, specifically a super typhoon and its potential impact on the local population. It does not mention any agricultural developments."
},
{
"tweet": {
"tweet_id": "1969891829702353172",
"text": "A lot of my friends in SoCal have been talking about how much more humid its felt over the last 10 years. and many of them have had to get AC because of it.\n\nHave you noticed the same thing living along the coast?\n\nIt's very humid today along the SoCal coast, with a marine heatwave offshore adding extra mugginess and tropical moisture streaming in from the south.",
"created_at": "2025-09-21T22:29:45Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses weather conditions, specifically humidity and marine heatwaves, but it does not mention agricultural developments or any topics related to agriculture."
},
{
"tweet": {
"tweet_id": "1969887603869782200",
"text": "30 hour timelapse of the strongest storm on the planet, Category 5 Super Typhoon Ragasa in the Western Pacific. \n\nThe storm is packing 165 mph winds with catastrophic wind gusts up to 200 mph. https://t.co/PcQiBW6C0y",
"created_at": "2025-09-21T22:12:58Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet is discussing a weather event, specifically a powerful storm, and does not mention anything related to agricultural developments."
},
{
"tweet": {
"tweet_id": "1969577085829333268",
"text": "Wildfire smoke kills more people in the US each year than car crashes, 41,000 deaths annually, per a new Stanford study in Nature.",
"created_at": "2025-09-21T01:39:04Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses the impact of wildfire smoke on public health and compares the number of deaths to car crashes. It does not mention agricultural developments or related topics."
},
{
"tweet": {
"tweet_id": "1969567922696921466",
"text": "San Francisco has been drought-free for over 900 days, its longest stretch without drought in nearly 20 years. https://t.co/FflsNz3Gtb",
"created_at": "2025-09-21T01:02:40Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses the drought status in San Francisco, not agricultural developments. It focuses on weather conditions rather than any specific advancements or changes in agriculture."
}
],
"count": 68,
"filter_question": "Is this tweet talking about agricultural developments?",
"summarization_question": "Summarize aggricultural developments, across production, but also commodities trade &c last week.",
"summary": "No tweets passed the filter"
},
"completed_at": "2025-09-26T23:08:36.208684Z",
"processing_time_seconds": 19
}
}

View File

@ -0,0 +1,698 @@
{
"success": true,
"message": "Job results retrieved successfully",
"data": {
"job_id": "a78678d4-5d38-4b76-becd-de5a73587470",
"status": "completed",
"results": {
"filtered_tweets": [
{
"tweet": {
"tweet_id": "1971696476956000468",
"text": "Cuernavaca, Mexico now...🌊👀\nhttps://t.co/jzTT8xACUi",
"created_at": "2025-09-26T22:00:47Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or any sun-related events. It refers to a location (Cuernavaca, Mexico) and includes an emoji, but there is no indication of discussing concerns about solar activity or related events."
},
{
"tweet": {
"tweet_id": "1971695980585406834",
"text": "RT @TWCAlexWilson: We've got the very latest tonight on @wxunfiltered with THE guy - former director of the NHC and our Hurricane Expert, @…",
"created_at": "2025-09-26T21:58:48Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or any sun-related event. It discusses weather news and features a discussion with a hurricane expert."
},
{
"tweet": {
"tweet_id": "1971693606307353042",
"text": "https://t.co/uSJHeF8DAm",
"created_at": "2025-09-26T21:49:22Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The input provided does not include the actual content of the tweet. Therefore, it is impossible to determine whether the tweet discusses a new worrying solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971691460010578410",
"text": "Heres what we know about Potential Tropical Cyclone Nine. Stay with The Weather Channel for all the latest information as we track this system through the weekend. https://t.co/NXDd1CabCF",
"created_at": "2025-09-26T21:40:50Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing Potential Tropical Cyclone Nine and weather-related information, not a solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971690193372827903",
"text": "RT @mikebettes: Here's your initial heads up on PTC 9(future #Imelda). There is A LOT of uncertainty after day 3, so please check back on t…",
"created_at": "2025-09-26T21:35:48Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses PTC 9, which is related to weather forecasting and potentially a hurricane, rather than a solar flare or sun-related event. There is no mention of solar activity in the content of the tweet."
},
{
"tweet": {
"tweet_id": "1971690184174707192",
"text": "RT @TWCChrisBruin: 1st cone for PTC 9 now being issued. Jacksonville, FL to Wrightsville Beach, NC needs to start preparing! Still opportun…",
"created_at": "2025-09-26T21:35:46Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing the issuance of a cone for a tropical system, likely related to weather events, rather than mentioning a solar flare or sun-related event. There is no indication in the text about solar activity or concerns related to the Sun."
},
{
"tweet": {
"tweet_id": "1971686656731426932",
"text": "COLUMBIA, S.C. (FOX Carolina) - Gov. Henry McMaster declared a state of emergency ahead of possible effects of Tropical Disturbance 94L.",
"created_at": "2025-09-26T21:21:45Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses a state of emergency declared by the governor in response to Tropical Disturbance 94L, which is a weather event related to a disturbance in the atmosphere, not related to solar flares or sun-related events. Therefore, it does not mention any solar activity."
},
{
"tweet": {
"tweet_id": "1971686281638982079",
"text": "Getting increasingly worried about significant flooding from Potential Tropical Cyclone Nine in the Carolinas.\n\nThe storm is forecast to slow down dramatically off the South Carolina coast, with some models showing 12+ inches of rain in spots.\n\nWith tropical cyclones, its usually not the wind that kills, its the water.",
"created_at": "2025-09-26T21:20:16Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a potential tropical cyclone and its impact, specifically focusing on significant flooding and rainfall. It does not mention any solar flare or sun-related events."
},
{
"tweet": {
"tweet_id": "1971685713226711336",
"text": "A new tropical storm is forming in the Bahamas and could become a rain and wind threat to the Southeast coast while a major hurricane recurves near Bermuda through early next week. Here's the latest.\nhttps://t.co/KF6No3OAcj https://t.co/kI8HQQsiTH",
"created_at": "2025-09-26T21:18:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a tropical storm forming in the Bahamas and mentions hurricane activity near Bermuda, which is related to weather events rather than solar flares or sun-related events."
},
{
"tweet": {
"tweet_id": "1971681622333575567",
"text": "Arizona is being slammed by severe thunderstorms today, dropping hail up to the size of golf balls, with millions under flash flood warnings across the Phoenix metro area. https://t.co/0fHzAbkKNJ",
"created_at": "2025-09-26T21:01:45Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet mentions severe thunderstorms and hail in Arizona, not a solar flare or sun-related event. It focuses on weather phenomena related to storms, rather than solar activity."
},
{
"tweet": {
"tweet_id": "1971679687194890336",
"text": "Culiacán, Mexico now...🌊👀\nhttps://t.co/xYuahM4pK6",
"created_at": "2025-09-26T20:54:04Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or sun-related event. Instead, it appears to be referencing an event in Culiacán, Mexico, without any context related to solar activity."
},
{
"tweet": {
"tweet_id": "1971678411493200288",
"text": "@zoom_earth https://t.co/m1ckjI77Qh",
"created_at": "2025-09-26T20:48:59Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not contain any information or context regarding a solar flare or any sun-related event. It only includes a username and a link."
},
{
"tweet": {
"tweet_id": "1971677437688967446",
"text": "Humberto is now a major category 3 hurricane....\n\n📹 @zoom_earth \nhttps://t.co/1MBGLNA7TO",
"created_at": "2025-09-26T20:45:07Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet is discussing a hurricane (Humberto) and includes a video link related to storm activity, not a solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971675480362570084",
"text": "Culiacán, Mexico now!...🌊🌊🌊\nhttps://t.co/W8h1hEF2DO",
"created_at": "2025-09-26T20:37:21Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything about solar flares or sun-related events. Instead, it seems to focus on a location (Culiacán, Mexico) along with an emoji representation of waves, which could indicate weather or ocean-related content rather than solar activity."
},
{
"tweet": {
"tweet_id": "1971674180094742900",
"text": "Major flooding in Cienfuegos, Santiago, in Dominican republic today...🌊🌊🌊\nhttps://t.co/FpOXFhbaYZ",
"created_at": "2025-09-26T20:32:11Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses major flooding in Cienfuegos, Santiago, in the Dominican Republic, which is unrelated to solar flares or sun-related events. Instead, it focuses on weather-related issues."
},
{
"tweet": {
"tweet_id": "1971673292869456343",
"text": "RT @FeliciaCombsTWC: We're breaking down Invest 94L - what will likely be Imelda - Currently most models have the system impacting the sout…",
"created_at": "2025-09-26T20:28:39Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or a sun-related event. It discusses a weather system (Invest 94L) and its potential impacts, which is related to meteorology, not solar activity."
},
{
"tweet": {
"tweet_id": "1971672329043550537",
"text": "It's also one year ago since hurricane John hit Mexico but everyone was to focussed on Helene...\nhttps://t.co/wDTPE4lIE6",
"created_at": "2025-09-26T20:24:49Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses hurricane John and mentions it in relation to hurricane Helene. It does not provide any information about solar flares or sun-related events."
},
{
"tweet": {
"tweet_id": "1971670871460008435",
"text": "Bethepage where the Ryder cup is being held 💥⚡️",
"created_at": "2025-09-26T20:19:02Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or sun-related event. Instead, it refers to the Ryder Cup, which is related to golf, and uses emojis that do not indicate a worrying event about the sun."
},
{
"tweet": {
"tweet_id": "1971668887197581560",
"text": "Major flooding in Bordj Bou Arreridj and M'Sila Provinces of Algeria over the past couple of days...🌊🌊🌊 https://t.co/inUWXpgjJ0",
"created_at": "2025-09-26T20:11:09Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses major flooding in specific provinces of Algeria, with no mention of a solar flare or any sun-related event. It is focused on weather conditions resulting from flooding rather than solar activity."
},
{
"tweet": {
"tweet_id": "1971666082936045689",
"text": "Have you noticed how many hurricanes starting with the letter \"I\" have been terribly destructive lately? It turns out there's a simple explanation. \nhttps://t.co/501lyIr1h8",
"created_at": "2025-09-26T20:00:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses hurricanes that start with the letter 'I' and their destructiveness, but it does not mention anything about solar flares or sun-related events. Therefore, it does not talk about a new worrying solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971664435933769964",
"text": "🍿🍿🍿",
"created_at": "2025-09-26T19:53:27Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet consists only of popcorn emojis, which do not provide any information about a solar flare or sun-related event. Therefore, it does not imply any concern or discussion regarding such events."
},
{
"tweet": {
"tweet_id": "1971657539185266786",
"text": "https://t.co/WqDssx8jpY",
"created_at": "2025-09-26T19:26:03Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not contain any information about a new solar flare or sun-related event. It may discuss other topics that are not relevant to solar activity."
},
{
"tweet": {
"tweet_id": "1971654210061324539",
"text": "RT @volcaholic1: Ladies and gents, I give you a box phone farm. \n\nThese create and manage fake accounts for disinformation, trolling, scams…",
"created_at": "2025-09-26T19:12:49Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or any sun-related event. It talks about a 'box phone farm' used for managing fake accounts, which is unrelated to solar activity."
},
{
"tweet": {
"tweet_id": "1971641679141908480",
"text": "Worlds oceans fail key health check as acidity crosses critical threshold for marine life.\n\nScientists call for renewed global effort to curb fossil fuels as seven of nine planetary boundaries now transgressed.\nhttps://t.co/rT4D8zAyo2",
"created_at": "2025-09-26T18:23:02Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses ocean health and the need to curb fossil fuels, with no mention of solar flares or sun-related events. It focuses on environmental issues related to marine life rather than solar activity."
},
{
"tweet": {
"tweet_id": "1971640773163503655",
"text": "Tropical storm alerts are expected to be issued in the Bahamas later today as a disturbance continues to organize. There is still significant uncertainty as to the details of how this will all shake out into next week. Here's the latest:\nhttps://t.co/KF6No3OAcj https://t.co/NgAdaaVwRI",
"created_at": "2025-09-26T18:19:26Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing tropical storm alerts and weather disturbances in the Bahamas, rather than a solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971640263425905130",
"text": "RT @volcaholic1: Severe Tropical Cyclone Opong has battered the Philippines, making landfall in Oriental Mindoro after tearing through Masb…",
"created_at": "2025-09-26T18:17:24Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet is discussing a severe tropical cyclone that has affected the Philippines. It does not mention anything about solar flares or sun-related events, so it does not meet the criteria of talking about a new worrying solar flare."
},
{
"tweet": {
"tweet_id": "1971629735940915242",
"text": "It's never too early to start getting prepared for a tropical storm or hurricane. Watch meteorologist @jordansteele show what you need to do during the countdown to landfall ⬇️",
"created_at": "2025-09-26T17:35:34Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing preparation for a tropical storm or hurricane, not a solar flare or any solar-related event. Therefore, it does not relate to the question about a worrying solar flare."
},
{
"tweet": {
"tweet_id": "1971627196843479195",
"text": "Residents of Essentuki, Russia, captured a murmuration of birds tonight. \n\nLarge groups moved together in changing patterns across the sky illuminated by the citys greenhouse lights. https://t.co/hxvCb9QFkm",
"created_at": "2025-09-26T17:25:29Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet describes a murmuration of birds in Essentuki, Russia, and mentions the lights of the city. It does not mention solar flares or any sun-related events."
},
{
"tweet": {
"tweet_id": "1971622293408244196",
"text": "Space is filling fast with Starlink and other satellites. \n\nWill orbit turn into a junkyard in 20 years? \n\nHow long before collisions create more debris?\n\nAre we taking this seriously enough?",
"created_at": "2025-09-26T17:06:00Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses the issue of satellite congestion and space debris, particularly focusing on the implications of increased satellite launches. There is no mention of solar flares or any sun-related events, making it clear that the tweet is not about such topics."
},
{
"tweet": {
"tweet_id": "1971621320258724347",
"text": "How cool is this! 🌳🌴🌱\nhttps://t.co/WMY3YiVN9G",
"created_at": "2025-09-26T17:02:08Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet expresses excitement about something related to nature (emojis of trees and plants) and does not mention or imply any solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971614351401640053",
"text": "*Hepatitis",
"created_at": "2025-09-26T16:34:26Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or a sun-related event. Instead, it references 'Hepatitis,' which is unrelated to solar activity."
},
{
"tweet": {
"tweet_id": "1971610237435039802",
"text": "One year ago today, Hurricane Helene struck Floridas Big Bend as a Category 4 storm, bringing catastrophic damage across the southeastern United States. \n\nThe hurricane caused severe inland flooding, left at least 250 people dead, and inflicted an estimated $78.7 billion in damages, making it one of the deadliest U.S. hurricanes in recent years.",
"created_at": "2025-09-26T16:18:06Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet discusses Hurricane Helene, its impact, and statistics related to it. It does not mention solar flares or sun-related events, so it is not relevant to the question."
},
{
"tweet": {
"tweet_id": "1971602661909950869",
"text": "At least 19 people have died this month after consuming bootleg alcohol in northwestern Russias Leningrad region near the border with Estonia, authorities said Friday.",
"created_at": "2025-09-26T15:47:59Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not mention anything related to solar flares or sun-related events. It discusses fatalities due to bootleg alcohol consumption in Russia, which is unrelated to solar activity."
},
{
"tweet": {
"tweet_id": "1971599948753129891",
"text": "Its time for the @rydercupusa. Here's a look at the gameday forecast. https://t.co/1cs63dkELg",
"created_at": "2025-09-26T15:37:12Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing the Ryder Cup and the gameday forecast, which is related to weather for the event. There is no mention of solar flares or sun-related events."
},
{
"tweet": {
"tweet_id": "1971599734159839648",
"text": "5 PEDIATRIC RED ADVANCED LIFE SUPPORT PATIENTS TRANSPORTED TO KENDALL. ALL PATIENTS TOOK EDIBLES https://t.co/MhkK6QQn78",
"created_at": "2025-09-26T15:36:21Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet is about pediatric patients and their transport, mentioning the use of edibles, which has no relation to solar flares or any sun-related events."
},
{
"tweet": {
"tweet_id": "1971598508294820191",
"text": "👀👀",
"created_at": "2025-09-26T15:31:29Z",
"username": "Volcaholic1"
},
"pass": false,
"reasoning": "The tweet does not provide any content or information regarding a solar flare or sun-related event. It simply contains an emoji response, which does not indicate concern or relevance to solar activity."
},
{
"tweet": {
"tweet_id": "1971595499384783162",
"text": "A wildfire sparked by lightning in July forced evacuations and closures as it destroyed dozens of structures. Now the National Park Service has announced when portions of the North Rim will reopen.\nhttps://t.co/NXYQ4s9Uae",
"created_at": "2025-09-26T15:19:32Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a wildfire caused by lightning and the reopening of portions of the North Rim by the National Park Service. It does not mention solar flares or any sun-related events."
},
{
"tweet": {
"tweet_id": "1971593953574273034",
"text": "RT @CharlesPeekWX: Heading east with the SC coast in my GPS, for reporting on what could be Imelda. With the anniversary of Hurricane Helen…",
"created_at": "2025-09-26T15:13:23Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet does not mention anything about a solar flare or any sun-related event. It is focused on reporting about a weather event related to Hurricane Imelda."
},
{
"tweet": {
"tweet_id": "1971591264194932825",
"text": "RT @smFISHMAN: Check out the first part of my sitdown with @JimCantore as @weatherchannel looks back at the impacts of #HurricaneHelene one…",
"created_at": "2025-09-26T15:02:42Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is primarily a retweet that discusses a sitdown interview related to Hurricane Helene and does not mention any solar flares or sun-related events."
},
{
"tweet": {
"tweet_id": "1971579324424946084",
"text": "RT @LaFemmePhojo: Were live from WNC with @weatherchannel this morning on the anniversary of Hurricane Helene. https://t.co/n4NCKKKaxi",
"created_at": "2025-09-26T14:15:15Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is primarily discussing a live report related to the anniversary of Hurricane Helene, not a new solar flare or sun-related event. There is no mention of solar activity in the tweet."
},
{
"tweet": {
"tweet_id": "1971577248231911566",
"text": "Recovery efforts are ongoing one year after Hurricane Helene devastated Western North Carolina. Senior National Correspondent @JMichaelsNews reports in Chimney Rock this morning. https://t.co/cBqIfpHGNg",
"created_at": "2025-09-26T14:07:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses recovery efforts from Hurricane Helene and does not mention any solar flare or sun-related event. It is focused on a weather event from the past rather than current or future solar activity."
},
{
"tweet": {
"tweet_id": "1971548459867250715",
"text": "RT @kellycass: Not only do we have Hurricane Humberto, but another area that is forecast to develop &amp; become Imelda. This one has the poten…",
"created_at": "2025-09-26T12:12:37Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses Hurricane Humberto and another developing storm named Imelda, which are both weather-related events, but it does not mention any solar flares or sun-related events."
},
{
"tweet": {
"tweet_id": "1971548310088352032",
"text": "The Southeast should prepare for a multiday flood threat beginning today. Several inches of rain could lead to flooding, and this is before any potential impacts from future Imelda next week. See the video for more. https://t.co/NUX8U23sp0 https://t.co/HqTUXrTeiJ",
"created_at": "2025-09-26T12:12:01Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a multiday flood threat and potential rainfall, but it does not mention any solar flares or sun-related events."
},
{
"tweet": {
"tweet_id": "1971533966277566921",
"text": "Future Imelda will likely develop Friday or Saturday, and could bring potential impacts to Georgia and the Carolinas next week. Watch this video for the latest track and timing. https://t.co/DmxhKd53ci https://t.co/gohU08qM4r",
"created_at": "2025-09-26T11:15:01Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a potential tropical storm named Imelda and its expected impacts on Georgia and the Carolinas, but there is no mention of solar flares or any sun-related events. Therefore, it does not address the question about new worrying solar activity."
},
{
"tweet": {
"tweet_id": "1971523139239555308",
"text": "Humberto has officially become a hurricane in the central Atlantic. Here's the latest. https://t.co/KF6No3OAcj",
"created_at": "2025-09-26T10:32:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing Humberto becoming a hurricane in the central Atlantic, which is related to weather events and hurricanes, not specifically to solar flares or sun-related events. Therefore, it does not talk about a new worrying solar flare."
},
{
"tweet": {
"tweet_id": "1971413690617303490",
"text": "Humberto continues to strengthen and is expected to become a major hurricane by the weekend. We are still watching Invest 94L. Here's the latest:\nhttps://t.co/KF6No3OAcj https://t.co/LjZlhILDYm",
"created_at": "2025-09-26T03:17:05Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet is discussing the strengthening of Hurricane Humberto and a weather event related to Invest 94L. It does not mention anything about a solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971380449575604703",
"text": "Tonight, we revisit areas that were at the center of the storms devastation. Watch \"Helene: One Year Later\" at 10/9c on The Weather Channel and streaming on The Weather Channel TV app: https://t.co/Feaf8zTBxX https://t.co/oWq5W8SANG",
"created_at": "2025-09-26T01:05:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet does not mention anything about solar flares or sun-related events. It talks about a documentary related to a storm and its aftermath."
},
{
"tweet": {
"tweet_id": "1971338240163733851",
"text": "RT @wxunfiltered: \"The risks for the east coast are going up\" - @DrRickKnabb \n\nInvest 94L (future #Imelda) is getting better organized this…",
"created_at": "2025-09-25T22:17:16Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a weather-related event (Invest 94L) and mentions a risk for the east coast, but does not reference a solar flare or sun-related event. There is no indication in the tweet that it relates to solar activities."
},
{
"tweet": {
"tweet_id": "1971333894419972570",
"text": "Two skydivers got the view of a lifetime when they saw a fully circular rainbow on their way back down to Earth. Our meteorologist Caitlin Kaiser explains how this was all possible. https://t.co/4jIe6iixzN https://t.co/N7FQuYL0QR",
"created_at": "2025-09-25T22:00:00Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses a visual phenomenon experienced by skydivers, specifically a circular rainbow, and does not mention anything about solar flares or sun-related events. Therefore, it does not talk about a worrying solar flare."
},
{
"tweet": {
"tweet_id": "1971303696760754264",
"text": "Watch as this gamer's session is interrupted by a 6.3 magnitude earthquake in Venezuela. Hopefully he got to pause his game. 🎮 https://t.co/Dr5oP4oBc3 https://t.co/URQuq14f2a",
"created_at": "2025-09-25T20:00:01Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses an earthquake event in Venezuela and its impact on a gamer's session, without any mention of solar flares or sun-related events."
},
{
"tweet": {
"tweet_id": "1971298477343711324",
"text": "Humberto could become the season's next major hurricane, but the next system, which is set to become Tropical Storm Imelda, could be a threat to the Bahamas and U.S. Here's what you need to know:\nhttps://t.co/KF6No3OAcj https://t.co/cW9hUk4sLV",
"created_at": "2025-09-25T19:39:16Z",
"username": "weatherchannel"
},
"pass": false,
"reasoning": "The tweet discusses tropical weather events, specifically hurricanes and tropical storms, rather than solar flares or sun-related phenomena. Therefore, it does not talk about a new worrying solar flare or sun-related event."
},
{
"tweet": {
"tweet_id": "1971271149146472527",
"text": "A hurricane is heading for Europe.\n#HurricaneGabrielle is on track for a direct hit on the Azores, with tropical storm conditions expected in Spain &amp; mainland Portugal.\nThis could be one of the most severe Atlantic systems to reach Iberia. https://t.co/2ngclARzt8",
"created_at": "2025-09-25T17:50:41Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet discusses a hurricane (Hurricane Gabrielle) heading for Europe, specifically the Azores, Spain, and Portugal. It does not mention a solar flare or any sun-related event. Therefore, it does not talk about concerns related to solar activity."
},
{
"tweet": {
"tweet_id": "1971269350138241256",
"text": "RT @MEERsrm: ”Our native trees are no longer native. Theyre foreigners now.” An arborists words sparked Mike Tidwells book on how climat…",
"created_at": "2025-09-25T17:43:32Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet does not mention anything about solar flares or sun-related events. It discusses native trees and climate-related themes, suggesting a focus on environmental issues rather than specifically solar activities."
},
{
"tweet": {
"tweet_id": "1971269335403593761",
"text": "RT @MEERsrm: This week, Dr. Ye Tao visited Solthis in Freetown to explore how MEERs passive cooling roofs could support healthcare centers…",
"created_at": "2025-09-25T17:43:28Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet does not mention anything related to a solar flare or a sun-related event. It discusses a visit by Dr. Ye Tao to explore passive cooling roofs for healthcare centers."
},
{
"tweet": {
"tweet_id": "1970752946238562809",
"text": "A prolific thunderstorm outbreak is ongoing across Californias Central Coast, with thousands of strikes recorded over the past 12 hours.\n\nThunderstorms are much further north than was expected by this time near Carmel and could reach the Bay Area soon. https://t.co/fUfmA0OrXE",
"created_at": "2025-09-24T07:31:31Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet is focused on a thunderstorm outbreak occurring in California, mentioning numerous lightning strikes and weather patterns. It does not mention solar flares or sun-related events, making it irrelevant to the question."
},
{
"tweet": {
"tweet_id": "1970618277450887423",
"text": "RT @bclemms: Super Typhoon Ragasa is ripping in Hong Kong. https://t.co/BcuyYCRm8Y",
"created_at": "2025-09-23T22:36:24Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet is about Super Typhoon Ragasa affecting Hong Kong and does not mention anything about solar flares or sun-related events. Therefore, it does not address the question."
},
{
"tweet": {
"tweet_id": "1970603236651659709",
"text": "A rare thunderstorm outbreak is possible along the Central Coast and into the SF Bay Area tonight into tomorrow. \n\nThunderstorms are a big deal in this part of the world because the Bay Area sees some of the fewest thunderstorms of any place on Earth outside the polar regions. https://t.co/m8hbkdCtB7",
"created_at": "2025-09-23T21:36:38Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a rare thunderstorm outbreak in the Central Coast and SF Bay Area, focusing on weather conditions rather than solar flares or sun-related events. There is no mention of solar activity or concerns about solar flares."
},
{
"tweet": {
"tweet_id": "1970591857735606340",
"text": "The greater Hong Kong area (GBA), home to 86 million people, is dodging a bullet as the inner core of Category 4 Typhoon Ragasa passes just south of the region with sustained winds of 130 mph and gusts up to 160 mph.\n\nMore than 750,000 people in South China have been forced to evacuate as the typhoon nears landfall, while Hong Kong has essentially been shut down due to the storm.",
"created_at": "2025-09-23T20:51:25Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet does not mention a solar flare or any sun-related event. It is focused on the impact of Typhoon Ragasa on the Greater Hong Kong Area."
},
{
"tweet": {
"tweet_id": "1970436467047739766",
"text": "RT @MEERsrm: Ariana Ejupi, MEERs Senior Project Officer, met with Mike Tidwell, Founder &amp; Director of the Chesapeake Climate Action Networ…",
"created_at": "2025-09-23T10:33:57Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet does not mention anything related to solar flares or sun-related events. It discusses a meeting between Ariana Ejupi and Mike Tidwell, which is not relevant to solar activity."
},
{
"tweet": {
"tweet_id": "1970278879987409289",
"text": "Insane video of a tornado roaring across Torch Lake in Northern Michigan, the same lake where I have family vacationed every summer for the last 10 years! \n\nhttps://t.co/pMrU6c44Op",
"created_at": "2025-09-23T00:07:45Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a tornado event in Michigan and does not mention any solar flares or sun-related phenomena."
},
{
"tweet": {
"tweet_id": "1970272162109100397",
"text": "RT @PappenheimWx: Speechless. Unreal tornado just occurred on Torch Lake in Michigan. I was watching the webcam when it initially touched d…",
"created_at": "2025-09-22T23:41:03Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a tornado event in Michigan and does not mention anything related to solar flares or sun-related events. Therefore, it does not address the question about a worrying solar flare."
},
{
"tweet": {
"tweet_id": "1970250776833597536",
"text": "Typhoon Ragasa was meant to be a once-in-50-year storm. Now, were seeing super typhoons like this every 34 years.\nThis isnt anything normal — its the #ClimateCrisis and insurance for Hong Kong is just about to get even more expensive. https://t.co/8QUtKGOn35",
"created_at": "2025-09-22T22:16:05Z",
"username": "PGDynes"
},
"pass": false,
"reasoning": "The tweet discusses the frequency of super typhoons and connects it to the climate crisis, but it does not mention solar flares or any sun-related events."
},
{
"tweet": {
"tweet_id": "1970191726456512878",
"text": "Europe has an air conditioning problem.\n\nAn estimated 175,000 people die from extreme heat every year in Europe, compared with just over 2,000 in the U.S. last year.\n\nOnly 20% of European homes have AC, versus 90% in the U.S.\n\nYou are nearly 4× more likely to die of extreme heat in Europe than to be fatally shot in the United States.\n\nIn Europe, future energy demands from installing AC will increasingly be supplied by clean energy sources.\n\nBut with rising temperatures driven by climate change, not having AC in Europe is becoming downright dangerous.\n\nIn Barcelona for example, the number of tropical nights has quadrupled since the 1950s.\n\nDespite having similar climates, Barcelona faces a 400% higher mortality risk than Los Angeles when temperatures climb above 30 °C (86 °F).\n\nGlobally, nights are warming faster than days due to climate change, and this is when mortality risk is highest, because the body cannot recover from daytime heat.\n\nWill Europe widely adopt AC, or continue sweating through brutal summers that are only getting worse?",
"created_at": "2025-09-22T18:21:26Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses the impacts of extreme heat and air conditioning issues in Europe, but it does not mention solar flares or any sun-related events. Instead, it focuses on climate change and the consequences of rising temperatures."
},
{
"tweet": {
"tweet_id": "1969924132998619483",
"text": "The Philippines Babuyan Islands are just hours away from a catastrophic strike by Category 5 Super Typhoon Ragasa, packing sustained winds of 165 mph and gusts up to 200 mph.\n\nThe remote islands are home to about 20,000 people, many of whom live in poverty. https://t.co/EmP7mAFmqW",
"created_at": "2025-09-22T00:38:07Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet is discussing an impending catastrophic strike by a Category 5 Super Typhoon Ragasa, not a solar flare or sun-related event. Therefore, it does not pertain to the question."
},
{
"tweet": {
"tweet_id": "1969891829702353172",
"text": "A lot of my friends in SoCal have been talking about how much more humid its felt over the last 10 years. and many of them have had to get AC because of it.\n\nHave you noticed the same thing living along the coast?\n\nIt's very humid today along the SoCal coast, with a marine heatwave offshore adding extra mugginess and tropical moisture streaming in from the south.",
"created_at": "2025-09-21T22:29:45Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses humidity levels and the impact of a marine heatwave, but it does not mention a solar flare or any sun-related event."
},
{
"tweet": {
"tweet_id": "1969887603869782200",
"text": "30 hour timelapse of the strongest storm on the planet, Category 5 Super Typhoon Ragasa in the Western Pacific. \n\nThe storm is packing 165 mph winds with catastrophic wind gusts up to 200 mph. https://t.co/PcQiBW6C0y",
"created_at": "2025-09-21T22:12:58Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses a super typhoon and its wind speeds, which are related to storm activity, not solar flares or sun-related events. Therefore, it does not address a worrying solar flare."
},
{
"tweet": {
"tweet_id": "1969577085829333268",
"text": "Wildfire smoke kills more people in the US each year than car crashes, 41,000 deaths annually, per a new Stanford study in Nature.",
"created_at": "2025-09-21T01:39:04Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses wildfire smoke and its impact on health, referencing a study related to air quality and death rates. It does not mention solar flares or any sun-related events, making it irrelevant to the question."
},
{
"tweet": {
"tweet_id": "1969567922696921466",
"text": "San Francisco has been drought-free for over 900 days, its longest stretch without drought in nearly 20 years. https://t.co/FflsNz3Gtb",
"created_at": "2025-09-21T01:02:40Z",
"username": "US_Stormwatch"
},
"pass": false,
"reasoning": "The tweet discusses San Francisco's drought-free status and does not mention solar flares or any sun-related events. It focuses on local weather conditions and their history."
}
],
"count": 68,
"filter_question": "Is this tweet talking about a new worrying solar flare or sun-related event?",
"summarization_question": "Summarize the state of the sun last week",
"summary": "No tweets passed the filter"
},
"completed_at": "2025-09-26T23:08:58.861315Z",
"processing_time_seconds": 17
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,27 @@
# Commission Jobs Script
A script to commission filtering jobs on the Twitter server with separate filter and summarization questions.
## Usage
```sh
commission-job.sh <filter_question> <summarization_question> <list_name> <output-filename>
```
## Examples
```sh
./commission-job.sh "Is this tweet talking about an important economics development" "What are the key economics events this week?" "econ" "econ.md"
```
## Parameters
- **filter_question**: The question used to filter tweets (determines which tweets pass the filter)
- **summarization_question**: The question used to guide the summary generation
- **list_name**: The name of the tweet list to process
The script will:
1. Submit a job to the server
2. Poll for job status every 2 seconds
3. Display progress updates
4. Show the final results when complete

View File

@ -0,0 +1,52 @@
# TODO: Commission Jobs Improvements
## Completed
- [x] Update script to use new `filter_question` and `summarization_question` API fields
- [x] Add input validation and usage instructions
- [x] Update README with examples and documentation
## Potential Improvements
### Script Enhancements
- [ ] Add support for filtering by users instead of just lists
- [ ] Add option to save results to a file (JSON or markdown format)
- [ ] Add timeout handling for long-running jobs
- [ ] Add retry logic for network failures
- [ ] Add colored output for better readability
- [ ] Add option to specify custom server URL (not hardcoded)
### Configuration
- [ ] Add config file support for default questions and lists
- [ ] Add environment variable support for server URL and API keys
- [ ] Add predefined question templates for common use cases
### Output Improvements
- [ ] Format summary output as markdown
- [ ] Add option to only show passed tweets vs all tweets
- [ ] Add statistics summary (total tweets, passed tweets, percentage)
- [ ] Add option to export results in different formats (CSV, JSON, MD)
### Error Handling
- [ ] Better error messages for common failures
- [ ] Validate list exists before starting job
- [ ] Handle job timeout scenarios gracefully
- [ ] Add option to resume failed jobs
### Advanced Features
- [ ] Batch processing multiple lists
- [ ] Comparison mode (run same questions on different lists)
- [ ] Historical analysis (compare results over time)
- [ ] Integration with other tools (email notifications, Slack, etc.)
## Usage Examples to Test
```bash
# AI developments
./commission-job.sh "Does this tweet discuss AI developments or research?" "What are the key AI breakthroughs and developments mentioned?" "ai-og"
# Economic indicators
./commission-job.sh "Does this tweet mention economic indicators or market trends?" "What are the main economic trends and forecasts discussed?" "forecasting"
# Political developments
./commission-job.sh "Does this tweet discuss political developments or policy changes?" "What are the key political developments and policy changes mentioned?" "whitehouse"
```

View File

@ -0,0 +1,61 @@
#!/bin/bash
filter_question="$1"
summarization_question="$2"
list="$3"
filename="$4"
if [ -z "$filter_question" ] || [ -z "$summarization_question" ] || [ -z "$list" ]; then
echo "Usage: $0 <filter_question> <summarization_question> <list_name> <output_file_name>"
echo "Example: $0 'Is this tweet talking about an important whitehouse action?' 'Summarize what the White house is up to this week.' 'whitehouse' '03-whitehouse.md'"
exit 1
fi
# Create JSON payload using jq to properly escape values
JSON_PAYLOAD=$(jq -n \
--arg filter_question "$filter_question" \
--arg summarization_question "$summarization_question" \
--arg list "$list" \
'{
"filter_question": $filter_question,
"summarization_question": $summarization_question,
"list": $list
}')
JOB_RESPONSE=$(curl -X POST https://tweets.nunosempere.com/api/filter-job \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD")
# Extract job ID
JOB_ID=$(echo $JOB_RESPONSE | jq -r '.data.job_id')
echo "Created job: $JOB_ID"
# 2. Poll for status until complete
while true; do
STATUS=$(curl -s "https://tweets.nunosempere.com/api/filter-job/$JOB_ID/status")
CURRENT_STATUS=$(echo $STATUS | jq -r '.data.status')
echo "Status: $CURRENT_STATUS"
if [ "$CURRENT_STATUS" = "completed" ]; then
echo "Job completed!"
break
elif [ "$CURRENT_STATUS" = "failed" ]; then
echo "Job failed: $(echo $STATUS | jq -r '.data.error_message')"
exit 1
fi
# Show progress
echo $STATUS | jq '.data.progress'
sleep 2
done
# 3. Get results
WEEK=$(date +%V)
mkdir -p $WEEK
curl "https://tweets.nunosempere.com/api/filter-job/$JOB_ID/results" | jq | tee "$WEEK/$filename.full"
cat "$WEEK/$filename.full" | jq -r .data.results.summary > "$WEEK/$filename.md"

View File

@ -0,0 +1,17 @@
reports:
./commission-job.sh "Is this tweet talking about an important economics development" "What are the key economics events this week?" "econ" "01-econ.md"
./commission-job.sh "Is this tweet talking about a development in shipping/freight/trucking, or about a new statistic or economic indicator?" "Summarize shipping/freight/trucking and related economic indicators this week" "freight" "02-freight.md"
./commission-job.sh "Is this tweet talking about an important whitehouse action?" "Summarize what the White house is up to this week." "whitehouse" "03-whitehouse.md"
./commission-job.sh "Is this tweet talking about an important event?" "Summarize important events this week" "mainstream-us-media" "04-mainstream-us-media.md"
./commission-job.sh "Is this tweet talking about an important event?" "Summarize important events this week" "us-politics-commentators" "05-mainstream-us-media.md"
./commission-job.sh "Is this tweet talking about a Russia/Ukraine event, or about NATO countries' response to it?" "Summarize events related to the Russia/Ukraine war and NATO countries' related actions" "russia-ukraine-nato" "06-russia-ukraine-nato.md"
./commission-job.sh "Does this tweet refer to a significant event?" "Summarize significant events as captured by OSINT sources" "osint" "07-venezuela.md"
./commission-job.sh "Is this tweet talking about an important event in Venezuela" "Summarize What happened in and around Venezuela this week." "venezuela" "08-venezuela.md"
./commission-job.sh "Is this tweet talking about a disease outbreak, new paper, administrative action, etc?" "Summarize biorisk news last week" "biorisk" "09-biorisk.md"
./commission-job.sh "Is this tweet talking about a significant technological development?" "Summarize reported technological developments last week" "general-tech" "10-tech.md"
./commission-job.sh "Is this tweet talking about a cyberattack?" "Summarize cyberattack news last week" "cyber" "11-cyber.md"
./commission-job.sh "Is this tweet talking about a development in climate?" "Summarize climate developments last week" "climate" "12-climate.md"
./commission-job.sh "Is this tweet talking about a natural disaster or storm that has or will affect over 10,000 people?" "Summarize natural disasters this week" "natural-disasters" "13-natural-disasters.md"
./commission-job.sh "Is this tweet talking about agricultural developments?" "Summarize aggricultural developments, across production, but also commodities trade &c last week." "natural-disasters" "14-agriculture.md"
./commission-job.sh "Is this tweet talking about a new worrying solar flare or sun-related event?" "Summarize the state of the sun last week" "natural-disasters" "15-solar.md"

View File

@ -0,0 +1,22 @@
module github.com/NunoSempere/twitter-cli-display-tui
go 1.23.4
require (
github.com/gdamore/tcell/v2 v2.8.1
github.com/jackc/pgx/v5 v5.7.4
github.com/joho/godotenv v1.5.1
github.com/mattn/go-runewidth v0.0.16
)
require (
github.com/gdamore/encoding v1.0.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
)

View File

@ -0,0 +1,104 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU=
github.com/gdamore/tcell/v2 v2.8.1/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,3 @@
AIHegemonyMemes
aixbt_agent
truth_terminal

View File

@ -0,0 +1,583 @@
0xellipse
adrusi
AFP
AISafetyMemes
alexandrosM
AlexGodofsky
alexmccullaaa
Algon_33
alicemazzy
AlmostMedia
AmirDaftari
anderssandberg
AnnaLeptikon
anthrupad
ApriiSR
Arnold_Ventures
AskYatharth
AstraKernel
asymmetricinfo
atroyn
AvetisMuradyan
awesomekling
azusaHFT
babieswithb
BackTheBunny
bdsqlsz
benlandautaylor
benrayfield
BenShindel
BickerinBrattle
bierlingm
caesararum
CalJamieson
chamath
CharlesFLehman
ChinaBugle
ChrisChipMonk
CNASdc
ConradBastable
ContrarianCurse
criticalthreats
croissanthology
culpable_mink
curtis_yarvin
dalibali2
DanielMiessler
darkpatterns
darth_vasya
David_Kasten
davidmanheim
deepfates
DefenderOfBasic
dick_nixon
dnak0v
drethelin
earnestpost
eigenrobot
elder_plinius
eliasluoto
eshear
FFmpeg
fleetingbits
foxyforecaster
FrameworkPuter
freed_dfilan
GabrielPeterss4
GaetenD
gak_pdx
GergelyOrosz
g_leech_
GZilgalvis
halogen1048576
hamandcheese
heynibras
HZoete
ianellisjones
inflammateomnia
ingalala
isnit0
IvanVendrov
jackson99ai
JavierBlas
JDVance
JgaltTweets
JohnArnoldFndtn
JohnDCook
johnrmyers
JorgeGalindo
JSchwarz91
Just_Curius
kanyewest
karolkarpinski
KelseyTuoc
KitsonJ1
LeahLibresco
leebriskcyrano
levelsio
Lizquidity
loquitur_ponte
ludwigABAP
lugaricano
lu_sichu
manic_pixie_agi
mattparlmer
mbateman
met2llurgist
metaproph3t
MickBransfield
MikePFrank
Mollyploofkins
MorlockP
moseskagan
mountainwesttax
MyLatinLife
NathanB60857242
NathanpmYoung
norabelrose
norvid_studies
nosilverv
nptacek
orthonormalist
OSINTNW
OurWorldInData
pachabelcanon
panchromaticity
parafactual
parakeetnebula
pastaraspberry
pastasnack_e
patio11
paulg
pelecolas
peterwildeford
pjchougule
PoliticalKiwi
Polymarket
polyminnow
ProfessorPujol
prophet_notes
psychosort
purplcabbage
pursuitofprog
QuintinPope5
RapidResponse47
real_lord_miles
rethink_x
RianCFFWhitton
robinhanson
RokoMijic
_rotimia
rsg
rumtin
sabethunder
ScarletAstrorum
sci_fi_infra
sebkrier
SecRubio
sentdefender
shagbark_hick
shashj
shinboson
singularitttt
somewheresy
s_r_constantin
SSGamblers
stanfordNYC
stianwestlake
stonewall1312
St_Rev
suntzoogway
sureailabs
TechEmails
teortaxesTex
TetraspaceWest
TheOisinMoran
thiagovscoelho
This_Liss
TolgaBilge_
tracewoodgrains
trump_repost
TylerAlterman
typesfast
uzpg_
visakanv
VitalikButerin
VOCPEnglish
wander_investor
wasabiboat
WillManidis
wmhuo168
xsphi
yacineMTB
yashkaf
zephyr_z9
zetalyrae
allisondman
almostlikethat
a_real_society
_brianpotter
rlacombe
random_walker
spicey_lemonade
stevekuhn16
melissa
tzhongg
ca_highlights
typicalmitul
GrandBastion
Abi0lvera
demiurgently
whistlecube
stuhlmueller
mnvrsngh
Saraht0n1n
juliangough
JesusFerna7026
sidkap_
MoralPriest
cat_neuron
AvitalBalwit
robi_rahman
zmkzmkz
dadkins_
JuanB_GM
blingdivinity
ARIA_research
abstrusivethots
literalbanana
skrishnan47
rasheedguo
valofpszz
Tianyi_Alex_Qiu
UnderwaterBepis
f
yishan
erin_f
thlarsen
SZekany
gdechichi
SecDef
uberboyo
TutorVals
DKokotajlo
ScottEa33474273
BondeKirk
joespurpleshirt
birchlse
relic_radiation
RomeoStevens76
doseofzero
therealpananon
kave_rennedy
ElliotGlazer
Jiankui_He
HitMissWisdom
repdinatitus
jholbo1
matthewjablack
MichealReilly
_npfoss
joshelman
peterhartree
drewsweettweets
sama
killerstorm
OedoSoldier
kepano
Bayesian0_0
AlecRad
jonny_morse
eddybuild
zeta_globin
MarkFriedenbach
stephen_zerfas
davidshor
saulmunn
shroominic
tshugart3
alix_ph
baselinescene
snewmanpv
drprevost
ChrisVanHollen
SteveWitkoff
ajespivera
kb_french
raymondadouglas
john_henry
climate_ben
IndraStocks
polymarketinfo
edgefills
mxslk
alex_rigatoni
geoffanders
thesnobdotcom
reasonisfun
RaoPoornima
neats29
kristijan_moves
wolftivy
Turn_Trout
zheanxu
RamVasuthevan
Grimezsz
Clutterbug_Me
repligate
FANswitchboard
diegocaleiro
BrandenSpikes
katiconen
captain_mrs
chefjoseandres
Peter__Wood
exgenesis
edgar_z_lin
ELuttwak
JasonGMatheny
logangraham
Grad62304977
kanzure
haththerescuer
LordDreadwar
Trotztd
rossgritz
Cmdr_Hadfield
patrickdward
adamhowes
MilanGriffes
mriiirx
Usama_Polani
Suhail
AndrewCritchPhD
edsaperia
crush_crime
BenSoskis
MyklClason
freeshreeda
jaltma
itsarnavb
patrickc
JoeGillis23
an_interstice
goodenoughjoey
isaakfreeman
FU_joehudson
nic_kup
nikitabier
travis4nh
COMSPOC
prashantfonseka
ryan_kidd44
finnhambly
rglenner
chisness
tamaybes
PTetlock
julianboolean_
MichaelJDickens
_RossPfeiffer
amsiegel
AppSpartacus
_rossry
typesfaster
jpradoabril
MuireallPrase
iamgingertrash
BarughTyrone
ericneyman
AllSourceA
fchollet
RichardMCNgo
RealCarlAllen
visakanx
sriramk
layer07_yuxi
nearcyan
alexanderklew
NWSSWPC
Alex_Gruver1
42irrationalist
DareFailed
rdramanet
XiaoWei___
janonacct
Morphenius
claddnl
balajis
matthewclifford
hanseulnam
PauseusMaximus
movebettersam
Squee451
TarasBob
IsaacKing314
v_maini
Willy_Egy
ruoxijia
nwspk
JiachenWang97
xuanalogue
rsalame7926
LaChispaCultura
deepseek_ai
VivekGRamaswamy
aftfuture
mmjukic
Lewis_Bollard
JonLeighton1
zachxbt
blockedfreq
ben_r_hoffman
DuncanMcClement
JohnHal57303115
Caro_Jeanmaire
hnykda
keendawg
MarwanData
alonc31
sapph_star
sam_atis
Meaningness
stencel_jakub
_bartoszzajac
agentofuser
karpathy
HiFromMichaelV
hankgreen
EnriqueIrrazab2
IMBavitz
Juan_VaGu
hrosspet
stevenkaas
jd_pressman
nc_znc
psychiel
forshaper
vidur_kapur
Jotto999
tgof137
cmonkey
I_am_awareness
antirez
LaurangeGreen
onelikelylad1
CRSegerie
Vasco__Grilo
echetus
weidai11
ruvaag
Aria_Babu
qntm
tenobrus
pvllss
jkeatn
7ip7ap
BrendanEich
Dominic2306
SharmakeFarah14
pre_rlhf
dawnlightmelody
FellowHominid
Scholars_Stage
SentinelTeamHQ
LuisCostigan1
trylks
UnringThisBell
karolineleavitt
Benyi_vpc
AlexPalcuie
michaelhpage
yoltartar
DanHendrycks
Ha_uke
0xperp
nayafia
cmeinel
CommunityNotes
SamoBurja
JorgeGCouto
vivian_belenky
LiamKovatch
davidgoggins
yudhister_
Xavi_Vill
WineMomBets
EHEefting
QiaochuYuan
JustineTunney
gallabytes
carl_feynman
base_rate_times
rai_sur11
CharlesD353
violethourblog
AndrewJEaddy
chromobear
yaroshipilov
JoshuaBlake_
tmkadamcz
davidroodman
MatthewJBar
andrewgrtz
zackmdavis
KerryLVaughan
artoriastech
Imara1408
ohabryka
TradeandMoney
CineraVerinia
daniel_filan
iabvek
gcolbourn
datagenproc
orellanin
joel_bkr
gwern
venkyganesan
AlvaroDeMenard
98Pollito
Jsevillamol
natalia__coelho
MWStory
jw_mann
akrolsmir
Sam__Enright
swift_centre
morphillogical
joshcmorrison
mishayagudin
teng0unsecret0
AaronGertler
ryancareyai
ozziegooen
tenthkrige
lxrjl
RossiSci
finmoorhouse
ltreszkai
csteadone
brightertmrrw
jpsimmon
niplav_site
alexanderwales
bianchini_alain
eli_lifland
Sheikheddy
amcivtwit
jessi_cata
ID_AA_Carmack
bcroesch
celloMolly
ArbResearch
evavivalt
MitiSaksena
Tegan_McCaslin
EpochAIResearch
alexdemarsh
StefanFSchubert
dschwarz26
EgeErdil2
DeZacliff
webmasterdave
juan_cambeiro
dfrsrchtwts
Domahhhh
LinchZhang
L___orenzo
Kat__Woods
SmoLurks
ClayGraubard
jahooma
jlagerros
llumdepalau
deanwball
Hello_World
euan_ong
JohnHCochrane
Anima_Int
Mikey0x_
snwy_me
vsbuffalo
BenDoBrown

View File

@ -0,0 +1,6 @@
Domahhhh
shayne_coplan
PTetlock
MickBransfield
JGalt
eightyhi

View File

@ -0,0 +1,87 @@
AnnaLeptikon
BenShindel
davidmanheim
foxyforecaster
freed_dfilan
g_leech_
ingalala
Just_Curius
NathanpmYoung
erin_f
kave_rennedy
saulmunn
raymondadouglas
exgenesis
tamaybes
julianboolean_
v_maini
DuncanMcClement
MarwanData
alonc31
sapph_star
sam_atis
stencel_jakub
psychiel
vidur_kapur
Vasco__Grilo
echetus
Aria_Babu
pvllss
Ha_uke
0xperp
JorgeGCouto
vivian_belenky
LiamKovatch
davidgoggins
yudhister_
rai_sur11
CharlesD353
AndrewJEaddy
tmkadamcz
zackmdavis
KerryLVaughan
ohabryka
CineraVerinia
daniel_filan
iabvek
gcolbourn
datagenproc
joel_bkr
AlvaroDeMenard
98Pollito
Jsevillamol
natalia__coelho
MWStory
jw_mann
akrolsmir
Sam__Enright
joshcmorrison
mishayagudin
teng0unsecret0
ryancareyai
ozziegooen
tenthkrige
RossiSci
finmoorhouse
ltreszkai
csteadone
brightertmrrw
niplav_site
eli_lifland
Sheikheddy
celloMolly
evavivalt
MitiSaksena
Tegan_McCaslin
alexdemarsh
dschwarz26
EgeErdil2
DeZacliff
juan_cambeiro
dfrsrchtwts
Kat__Woods
SmoLurks
ClayGraubard
jahooma
jlagerros
Anima_Int

View File

@ -0,0 +1,24 @@
# Sentinel signal
VOCPEnglish
chefjoseandres
ELuttwak
RapidResponse47
OSINTNW
typesfast
sentdefender
criticalthreats
JDVance
teortaxesTex
artoriastech
JgaltTweets
zephyr_z9
SecRubio
Mollyploofkins
SteveWitkoff
trump_repost
SecDef
ChinaBugle
CNASdc
elder_plinius
NWSSWPC

View File

@ -0,0 +1,12 @@
WhiteHouse
VP
PressSec
RapidResponse47
DODResponse
PamBondi
howardlutnick
SecRubio
marcorubio
tedcruz
JDVance
trump_repost

View File

@ -0,0 +1,577 @@
package main
import (
"fmt"
"flag"
"os/exec"
"runtime"
"context"
"path/filepath"
"os"
"slices"
"strings"
"time"
"github.com/jackc/pgx/v5"
"github.com/joho/godotenv"
"github.com/gdamore/tcell/v2"
"github.com/mattn/go-runewidth"
)
var SHORT_TWEET_SIZE int = 180
func newApp() (*App, error) {
screen, err := tcell.NewScreen()
if err != nil {
return nil, fmt.Errorf("failed to create screen: %v", err)
}
if err := screen.Init(); err != nil {
return nil, fmt.Errorf("failed to initialize screen: %v", err)
}
return &App{
screen: screen,
selectedIdx: 0,
currentPage: 0,
}, nil
}
func (a *App) loadTweets(accountsList string) ([]Tweet, error) {
if err := godotenv.Load(".env"); err != nil {
return []Tweet{}, fmt.Errorf("error loading .env file: %v", err)
}
url := os.Getenv("DATABASE_POOL_URL")
if url == "" {
return []Tweet{}, fmt.Errorf("DATABASE_POOL_URL environment variable not set")
}
ctx := context.Background()
conn, err := pgx.Connect(ctx, url)
if err != nil {
return []Tweet{}, fmt.Errorf("in client, failed to connect to database: %v", err)
}
defer conn.Close(ctx)
rows, err := conn.Query(ctx, "SELECT tweet_id, tweet_text, username, created_at FROM tweets0x001 WHERE created_at >= NOW() - INTERVAL '37 day' ORDER BY created_at DESC")
// 37 day
if err != nil {
return []Tweet{}, fmt.Errorf("failed to query tweets: %v", err)
}
defer rows.Close()
validAccounts, err := getAccounts(accountsList)
if err != nil {
return []Tweet{}, fmt.Errorf("didn't get accounts: %v", err)
}
var sources []Tweet
for rows.Next() {
var s Tweet
var date time.Time
err := rows.Scan(&s.ID, &s.Text, &s.Username, &date)
s.CreatedAt = date.Format("2006-01-02 15:04:05")
if err != nil {
return []Tweet{}, fmt.Errorf("failed to scan row: %v", err)
}
if slices.Contains(validAccounts, s.Username) {
sources = append(sources, s)
}
}
return sources, nil
}
func getAccounts(accountsList string) ([]string, error){
accountsDir := "./lists"
accountsPath := filepath.Join(accountsDir, accountsList+".txt")
accountsData, err := os.ReadFile(accountsPath)
if err != nil {
return []string{}, fmt.Errorf("error reading accounts file: %v", err)
}
accounts := strings.Split(strings.TrimSpace(string(accountsData)), "\n")
// Filter out empty and commented accounts
var validAccounts []string
for _, account := range accounts {
if account = strings.TrimSpace(account); account != "" && !strings.HasPrefix(account, "#") {
validAccounts = append(validAccounts, account)
}
}
return validAccounts, nil
}
func (a *App) Run() error {
// Try to load from cache
allTweets, err := a.loadTweets(a.accountsList)
if err != nil {
return err
}
// Filter tweets based on length preferences and username
a.tweets = make([]Tweet, 0, len(allTweets))
for _, tweet := range allTweets {
// Skip if username filter is set and doesn't match
if a.filterUsername != "" && tweet.Username != a.filterUsername {
continue
}
tweetLength := len(tweet.Text)
if (a.shortTweetsOnly && tweetLength < SHORT_TWEET_SIZE) ||
(a.longTweetsOnly && tweetLength >= SHORT_TWEET_SIZE) ||
(!a.shortTweetsOnly && !a.longTweetsOnly) {
a.tweets = append(a.tweets, tweet)
}
}
if len(a.tweets) == 0 {
if a.filterUsername != "" {
return fmt.Errorf("no tweets found from user @%s", a.filterUsername)
}
return fmt.Errorf("no tweets match the current length filter")
}
for {
a.draw()
switch ev := a.screen.PollEvent().(type) {
case *tcell.EventKey:
startIdx, endIdx := a.getPageBoundaries(a.currentPage)
switch ev.Key() {
case tcell.KeyEscape, tcell.KeyCtrlC:
return nil
case tcell.KeyUp:
if a.selectedIdx > 0 {
a.selectedIdx--
if a.selectedIdx < startIdx {
a.currentPage--
}
}
case tcell.KeyDown:
if a.selectedIdx < len(a.tweets)-1 {
a.selectedIdx++
if a.selectedIdx >= endIdx {
a.currentPage++
}
}
case tcell.KeyRight:
nextStart, _ := a.getPageBoundaries(a.currentPage + 1)
if nextStart < len(a.tweets) {
a.currentPage++
a.selectedIdx = nextStart
}
case tcell.KeyLeft:
if a.currentPage > 0 {
a.currentPage--
prevStart, _ := a.getPageBoundaries(a.currentPage)
a.selectedIdx = prevStart
}
case tcell.KeyRune:
switch ev.Rune() {
case 'h':
if a.currentPage > 0 {
a.currentPage--
prevStart, _ := a.getPageBoundaries(a.currentPage)
a.selectedIdx = prevStart
}
case 'j':
if a.selectedIdx < len(a.tweets)-1 {
a.selectedIdx++
if a.selectedIdx >= endIdx {
a.currentPage++
}
}
case 'k':
if a.selectedIdx > 0 {
a.selectedIdx--
if a.selectedIdx < startIdx {
a.currentPage--
}
}
case 'l':
nextStart, _ := a.getPageBoundaries(a.currentPage + 1)
if nextStart < len(a.tweets) {
a.currentPage++
a.selectedIdx = nextStart
}
case 'q', 'Q':
return nil
case 'o', 'O', 'r', 'R':
if err := a.handleCommand(ev.Rune()); err != nil {
return err
}
}
}
case *tcell.EventResize:
a.screen.Sync()
}
}
}
func (a *App) getPageBoundaries(page int) (startIdx, endIdx int) {
width, height := a.screen.Size()
availableHeight := height - 0
// Find start index by walking through previous pages
startIdx = 0
currentY := 0
for p := 0; p < page; p++ {
// Find where this page ends
for startIdx < len(a.tweets) {
tweetHeight := a.calculateTweetHeight(a.tweets[startIdx], width)
if currentY+tweetHeight > availableHeight {
currentY = 0
break
}
currentY += tweetHeight
startIdx++
}
}
// Find end index by calculating how many tweets fit from the start
endIdx = startIdx
currentY = 0
for endIdx < len(a.tweets) {
tweetHeight := a.calculateTweetHeight(a.tweets[endIdx], width)
if currentY+tweetHeight > availableHeight {
break
}
currentY += tweetHeight
endIdx++
}
return startIdx, endIdx
}
func convertToNormal(text string) string {
replacements := map[rune]rune{
// Lowercase mappings
'𝗮': 'a', '𝗯': 'b', '𝗰': 'c', '𝗱': 'd', '𝗲': 'e', '𝗳': 'f',
'𝗴': 'g', '𝗵': 'h', '𝗶': 'i', '𝗷': 'j', '𝗸': 'k', '𝗹': 'l',
'𝗺': 'm', '𝗻': 'n', '𝗼': 'o', '𝗽': 'p', '𝗾': 'q', '𝗿': 'r',
'𝘀': 's', '𝘁': 't', '𝘂': 'u', '𝘃': 'v', '𝘄': 'w',
'𝘅': 'x', '𝘆': 'y', '𝘇': 'z',
// Uppercase mappings
'𝗔': 'A', '𝗕': 'B', '𝗖': 'C', '𝗗': 'D', '𝗘': 'E', '𝗙': 'F',
'𝗚': 'G', '𝗛': 'H', '𝗜': 'I', '𝗝': 'J', '𝗞': 'K', '𝗟': 'L',
'𝗠': 'M', '𝗡': 'N', '𝗢': 'O', '𝗣': 'P', '𝗤': 'Q', '𝗥': 'R',
'𝗦': 'S', '𝗧': 'T', '𝗨': 'U', '𝗩': 'V', '𝗪': 'W',
'𝗫': 'X', '𝗬': 'Y', '𝗭': 'Z',
}
var result strings.Builder
for _, char := range text {
if normalChar, found := replacements[char]; found {
result.WriteRune(normalChar)
} else {
result.WriteRune(char) // if character is not in map, keep it as is
}
}
return result.String()
}
func (a *App) draw() {
a.screen.Clear()
width, height := a.screen.Size()
style := tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorWhite)
selectedStyle := tcell.StyleDefault.Background(tcell.Color24).Foreground(tcell.ColorWhite)
// Get the tweets that fit on this page
startIdx, endIdx := a.getPageBoundaries(a.currentPage)
// Draw the tweets
currentY := 0
for idx := startIdx; idx < endIdx; idx++ {
tweet := a.tweets[idx]
currentStyle := style
if idx == a.selectedIdx {
currentStyle = selectedStyle
}
// Cap tweet text length at 2500 characters
text := tweet.Text
if len(text) > 2500 {
text = text[:2500] + "..."
}
text = convertToNormal(text)
tweetLine := fmt.Sprintf("[%d] @%s: %s | %s", idx, tweet.Username, text, tweet.CreatedAt)
lastY := drawText(a.screen, 0, currentY, width, currentStyle, tweetLine)
currentY = lastY + 1
}
// Draw help text at the bottom
helpText := "^/v: Navigate | <>: Change Page | o: Open | r: Reply | q: Quit"
if height > 0 {
drawText(a.screen, 0, height-1, width, style, helpText)
}
a.screen.Show()
}
func (a *App) calculateTweetHeight(tweet Tweet, width int) int {
// Cap tweet text length at 2500 characters
text := tweet.Text
if len(text) > 2500 {
text = text[:2500] + "..."
}
if tweet.Username == "VOCPEnglish" {
text = convertToNormal(text)
}
// Format the tweet line as it will be displayed
tweetLine := fmt.Sprintf("[%d] @%s: %s | %s", tweet.ID, tweet.Username, text, tweet.CreatedAt)
// Count how many lines this tweet will take using proper Unicode width
lines := 1
currentLineWidth := 0
for _, r := range tweetLine {
runeWidth := runewidth.RuneWidth(r)
if currentLineWidth+runeWidth > width {
lines++
currentLineWidth = runeWidth
} else {
currentLineWidth += runeWidth
}
}
return lines
}
func drawText(screen tcell.Screen, x, y, maxWidth int, style tcell.Style, text string) int {
currentX := x
currentY := y
for _, r := range text {
runeWidth := runewidth.RuneWidth(r)
if currentX+runeWidth > x+maxWidth {
// Move to next line
currentY++
currentX = x
}
screen.SetContent(currentX, currentY, r, nil, style)
currentX += runeWidth
}
return currentY
}
func (a *App) handleCommand(cmd rune) error {
if len(a.tweets) == 0 {
return nil
}
currentTweet := a.tweets[a.selectedIdx]
switch cmd {
case 'o', 'O':
// Open tweet in browser
tweetURL := fmt.Sprintf("https://twitter.com/user/status/%s", currentTweet.ID)
return openBrowser(tweetURL)
case 'r':
// Get reply text from user
reply := a.getInput("Reply: ")
if reply == "" {
return nil // User cancelled
}
// Save current screen state and clean up terminal
a.screen.Fini()
fmt.Print("\033[H\033[2J") // Clear screen
// Cap tweet text length for display
text := currentTweet.Text
if len(text) > 2500 {
text = text[:2500] + "..."
}
// Show feedback
fmt.Printf("Sending reply to tweet: %s\n", text)
fmt.Printf("Your reply: %s\n", reply)
// Construct the command that will be executed
cmdStr := fmt.Sprintf("tweet -d %s %q", currentTweet.ID, reply)
// Show the command that will be executed
fmt.Printf("\nExecuting command:\n$ %s\n\n", cmdStr)
// Use split to separate command and its arguments
cmdArgs := []string{"-i", "-c", cmdStr}
bashCmd := exec.Command("bash", cmdArgs...) // Use exec.Command directly, no need for quotes
err := bashCmd.Run()
// Show result and wait for user input
if err != nil {
fmt.Printf("\nError sending reply: %v\n", err)
} else {
fmt.Println("\nReply sent successfully!")
}
fmt.Print("\nPress Enter to continue...")
fmt.Scanln() // Wait for Enter key
// Reinitialize screen
screen, err := tcell.NewScreen()
if err != nil {
return fmt.Errorf("failed to create new screen: %v", err)
}
if err := screen.Init(); err != nil {
return fmt.Errorf("failed to initialize new screen: %v", err)
}
a.screen = screen
/*
case 'R':
allTweets, ok := loadFromCache(a.accountsList)
if !ok {
return fmt.Errorf("no cached tweets available - please run fetcher first")
}
// Filter tweets based on length preferences and username
a.tweets = make([]Tweet, 0, len(allTweets))
for _, tweet := range allTweets {
// Skip if username filter is set and doesn't match
if a.filterUsername != "" && tweet.Username != a.filterUsername {
continue
}
tweetLength := len(tweet.Text)
if (a.shortTweetsOnly && tweetLength < SHORT_TWEET_SIZE) ||
(a.longTweetsOnly && tweetLength >= SHORT_TWEET_SIZE) ||
(!a.shortTweetsOnly && !a.longTweetsOnly) {
a.tweets = append(a.tweets, tweet)
}
}
// Reset selection if it's now out of bounds
if a.selectedIdx >= len(a.tweets) {
a.selectedIdx = len(a.tweets) - 1
}
if a.selectedIdx < 0 {
a.selectedIdx = 0
}
*/
}
return nil
}
func (a *App) getInput(prompt string) string {
// Clear bottom of screen
width, height := a.screen.Size()
style := tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorWhite)
// Create a buffer for multiline input
var lines []string
currentLine := ""
cursorX := len(prompt)
cursorY := height - 3
// Show initial prompt and instructions
drawText(a.screen, 0, cursorY-1, width, style, "Enter your reply (Ctrl+J to submit, Enter for new line, Esc to cancel):")
drawText(a.screen, 0, cursorY, width, style, prompt)
a.screen.Show()
for {
ev := a.screen.PollEvent()
switch ev := ev.(type) {
case *tcell.EventKey:
switch ev.Key() {
case tcell.KeyCtrlJ:
if currentLine != "" {
lines = append(lines, currentLine)
}
return strings.Join(lines, "\n")
case tcell.KeyEscape:
return ""
case tcell.KeyEnter:
lines = append(lines, currentLine)
currentLine = ""
cursorX = len(prompt)
cursorY++
if cursorY >= height-1 {
cursorY--
a.screen.Clear()
drawText(a.screen, 0, cursorY-len(lines)-1, width, style, "Enter your reply (Ctrl+J to submit, Enter for new line, Esc to cancel):")
for i, line := range lines {
drawText(a.screen, 0, cursorY-len(lines)+i, width, style, prompt+line)
}
}
drawText(a.screen, 0, cursorY, width, style, prompt)
case tcell.KeyBackspace, tcell.KeyBackspace2:
if len(currentLine) > 0 {
currentLine = currentLine[:len(currentLine)-1]
cursorX--
a.screen.SetContent(cursorX, cursorY, ' ', nil, style)
} else if len(lines) > 0 {
currentLine = lines[len(lines)-1]
lines = lines[:len(lines)-1]
cursorY--
cursorX = len(prompt) + len(currentLine)
}
case tcell.KeyRune:
currentLine += string(ev.Rune())
a.screen.SetContent(cursorX, cursorY, ev.Rune(), nil, style)
cursorX++
}
// Redraw current line
for x := 0; x < width; x++ {
a.screen.SetContent(x, cursorY, ' ', nil, style)
}
drawText(a.screen, 0, cursorY, width, style, prompt+currentLine)
a.screen.Show()
}
}
}
func openBrowser(url string) error {
var cmd string
var args []string
switch runtime.GOOS {
case "windows":
cmd = "cmd"
args = []string{"/c", "start"}
case "darwin":
cmd = "open"
default: // "linux", "freebsd", "openbsd", "netbsd"
cmd = "xdg-open"
}
args = append(args, url)
return exec.Command(cmd, args...).Start()
}
func main() {
// Define command line flags
list := flag.String("list", "all", "Read a specific accounts list from data. By default all (all.txt, all.json)")
shortTweets := flag.Bool("short", false, "Show only short tweets (<180 characters)")
longTweets := flag.Bool("long", false, "Show only long tweets (>=180 characters)")
username := flag.String("u", "", "Show tweets only from this username")
flag.Parse()
app, err := newApp()
if err != nil {
fmt.Printf("Could not create client: %v\n", err)
os.Exit(1)
}
// Configure tweet filtering
if *shortTweets && *longTweets {
fmt.Println("Warning: Both --short and --long flags set. Showing all tweets.")
} else {
app.shortTweetsOnly = *shortTweets
app.longTweetsOnly = *longTweets
}
// Configure which accounts list to use
app.accountsList = *list
app.filterUsername = *username
if err := app.Run(); err != nil {
app.screen.Fini()
fmt.Printf("Error running client: %v\n", err)
os.Exit(1)
}
app.screen.Fini()
}

View File

@ -0,0 +1,7 @@
all:
go run main.go types.go --list all
forecasting:
go run main.go types.go --list forecasting

View File

@ -0,0 +1,40 @@
package main
import (
"time"
"net/http"
"github.com/gdamore/tcell/v2"
)
type Tweet struct {
ID string `json:"tweet_id"`
Text string `json:"text"`
CreatedAt string `json:"created_at"`
Username string `json:"username"`
}
type TimelineResponse struct {
Timeline []Tweet `json:"timeline"`
}
type Cache struct {
Tweets []Tweet `json:"tweets"`
Timestamp time.Time `json:"timestamp"`
}
type App struct {
screen tcell.Screen
tweets []Tweet
selectedIdx int
currentPage int
shortTweetsOnly bool
longTweetsOnly bool
accountsList string
filterUsername string
}
type Fetcher struct {
client *http.Client
rateLimiter chan time.Time
accountsList string
}

View File

@ -0,0 +1,13 @@
version: 1.0.{build}
clone_folder: c:\gopath\src\github.com\gdamore\encoding
environment:
GOPATH: c:\gopath
build_script:
- go version
- go env
- SET PATH=%LOCALAPPDATA%\atom\bin;%GOPATH%\bin;%PATH%
- go get -t ./...
- go build
- go install ./...
test_script:
- go test ./...

View File

@ -0,0 +1,73 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at garrett@damore.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,20 @@
## encoding
[![Linux](https://img.shields.io/github/actions/workflow/status/gdamore/encoding/linux.yml?branch=main&logoColor=grey&logo=linux&label=)](https://github.com/gdamore/encoding/actions/workflows/linux.yml)
[![Windows](https://img.shields.io/github/actions/workflow/status/gdamore/encoding/windows.yml?branch=main&logoColor=grey&logo=windows&label=)](https://github.com/gdamore/encoding/actions/workflows/windows.yml)
[![Apache License](https://img.shields.io/github/license/gdamore/encoding.svg?logoColor=silver&logo=opensourceinitiative&color=blue&label=)](https://github.com/gdamore/encoding/blob/master/LICENSE)
[![Coverage](https://img.shields.io/codecov/c/github/gdamore/encoding?logoColor=grey&logo=codecov&label=)](https://codecov.io/gh/gdamore/encoding)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/gdamore/encoding)
Package encoding provides a number of encodings that are missing from the
standard Go [encoding]("https://godoc.org/golang.org/x/text/encoding") package.
We hope that we can contribute these to the standard Go library someday. It
turns out that some of these are useful for dealing with I/O streams coming
from non-UTF friendly sources.
The UTF8 Encoder is also useful for situations where valid UTF-8 might be
carried in streams that contain non-valid UTF; in particular I use it for
helping me cope with terminals that embed escape sequences in otherwise
valid UTF-8.

View File

@ -0,0 +1,12 @@
# Security Policy
We take security very seriously in mangos, since you may be using it in
Internet-facing applications.
## Reporting a Vulnerability
To report a vulnerability, please contact us on our discord.
You may also send an email to garrett@damore.org, or info@staysail.tech.
We will keep the reporter updated on any status updates on a regular basis,
and will respond within two business days for any reported security issue.

View File

@ -0,0 +1,36 @@
// Copyright 2015 Garrett D'Amore
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"golang.org/x/text/encoding"
)
// ASCII represents the 7-bit US-ASCII scheme. It decodes directly to
// UTF-8 without change, as all ASCII values are legal UTF-8.
// Unicode values less than 128 (i.e. 7 bits) map 1:1 with ASCII.
// It encodes runes outside of that to 0x1A, the ASCII substitution character.
var ASCII encoding.Encoding
func init() {
amap := make(map[byte]rune)
for i := 128; i <= 255; i++ {
amap[byte(i)] = RuneError
}
cm := &Charmap{Map: amap}
cm.Init()
ASCII = cm
}

View File

@ -0,0 +1,195 @@
// Copyright 2024 Garrett D'Amore
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"sync"
"unicode/utf8"
"golang.org/x/text/encoding"
"golang.org/x/text/transform"
)
const (
// RuneError is an alias for the UTF-8 replacement rune, '\uFFFD'.
RuneError = '\uFFFD'
// RuneSelf is the rune below which UTF-8 and the Unicode values are
// identical. Its also the limit for ASCII.
RuneSelf = 0x80
// ASCIISub is the ASCII substitution character.
ASCIISub = '\x1a'
)
// Charmap is a structure for setting up encodings for 8-bit character sets,
// for transforming between UTF8 and that other character set. It has some
// ideas borrowed from golang.org/x/text/encoding/charmap, but it uses a
// different implementation. This implementation uses maps, and supports
// user-defined maps.
//
// We do assume that a character map has a reasonable substitution character,
// and that valid encodings are stable (exactly a 1:1 map) and stateless
// (that is there is no shift character or anything like that.) Hence this
// approach will not work for many East Asian character sets.
//
// Measurement shows little or no measurable difference in the performance of
// the two approaches. The difference was down to a couple of nsec/op, and
// no consistent pattern as to which ran faster. With the conversion to
// UTF-8 the code takes about 25 nsec/op. The conversion in the reverse
// direction takes about 100 nsec/op. (The larger cost for conversion
// from UTF-8 is most likely due to the need to convert the UTF-8 byte stream
// to a rune before conversion.
type Charmap struct {
transform.NopResetter
bytes map[rune]byte
runes [256][]byte
once sync.Once
// The map between bytes and runes. To indicate that a specific
// byte value is invalid for a charcter set, use the rune
// utf8.RuneError. Values that are absent from this map will
// be assumed to have the identity mapping -- that is the default
// is to assume ISO8859-1, where all 8-bit characters have the same
// numeric value as their Unicode runes. (Not to be confused with
// the UTF-8 values, which *will* be different for non-ASCII runes.)
//
// If no values less than RuneSelf are changed (or have non-identity
// mappings), then the character set is assumed to be an ASCII
// superset, and certain assumptions and optimizations become
// available for ASCII bytes.
Map map[byte]rune
// The ReplacementChar is the byte value to use for substitution.
// It should normally be ASCIISub for ASCII encodings. This may be
// unset (left to zero) for mappings that are strictly ASCII supersets.
// In that case ASCIISub will be assumed instead.
ReplacementChar byte
}
type cmapDecoder struct {
transform.NopResetter
runes [256][]byte
}
type cmapEncoder struct {
transform.NopResetter
bytes map[rune]byte
replace byte
}
// Init initializes internal values of a character map. This should
// be done early, to minimize the cost of allocation of transforms
// later. It is not strictly necessary however, as the allocation
// functions will arrange to call it if it has not already been done.
func (c *Charmap) Init() {
c.once.Do(c.initialize)
}
func (c *Charmap) initialize() {
c.bytes = make(map[rune]byte)
ascii := true
for i := 0; i < 256; i++ {
r, ok := c.Map[byte(i)]
if !ok {
r = rune(i)
}
if r < 128 && r != rune(i) {
ascii = false
}
if r != RuneError {
c.bytes[r] = byte(i)
}
utf := make([]byte, utf8.RuneLen(r))
utf8.EncodeRune(utf, r)
c.runes[i] = utf
}
if ascii && c.ReplacementChar == '\x00' {
c.ReplacementChar = ASCIISub
}
}
// NewDecoder returns a Decoder the converts from the 8-bit
// character set to UTF-8. Unknown mappings, if any, are mapped
// to '\uFFFD'.
func (c *Charmap) NewDecoder() *encoding.Decoder {
c.Init()
return &encoding.Decoder{Transformer: &cmapDecoder{runes: c.runes}}
}
// NewEncoder returns a Transformer that converts from UTF8 to the
// 8-bit character set. Unknown mappings are mapped to 0x1A.
func (c *Charmap) NewEncoder() *encoding.Encoder {
c.Init()
return &encoding.Encoder{
Transformer: &cmapEncoder{
bytes: c.bytes,
replace: c.ReplacementChar,
},
}
}
func (d *cmapDecoder) Transform(dst, src []byte, atEOF bool) (int, int, error) {
var e error
var ndst, nsrc int
for _, c := range src {
b := d.runes[c]
l := len(b)
if ndst+l > len(dst) {
e = transform.ErrShortDst
break
}
for i := 0; i < l; i++ {
dst[ndst] = b[i]
ndst++
}
nsrc++
}
return ndst, nsrc, e
}
func (d *cmapEncoder) Transform(dst, src []byte, atEOF bool) (int, int, error) {
var e error
var ndst, nsrc int
for nsrc < len(src) {
if ndst >= len(dst) {
e = transform.ErrShortDst
break
}
r, sz := utf8.DecodeRune(src[nsrc:])
if r == utf8.RuneError && sz == 1 {
// If its inconclusive due to insufficient data in
// in the source, report it
if atEOF && !utf8.FullRune(src[nsrc:]) {
e = transform.ErrShortSrc
break
}
}
if c, ok := d.bytes[r]; ok {
dst[ndst] = c
} else {
dst[ndst] = d.replace
}
nsrc += sz
ndst++
}
return ndst, nsrc, e
}

View File

@ -0,0 +1,17 @@
// Copyright 2015 Garrett D'Amore
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package encoding provides a few of the encoding structures that are
// missing from the Go x/text/encoding tree.
package encoding

View File

@ -0,0 +1,273 @@
// Copyright 2015 Garrett D'Amore
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"golang.org/x/text/encoding"
)
// EBCDIC represents the 8-bit EBCDIC scheme, found in some mainframe
// environments. If you don't know what this is, consider yourself lucky.
var EBCDIC encoding.Encoding
func init() {
cm := &Charmap{
ReplacementChar: '\x3f',
Map: map[byte]rune{
// 0x00-0x03 match
0x04: RuneError,
0x05: '\t',
0x06: RuneError,
0x07: '\x7f',
0x08: RuneError,
0x09: RuneError,
0x0a: RuneError,
// 0x0b-0x13 match
0x14: RuneError,
0x15: '\x85', // Not in any ISO code
0x16: '\x08',
0x17: RuneError,
// 0x18-0x19 match
0x1a: RuneError,
0x1b: RuneError,
// 0x1c-0x1f match
0x20: RuneError,
0x21: RuneError,
0x22: RuneError,
0x23: RuneError,
0x24: RuneError,
0x25: '\n',
0x26: '\x17',
0x27: '\x1b',
0x28: RuneError,
0x29: RuneError,
0x2a: RuneError,
0x2b: RuneError,
0x2c: RuneError,
0x2d: '\x05',
0x2e: '\x06',
0x2f: '\x07',
0x30: RuneError,
0x31: RuneError,
0x32: '\x16',
0x33: RuneError,
0x34: RuneError,
0x35: RuneError,
0x36: RuneError,
0x37: '\x04',
0x38: RuneError,
0x39: RuneError,
0x3a: RuneError,
0x3b: RuneError,
0x3c: '\x14',
0x3d: '\x15',
0x3e: RuneError,
0x3f: '\x1a', // also replacement char
0x40: ' ',
0x41: '\xa0',
0x42: RuneError,
0x43: RuneError,
0x44: RuneError,
0x45: RuneError,
0x46: RuneError,
0x47: RuneError,
0x48: RuneError,
0x49: RuneError,
0x4a: RuneError,
0x4b: '.',
0x4c: '<',
0x4d: '(',
0x4e: '+',
0x4f: '|',
0x50: '&',
0x51: RuneError,
0x52: RuneError,
0x53: RuneError,
0x54: RuneError,
0x55: RuneError,
0x56: RuneError,
0x57: RuneError,
0x58: RuneError,
0x59: RuneError,
0x5a: '!',
0x5b: '$',
0x5c: '*',
0x5d: ')',
0x5e: ';',
0x5f: '¬',
0x60: '-',
0x61: '/',
0x62: RuneError,
0x63: RuneError,
0x64: RuneError,
0x65: RuneError,
0x66: RuneError,
0x67: RuneError,
0x68: RuneError,
0x69: RuneError,
0x6a: '¦',
0x6b: ',',
0x6c: '%',
0x6d: '_',
0x6e: '>',
0x6f: '?',
0x70: RuneError,
0x71: RuneError,
0x72: RuneError,
0x73: RuneError,
0x74: RuneError,
0x75: RuneError,
0x76: RuneError,
0x77: RuneError,
0x78: RuneError,
0x79: '`',
0x7a: ':',
0x7b: '#',
0x7c: '@',
0x7d: '\'',
0x7e: '=',
0x7f: '"',
0x80: RuneError,
0x81: 'a',
0x82: 'b',
0x83: 'c',
0x84: 'd',
0x85: 'e',
0x86: 'f',
0x87: 'g',
0x88: 'h',
0x89: 'i',
0x8a: RuneError,
0x8b: RuneError,
0x8c: RuneError,
0x8d: RuneError,
0x8e: RuneError,
0x8f: '±',
0x90: RuneError,
0x91: 'j',
0x92: 'k',
0x93: 'l',
0x94: 'm',
0x95: 'n',
0x96: 'o',
0x97: 'p',
0x98: 'q',
0x99: 'r',
0x9a: RuneError,
0x9b: RuneError,
0x9c: RuneError,
0x9d: RuneError,
0x9e: RuneError,
0x9f: RuneError,
0xa0: RuneError,
0xa1: '~',
0xa2: 's',
0xa3: 't',
0xa4: 'u',
0xa5: 'v',
0xa6: 'w',
0xa7: 'x',
0xa8: 'y',
0xa9: 'z',
0xaa: RuneError,
0xab: RuneError,
0xac: RuneError,
0xad: RuneError,
0xae: RuneError,
0xaf: RuneError,
0xb0: '^',
0xb1: RuneError,
0xb2: RuneError,
0xb3: RuneError,
0xb4: RuneError,
0xb5: RuneError,
0xb6: RuneError,
0xb7: RuneError,
0xb8: RuneError,
0xb9: RuneError,
0xba: '[',
0xbb: ']',
0xbc: RuneError,
0xbd: RuneError,
0xbe: RuneError,
0xbf: RuneError,
0xc0: '{',
0xc1: 'A',
0xc2: 'B',
0xc3: 'C',
0xc4: 'D',
0xc5: 'E',
0xc6: 'F',
0xc7: 'G',
0xc8: 'H',
0xc9: 'I',
0xca: '\xad', // NB: soft hyphen
0xcb: RuneError,
0xcc: RuneError,
0xcd: RuneError,
0xce: RuneError,
0xcf: RuneError,
0xd0: '}',
0xd1: 'J',
0xd2: 'K',
0xd3: 'L',
0xd4: 'M',
0xd5: 'N',
0xd6: 'O',
0xd7: 'P',
0xd8: 'Q',
0xd9: 'R',
0xda: RuneError,
0xdb: RuneError,
0xdc: RuneError,
0xdd: RuneError,
0xde: RuneError,
0xdf: RuneError,
0xe0: '\\',
0xe1: '\u2007', // Non-breaking space
0xe2: 'S',
0xe3: 'T',
0xe4: 'U',
0xe5: 'V',
0xe6: 'W',
0xe7: 'X',
0xe8: 'Y',
0xe9: 'Z',
0xea: RuneError,
0xeb: RuneError,
0xec: RuneError,
0xed: RuneError,
0xee: RuneError,
0xef: RuneError,
0xf0: '0',
0xf1: '1',
0xf2: '2',
0xf3: '3',
0xf4: '4',
0xf5: '5',
0xf6: '6',
0xf7: '7',
0xf8: '8',
0xf9: '9',
0xfa: RuneError,
0xfb: RuneError,
0xfc: RuneError,
0xfd: RuneError,
0xfe: RuneError,
0xff: RuneError,
}}
cm.Init()
EBCDIC = cm
}

View File

@ -0,0 +1,33 @@
// Copyright 2015 Garrett D'Amore
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"golang.org/x/text/encoding"
)
// ISO8859_1 represents the 8-bit ISO8859-1 scheme. It decodes directly to
// UTF-8 without change, as all ISO8859-1 values are legal UTF-8.
// Unicode values less than 256 (i.e. 8 bits) map 1:1 with 8859-1.
// It encodes runes outside of that to 0x1A, the ASCII substitution character.
var ISO8859_1 encoding.Encoding
func init() {
cm := &Charmap{}
cm.Init()
// 8859-1 is the 8-bit identity map for Unicode.
ISO8859_1 = cm
}

View File

@ -0,0 +1,35 @@
// Copyright 2015 Garrett D'Amore
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"golang.org/x/text/encoding"
)
// ISO8859_9 represents the 8-bit ISO8859-9 scheme.
var ISO8859_9 encoding.Encoding
func init() {
cm := &Charmap{Map: map[byte]rune{
0xD0: 'Ğ',
0xDD: 'İ',
0xDE: 'Ş',
0xF0: 'ğ',
0xFD: 'ı',
0xFE: 'ş',
}}
cm.Init()
ISO8859_9 = cm
}

View File

@ -0,0 +1,35 @@
// Copyright 2015 Garrett D'Amore
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package encoding
import (
"golang.org/x/text/encoding"
)
type validUtf8 struct{}
// UTF8 is an encoding for UTF-8. All it does is verify that the UTF-8
// in is valid. The main reason for its existence is that it will detect
// and report ErrSrcShort or ErrDstShort, whereas the Nop encoding just
// passes every byte, blithely.
var UTF8 encoding.Encoding = validUtf8{}
func (validUtf8) NewDecoder() *encoding.Decoder {
return &encoding.Decoder{Transformer: encoding.UTF8Validator}
}
func (validUtf8) NewEncoder() *encoding.Encoder {
return &encoding.Encoder{Transformer: encoding.UTF8Validator}
}

View File

@ -0,0 +1,13 @@
version: 1.0.{build}
clone_folder: c:\gopath\src\github.com\gdamore\tcell
environment:
GOPATH: c:\gopath
build_script:
- go version
- go env
- SET PATH=%LOCALAPPDATA%\atom\bin;%GOPATH%\bin;%PATH%
- go get -t ./...
- go build
- go install ./...
test_script:
- go test ./...

View File

@ -0,0 +1 @@
coverage.txt

View File

@ -0,0 +1,18 @@
language: go
go:
- 1.15.x
- master
arch:
- amd64
- ppc64le
before_install:
- go get -t -v ./...
script:
- go test -race -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@ -0,0 +1,4 @@
Garrett D'Amore <garrett@damore.org>
Zachary Yedidia <zyedidia@gmail.com>
Junegunn Choi <junegunn.c@gmail.com>
Staysail Systems, Inc. <info@staysail.tech>

View File

@ -0,0 +1,82 @@
## Breaking Changes in _Tcell_ v2
A number of changes were made to _Tcell_ for version two, and some of these are breaking.
### Import Path
The import path for tcell has changed to `github.com/gdamore/tcell/v2` to reflect a new major version.
### Style Is Not Numeric
The type `Style` has changed to a structure, to allow us to add additional data such as flags for color setting,
more attribute bits, and so forth.
Applications that relied on this being a number will need to be updated to use the accessor methods.
### Mouse Event Changes
The middle mouse button was reported as button 2 on Linux, but as button 3 on Windows,
and the right mouse button was reported the reverse way.
_Tcell_ now always reports the right mouse button as button 2, and the middle button as button 3.
To help make this clearer, new symbols `ButtonPrimary`, `ButtonSecondary`, and
`ButtonMiddle` are provided.
(Note that which button is right vs. left may be impacted by user preferences.
Usually the left button will be considered the Primary, and the right will be the Secondary.)
Applications may need to adjust their handling of mouse buttons 2 and 3 accordingly.
### Terminals Removed
A number of terminals have been removed.
These are mostly ancient definitions unlikely to be used by anyone, such as `adm3a`.
### High Number Function Keys
Historically terminfo reported function keys with modifiers set as a different
function key altogether. For example, Shift-F1 was reported as F13 on XTerm.
_Tcell_ now prefers to report these using the base key (such as F1) with modifiers added.
This works on XTerm and VTE based emulators, but some emulators may not support this.
The new behavior more closely aligns with behavior on Windows platforms.
## New Features in _Tcell_ v2
These features are not breaking, but are introduced in version 2.
### Improved Modifier Support
For terminals that appear to behave like the venerable XTerm, _tcell_
automatically adds modifier reporting for ALT, CTRL, SHIFT, and META keys
when the terminal reports them.
### Better Support for Palettes (Themes)
When using a color by its name or palette entry, _Tcell_ now tries to
use that palette entry as is; this should avoid some inconsistency and respect
terminal themes correctly.
When true fidelity to RGB values is needed, the new `TrueColor()` API can be used
to create a direct color, which bypasses the palette altogether.
### Automatic TrueColor Detection
For some terminals, if the `Tc` or `RGB` properties are present in terminfo,
_Tcell_ will automatically assume the terminal supports 24-bit color.
### ColorReset
A new color value, `ColorReset` can be used on the foreground or background
to reset the color the default used by the terminal.
### tmux Support
_Tcell_ now has improved support for tmux, when the `$TERM` variable is set to "tmux".
### Strikethrough Support
_Tcell_ has support for strikethrough when the terminal supports it, using the new `StrikeThrough()` API.
### Bracketed Paste Support
_Tcell_ provides the long requested capability to discriminate paste event by using the
bracketed-paste capability present in some terminals. This is automatically available on
terminals that support XTerm style mouse handling, but applications must opt-in to this
by using the new `EnablePaste()` function. A new `EventPaste` type of event will be
delivered when starting and finishing a paste operation.

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,61 @@
# WASM for _Tcell_
You can build _Tcell_ project into a webpage by compiling it slightly differently. This will result in a _Tcell_ project you can embed into another html page, or use as a standalone page.
## Building your project
WASM needs special build flags in order to work. You can build it by executing
```sh
GOOS=js GOARCH=wasm go build -o yourfile.wasm
```
## Additional files
You also need 5 other files in the same directory as the wasm. Four (`tcell.html`, `tcell.js`, `termstyle.css`, and `beep.wav`) are provided in the `webfiles` directory. The last one, `wasm_exec.js`, can be copied from GOROOT into the current directory by executing
```sh
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./
```
In `tcell.js`, you also need to change the constant
```js
const wasmFilePath = "yourfile.wasm"
```
to the file you outputted to when building.
## Displaying your project
### Standalone
You can see the project (with an white background around the terminal) by serving the directory. You can do this using any framework, including another golang project:
```golang
// server.go
package main
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe(":8080",
http.FileServer(http.Dir("/path/to/dir/to/serve")),
))
}
```
To see the webpage with this example, you can type in `localhost:8080/tcell.html` into your browser while `server.go` is running.
### Embedding
It is recommended to use an iframe if you want to embed the app into a webpage:
```html
<iframe src="tcell.html" title="Tcell app"></iframe>
```
## Other considerations
### Accessing files
`io.Open(filename)` and other related functions for reading file systems do not work; use `http.Get(filename)` instead.

View File

@ -0,0 +1,290 @@
<img src="logos/tcell.png" style="float: right"/>
# Tcell
_Tcell_ is a _Go_ package that provides a cell based view for text terminals, like _XTerm_.
It was inspired by _termbox_, but includes many additional improvements.
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
[![Linux](https://img.shields.io/github/actions/workflow/status/gdamore/tcell/linux.yml?branch=main&logoColor=grey&logo=linux&label=)](https://github.com/gdamore/tcell/actions/workflows/linux.yml)
[![Windows](https://img.shields.io/github/actions/workflow/status/gdamore/tcell/windows.yml?branch=main&logoColor=grey&logo=windows&label=)](https://github.com/gdamore/tcell/actions/workflows/windows.yml)
[![Apache License](https://img.shields.io/github/license/gdamore/tcell.svg?logoColor=silver&logo=opensourceinitiative&color=blue&label=)](https://github.com/gdamore/tcell/blob/master/LICENSE)
[![Docs](https://img.shields.io/badge/godoc-reference-blue.svg?label=&logo=go)](https://pkg.go.dev/github.com/gdamore/tcell/v2)
[![Discord](https://img.shields.io/discord/639503822733180969?label=&logo=discord)](https://discord.gg/urTTxDN)
[![Coverage](https://img.shields.io/codecov/c/github/gdamore/tcell?logoColor=grey&logo=codecov&label=)](https://codecov.io/gh/gdamore/tcell)
[![Go Report Card](https://goreportcard.com/badge/github.com/gdamore/tcell/v2)](https://goreportcard.com/report/github.com/gdamore/tcell/v2)
Please see [here](UKRAINE.md) for an important message for the people of Russia.
NOTE: This is version 2 of _Tcell_. There are breaking changes relative to version 1.
Version 1.x remains available using the import `github.com/gdamore/tcell`.
## Tutorial
A brief, and still somewhat rough, [tutorial](TUTORIAL.md) is available.
## Examples
- [proxima5](https://github.com/gdamore/proxima5) - space shooter ([video](https://youtu.be/jNxKTCmY_bQ))
- [govisor](https://github.com/gdamore/govisor) - service management UI ([screenshot](http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png))
- mouse demo - included mouse test ([screenshot](http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png))
- [gomatrix](https://github.com/gdamore/gomatrix) - converted from Termbox
- [micro](https://github.com/zyedidia/micro/) - lightweight text editor with syntax-highlighting and themes
- [godu](https://github.com/viktomas/godu) - utility to discover large files/folders
- [tview](https://github.com/rivo/tview/) - rich interactive widgets
- [cview](https://code.rocketnine.space/tslocum/cview) - user interface toolkit (fork of _tview_)
- [awesome gocui](https://github.com/awesome-gocui/gocui) - Go Console User Interface
- [gomandelbrot](https://github.com/rgm3/gomandelbrot) - Mandelbrot!
- [WTF](https://github.com/senorprogrammer/wtf) - personal information dashboard
- [browsh](https://github.com/browsh-org/browsh) - modern web browser ([video](https://www.youtube.com/watch?v=HZq86XfBoRo))
- [go-life](https://github.com/sachaos/go-life) - Conway's Game of Life
- [gowid](https://github.com/gcla/gowid) - compositional widgets for terminal UIs, inspired by _urwid_
- [termshark](https://termshark.io) - interface for _tshark_, inspired by Wireshark, built on _gowid_
- [go-tetris](https://github.com/MichaelS11/go-tetris) - Go Tetris with AI option
- [fzf](https://github.com/junegunn/fzf) - command-line fuzzy finder
- [ascii-fluid](https://github.com/esimov/ascii-fluid) - fluid simulation controlled by webcam
- [cbind](https://code.rocketnine.space/tslocum/cbind) - key event encoding, decoding and handling
- [tpong](https://github.com/spinzed/tpong) - old-school Pong
- [aerc](https://git.sr.ht/~sircmpwn/aerc) - email client
- [tblogs](https://github.com/ezeoleaf/tblogs) - development blogs reader
- [spinc](https://github.com/lallassu/spinc) - _irssi_ inspired chat application for Cisco Spark/WebEx
- [gorss](https://github.com/lallassu/gorss) - RSS/Atom feed reader
- [memoryalike](https://github.com/Bios-Marcel/memoryalike) - memorization game
- [lf](https://github.com/gokcehan/lf) - file manager
- [goful](https://github.com/anmitsu/goful) - CUI file manager
- [gokeybr](https://github.com/bunyk/gokeybr) - deliberately practice your typing
- [gonano](https://github.com/jbaramidze/gonano) - editor, mimics _nano_
- [uchess](https://github.com/tmountain/uchess) - UCI chess client
- [min](https://github.com/a-h/min) - Gemini browser
- [ov](https://github.com/noborus/ov) - file pager
- [tmux-wormhole](https://github.com/gcla/tmux-wormhole) - _tmux_ plugin to transfer files
- [gruid-tcell](https://github.com/anaseto/gruid-tcell) - driver for the grid based UI and game framework
- [aretext](https://github.com/aretext/aretext) - minimalist text editor with _vim_ key bindings
- [sync](https://github.com/kyprifog/sync) - GitHub repo synchronization tool
- [statusbar](https://github.com/kyprifog/statusbar) - statusbar motivation tool for tracking periodic tasks/goals
- [todo](https://github.com/kyprifog/todo) - simple todo app
- [gosnakego](https://github.com/liweiyi88/gosnakego) - a snake game
- [gbb](https://github.com/sdemingo/gbb) - A classical bulletin board app for tildes or public unix servers
- [lil](https://github.com/andrievsky/lil) - A simple and flexible interface for any service by implementing only list and get operations
- [hero.go](https://github.com/barisbll/hero.go) - 2d monster shooter ([video](https://user-images.githubusercontent.com/40062673/277157369-240d7606-b471-4aa1-8c54-4379a513122b.mp4))
- [go-tetris](https://github.com/aaronriekenberg/go-tetris) - simple tetris game for native terminal and WASM using github actions+pages
- [oddshub](https://github.com/dos-2/oddshub) - A TUI designed for analyzing sports betting odds
## Pure Go Terminfo Database
_Tcell_ includes a full parser and expander for terminfo capability strings,
so that it can avoid hard coding escape strings for formatting. It also favors
portability, and includes support for all POSIX systems.
The database is also flexible & extensible, and can be modified by either running
a program to build the entire database, or an entry for just a single terminal.
## More Portable
_Tcell_ is portable to a wide variety of systems, and is pure Go, without
any need for CGO.
_Tcell_ is believed to work with mainstream systems officially supported by golang.
## No Async IO
_Tcell_ is able to operate without requiring `SIGIO` signals (unlike _termbox_),
or asynchronous I/O, and can instead use standard Go file objects and Go routines.
This means it should be safe, especially for
use with programs that use exec, or otherwise need to manipulate the tty streams.
This model is also much closer to idiomatic Go, leading to fewer surprises.
## Rich Unicode & non-Unicode support
_Tcell_ includes enhanced support for Unicode, including wide characters and
combining characters, provided your terminal can support them.
Note that
Windows terminals generally don't support the full Unicode repertoire.
It will also convert to and from Unicode locales, so that the program
can work with UTF-8 internally, and get reasonable output in other locales.
_Tcell_ tries hard to convert to native characters on both input and output.
On output _Tcell_ even makes use of the alternate character set to facilitate
drawing certain characters.
## More Function Keys
_Tcell_ also has richer support for a larger number of special keys that some
terminals can send.
## Better Color Handling
_Tcell_ will respect your terminal's color space as specified within your terminfo entries.
For example attempts to emit color sequences on VT100 terminals
won't result in unintended consequences.
In legacy Windows mode, _Tcell_ supports 16 colors, bold, dim, and reverse,
instead of just termbox's 8 colors with reverse. (Note that there is some
conflation with bold/dim and colors.)
Modern Windows 10 can benefit from much richer colors however.
_Tcell_ maps 16 colors down to 8, for terminals that need it.
(The upper 8 colors are just brighter versions of the lower 8.)
## Better Mouse Support
_Tcell_ supports enhanced mouse tracking mode, so your application can receive
regular mouse motion events, and wheel events, if your terminal supports it.
(Note: The Windows 10 Terminal application suffers from a flaw in this regard,
and does not support mouse interaction. The stock Windows 10 console host
fired up with cmd.exe or PowerShell works fine however.)
## _Termbox_ Compatibility
A compatibility layer for _termbox_ is provided in the `compat` directory.
To use it, try importing `github.com/gdamore/tcell/termbox` instead.
Most _termbox-go_ programs will probably work without further modification.
## Working With Unicode
Internally _Tcell_ uses UTF-8, just like Go.
However, _Tcell_ understands how to
convert to and from other character sets, using the capabilities of
the `golang.org/x/text/encoding` packages.
Your application must supply
them, as the full set of the most common ones bloats the program by about 2 MB.
If you're lazy, and want them all anyway, see the `encoding` sub-directory.
## Wide & Combining Characters
The `SetContent()` API takes a primary rune, and an optional list of combining runes.
If any of the runes is a wide (East Asian) rune occupying two cells,
then the library will skip output from the following cell. Care must be
taken in the application to avoid explicitly attempting to set content in the
next cell, otherwise the results are undefined. (Normally the wide character
is displayed, and the other character is not; do not depend on that behavior.)
Older terminal applications (especially on systems like Windows 8) lack support
for advanced Unicode, and thus may not fare well.
## Colors
_Tcell_ assumes the ANSI/XTerm color model, including the 256 color map that
XTerm uses when it supports 256 colors. The terminfo guidance will be
honored, with respect to the number of colors supported. Also, only
terminals which expose ANSI style `setaf` and `setab` will support color;
if you have a color terminal that only has `setf` and `setb`, please submit
a ticket.
## 24-bit Color
_Tcell_ _supports 24-bit color!_ (That is, if your terminal can support it.)
NOTE: Technically the approach of using 24-bit RGB values for color is more
accurately described as "direct color", but most people use the term "true color".
We follow the (inaccurate) common convention.
There are a few ways you can enable (or disable) true color.
- For many terminals, we can detect it automatically if your terminal
includes the `RGB` or `Tc` capabilities (or rather it did when the database
was updated.)
- You can force this one by setting the `COLORTERM` environment variable to
`24-bit`, `truecolor` or `24bit`. This is the same method used
by most other terminal applications that support 24-bit color.
- If you set your `TERM` environment variable to a value with the suffix `-truecolor`
then 24-bit color compatible with XTerm and ECMA-48 will be assumed.
(This feature is deprecated.
It is recommended to use one of other methods listed above.)
- You can disable 24-bit color by setting `TCELL_TRUECOLOR=disable` in your
environment.
When using TrueColor, programs will display the colors that the programmer
intended, overriding any "`themes`" you may have set in your terminal
emulator. (For some cases, accurate color fidelity is more important
than respecting themes. For other cases, such as typical text apps that
only use a few colors, its more desirable to respect the themes that
the user has established.)
## Performance
Reasonable attempts have been made to minimize sending data to terminals,
avoiding repeated sequences or drawing the same cell on refresh updates.
## Terminfo
(Not relevant for Windows users.)
The Terminfo implementation operates with a built-in database.
This should satisfy most users. However, it can also (on systems
with ncurses installed), dynamically parse the output from `infocmp`
for terminals it does not already know about.
See the `terminfo/` directory for more information about generating
new entries for the built-in database.
_Tcell_ requires that the terminal support the `cup` mode of cursor addressing.
Ancient terminals without the ability to position the cursor directly
are not supported.
This is unlikely to be a problem; such terminals have not been mass-produced
since the early 1970s.
## Mouse Support
Mouse support is detected via the `kmous` terminfo variable, however,
enablement/disablement and decoding mouse events is done using hard coded
sequences based on the XTerm X11 model. All popular
terminals with mouse tracking support this model. (Full terminfo support
is not possible as terminfo sequences are not defined.)
On Windows, the mouse works normally.
Mouse wheel buttons on various terminals are known to work, but the support
in terminal emulators, as well as support for various buttons and
live mouse tracking, varies widely.
Modern _xterm_, macOS _Terminal_, and _iTerm_ all work well.
## Bracketed Paste
Terminals that appear to support the XTerm mouse model also can support
bracketed paste, for applications that opt-in. See `EnablePaste()` for details.
## Testability
There is a `SimulationScreen`, that can be used to simulate a real screen
for automated testing. The supplied tests do this. The simulation contains
event delivery, screen resizing support, and capabilities to inject events
and examine "`physical`" screen contents.
## Platforms
### POSIX (Linux, FreeBSD, macOS, Solaris, etc.)
Everything works using pure Go on mainstream platforms. Some more esoteric
platforms (e.g., AIX) may need to be added. Pull requests are welcome!
### Windows
Windows console mode applications are supported.
Modern console applications like ConEmu and the Windows 10 terminal,
support all the good features (resize, mouse tracking, etc.)
### WASM
WASM is supported, but needs additional setup detailed in [README-wasm](README-wasm.md).
### Plan9 and others
These platforms won't work, but compilation stubs are supplied
for folks that want to include parts of this in software for those
platforms. The Simulation screen works, but as _Tcell_ doesn't know how to
allocate a real screen object on those platforms, `NewScreen()` will fail.
If anyone has wisdom about how to improve support for these,
please let me know. PRs are especially welcome.
### Commercial Support
_Tcell_ is absolutely free, but if you want to obtain commercial, professional support, there are options.
- [TideLift](https://tidelift.com/) subscriptions include support for _Tcell_, as well as many other open source packages.
- [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis.

View File

@ -0,0 +1,15 @@
# SECURITY
It's somewhat unlikely that tcell is in a security sensitive path,
but we do take security seriously.
## Vulnerabilityu Response
If you report a vulnerability, we will respond within 2 business days.
## Report a Vulnerability
If you wish to report a vulnerability found in tcell, simply send a message
to garrett@damore.org. You may also reach us on our discord channel -
https://discord.gg/urTTxDN - a private message to `gdamore` on that channel
may be submitted instead of mail.

View File

@ -0,0 +1,313 @@
# _Tcell_ Tutorial
_Tcell_ provides a low-level, portable API for building terminal-based programs.
A [terminal emulator](https://en.wikipedia.org/wiki/Terminal_emulator)
(or a real terminal such as a DEC VT-220) is used to interact with such a program.
_Tcell_'s interface is fairly low-level.
While it provides a reasonably portable way of dealing with all the usual terminal
features, it may be easier to utilize a higher level framework.
A number of such frameworks are listed on the _Tcell_ main [README](README.md).
This tutorial provides the details of _Tcell_, and is appropriate for developers
wishing to create their own application frameworks or needing more direct access
to the terminal capabilities.
## Resize events
Applications receive an event of type `EventResize` when they are first initialized and each time the terminal is resized.
The new size is available as `Size`.
```go
switch ev := ev.(type) {
case *tcell.EventResize:
w, h := ev.Size()
logMessage(fmt.Sprintf("Resized to %dx%d", w, h))
}
```
## Key events
When a key is pressed, applications receive an event of type `EventKey`.
This event describes the modifier keys pressed (if any) and the pressed key or rune.
When a rune key is pressed, an event with its `Key` set to `KeyRune` is dispatched.
When a non-rune key is pressed, it is available as the `Key` of the event.
```go
switch ev := ev.(type) {
case *tcell.EventKey:
mod, key, ch := ev.Mod(), ev.Key(), ev.Rune()
logMessage(fmt.Sprintf("EventKey Modifiers: %d Key: %d Rune: %d", mod, key, ch))
}
```
### Key event restrictions
Terminal-based programs have less visibility into keyboard activity than graphical applications.
When a key is pressed and held, additional key press events are sent by the terminal emulator.
The rate of these repeated events depends on the emulator's configuration.
Key release events are not available.
It is not possible to distinguish runes typed while holding shift and runes typed using caps lock.
Capital letters are reported without the Shift modifier.
## Mouse events
Applications receive an event of type `EventMouse` when the mouse moves, or a mouse button is pressed or released.
Mouse events are only delivered if
`EnableMouse` has been called.
The mouse buttons being pressed (if any) are available as `Buttons`, and the position of the mouse is available as `Position`.
```go
switch ev := ev.(type) {
case *tcell.EventMouse:
mod := ev.Modifiers()
btns := ev.Buttons()
x, y := ev.Position()
logMessage(fmt.Sprintf("EventMouse Modifiers: %d Buttons: %d Position: %d,%d", mod, btns, x, y))
}
```
### Mouse buttons
Identifier | Alias | Description
-----------|-----------------|-----------
Button1 | ButtonPrimary | Left button
Button2 | ButtonSecondary | Right button
Button3 | ButtonMiddle | Middle button
Button4 | | Side button (thumb/next)
Button5 | | Side button (thumb/prev)
WheelUp | | Scroll wheel up
WheelDown | | Scroll wheel down
WheelLeft | | Horizontal wheel left
WheelRight | | Horizontal wheel right
## Usage
To create a _Tcell_ application, first initialize a screen to hold it.
```go
s, err := tcell.NewScreen()
if err != nil {
log.Fatalf("%+v", err)
}
if err := s.Init(); err != nil {
log.Fatalf("%+v", err)
}
// Set default text style
defStyle := tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset)
s.SetStyle(defStyle)
// Clear screen
s.Clear()
```
Text may be drawn on the screen using `SetContent`.
```go
s.SetContent(0, 0, 'H', nil, defStyle)
s.SetContent(1, 0, 'i', nil, defStyle)
s.SetContent(2, 0, '!', nil, defStyle)
```
To draw text more easily, define a render function.
```go
func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {
row := y1
col := x1
for _, r := range []rune(text) {
s.SetContent(col, row, r, nil, style)
col++
if col >= x2 {
row++
col = x1
}
if row > y2 {
break
}
}
}
```
Lastly, define an event loop to handle user input and update application state.
```go
quit := func() {
s.Fini()
os.Exit(0)
}
for {
// Update screen
s.Show()
// Poll event
ev := s.PollEvent()
// Process event
switch ev := ev.(type) {
case *tcell.EventResize:
s.Sync()
case *tcell.EventKey:
if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
quit()
}
}
}
```
## Demo application
The following demonstrates how to initialize a screen, draw text/graphics and handle user input.
```go
package main
import (
"fmt"
"log"
"github.com/gdamore/tcell/v2"
)
func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {
row := y1
col := x1
for _, r := range []rune(text) {
s.SetContent(col, row, r, nil, style)
col++
if col >= x2 {
row++
col = x1
}
if row > y2 {
break
}
}
}
func drawBox(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {
if y2 < y1 {
y1, y2 = y2, y1
}
if x2 < x1 {
x1, x2 = x2, x1
}
// Fill background
for row := y1; row <= y2; row++ {
for col := x1; col <= x2; col++ {
s.SetContent(col, row, ' ', nil, style)
}
}
// Draw borders
for col := x1; col <= x2; col++ {
s.SetContent(col, y1, tcell.RuneHLine, nil, style)
s.SetContent(col, y2, tcell.RuneHLine, nil, style)
}
for row := y1 + 1; row < y2; row++ {
s.SetContent(x1, row, tcell.RuneVLine, nil, style)
s.SetContent(x2, row, tcell.RuneVLine, nil, style)
}
// Only draw corners if necessary
if y1 != y2 && x1 != x2 {
s.SetContent(x1, y1, tcell.RuneULCorner, nil, style)
s.SetContent(x2, y1, tcell.RuneURCorner, nil, style)
s.SetContent(x1, y2, tcell.RuneLLCorner, nil, style)
s.SetContent(x2, y2, tcell.RuneLRCorner, nil, style)
}
drawText(s, x1+1, y1+1, x2-1, y2-1, style, text)
}
func main() {
defStyle := tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset)
boxStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorPurple)
// Initialize screen
s, err := tcell.NewScreen()
if err != nil {
log.Fatalf("%+v", err)
}
if err := s.Init(); err != nil {
log.Fatalf("%+v", err)
}
s.SetStyle(defStyle)
s.EnableMouse()
s.EnablePaste()
s.Clear()
// Draw initial boxes
drawBox(s, 1, 1, 42, 7, boxStyle, "Click and drag to draw a box")
drawBox(s, 5, 9, 32, 14, boxStyle, "Press C to reset")
quit := func() {
// You have to catch panics in a defer, clean up, and
// re-raise them - otherwise your application can
// die without leaving any diagnostic trace.
maybePanic := recover()
s.Fini()
if maybePanic != nil {
panic(maybePanic)
}
}
defer quit()
// Here's how to get the screen size when you need it.
// xmax, ymax := s.Size()
// Here's an example of how to inject a keystroke where it will
// be picked up by the next PollEvent call. Note that the
// queue is LIFO, it has a limited length, and PostEvent() can
// return an error.
// s.PostEvent(tcell.NewEventKey(tcell.KeyRune, rune('a'), 0))
// Event loop
ox, oy := -1, -1
for {
// Update screen
s.Show()
// Poll event
ev := s.PollEvent()
// Process event
switch ev := ev.(type) {
case *tcell.EventResize:
s.Sync()
case *tcell.EventKey:
if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
return
} else if ev.Key() == tcell.KeyCtrlL {
s.Sync()
} else if ev.Rune() == 'C' || ev.Rune() == 'c' {
s.Clear()
}
case *tcell.EventMouse:
x, y := ev.Position()
switch ev.Buttons() {
case tcell.Button1, tcell.Button2:
if ox < 0 {
ox, oy = x, y // record location when click started
}
case tcell.ButtonNone:
if ox >= 0 {
label := fmt.Sprintf("%d,%d to %d,%d", ox, oy, x, y)
drawBox(s, ox, oy, x, y, boxStyle, label)
ox, oy = -1, -1
}
}
}
}
}
```

View File

@ -0,0 +1,77 @@
# Ukraine, Russia, and a World Tragedy
## A message to those inside Russia
### Written March 4, 2022.
It is with a very heavy heart that I write this. I am normally opposed to the use of open source
projects to communicate political positions or advocate for things outside the immediate relevancy
to that project.
However, the events occurring in Ukraine, and specifically the unprecedented invasion of Ukraine by
Russian forces operating under orders from Russian President Vladimir Putin compel me to speak out.
Those who know me, know that I have family, friends, and colleagues in Russia, and Ukraine both. My closest friends
have historically been Russian friends my wife's hometown of Chelyabinsk. I myself have in the past
frequently traveled to Russia, and indeed operated a software development firm with offices in St. Petersburg.
I had a special kinship with Russia and its people.
I say "had", because I fear that the actions of Putin, and the massive disinformation campaign that his regime
has waged inside Russia, mean that it's likely that I won't see those friends again. At present, I'm not sure
my wife will see her own mother again. We no longer feel it's safe for either of us to return Russia given
actions taken by the regime to crack down on those who express disagreement.
Russian citizens are being led to believe it is acting purely defensively, and that only legitimate military
targets are being targeted, and that all the information we have received in the West are fakes.
I am confident that nothing could be further from the truth.
This has caused many in Russia, including people whom I respect and believe to be smarter than this, to
stand by Putin, and endorse his actions. The claim is that the entirety of NATO is operating at the behest
of the USA, and that the entirety of Europe was poised to attack Russia. While this is clearly absurd to those
of us with any understanding of western politics, Russian citizens are being fed this lie, and believing it.
If you're reading this from inside Russia -- YOU are the person that I hope this message reaches. Your
government is LYING to you. Of course, all governments lie all the time. But consider this. Almost the
entire world has condemned the invasion of Ukraine as criminal, and has applied sanctions. Even countries
which have poor relations with the US sanctioning Russia, as well as nations which historically have remained
neutral. (Famously neutral -- even during World War II, Switzerland has acted to apply sanctions in
concert with the rest of the world.)
Ask yourself, why does Putin fear a free press so much, if what he says is true? Why the crack-downs on
children expressing only a desire for peace with Ukraine? Why would the entire world unified against him,
if Putin was in the right? Why would the only countries that stood with Russia against
the UN resolution to condemn these acts as crimes be Belarus, North Korea, and Syria? Even countries normally
allied to Russia could not bring themselves to do more than abstain from the vote to condemn it.
To be clear, I do not claim that the actions taken by the West or by the Ukrainian government were completely
blameless. On the contrary, I understand that Western media is biased, and the truth is rarely exactly
as reported. I believe that there is a kernel of truth in the claims of fascists and ultra-nationalist
militias operating in Ukraine and specifically Donbas. However, I am also equally certain that Putin's
response is out of proportion, and that concerns about such militias are principally just a pretext to justify
an invasion.
Europe is at war, unlike we've seen in my lifetime. The world is more divided, and closer to nuclear holocaust
than it has been since the Cold War. And that is 100% the fault of Putin.
While Putin remains in power, there cannot really be any way for Russian international relations to return
to normal. Putin has set your country on a path to return to the Cold War, likely because he fancies himself
to be a new Stalin. However, unlike the Soviet Union, the Russian economy does not have the wherewithal to
stand on its own, and the invasion of Ukraine has fully ensured that Russia will not find any friends anywhere
else in Europe, and probably few places in Asia.
The *only* paths forward for Russia are either a Russia without Putin (and those who would support his agenda),
or a complete breakdown of Russian prosperity, likely followed by the increasing international conflict that will
be the natural escalation from a country that is isolated and impoverished. Those of us observing from the West are
gravely concerned, because we cannot see any end to this madness that does not result in nuclear conflict,
unless from within.
In the meantime, the worst prices will be paid for by innocents in Ukraine, and by young Russian mean
forced to carry out the orders of Putin's corrupt regime.
And *that* is why I write this -- to appeal to those within Russia to open your eyes, and think with
your minds. It is right and proper to be proud of your country and its rich heritage. But it is also
right and proper to look for ways to save it from the ruinous path that its current leadership has set it upon,
and to recognize when that leadership is no longer acting in interest of the country or its people.
- Garrett D'Amore, March 4, 2022

View File

@ -0,0 +1,34 @@
// Copyright 2024 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
// AttrMask represents a mask of text attributes, apart from color.
// Note that support for attributes may vary widely across terminals.
type AttrMask uint
// Attributes are not colors, but affect the display of text. They can
// be combined, in some cases, but not others. (E.g. you can have Dim Italic,
// but only CurlyUnderline cannot be mixed with DottedUnderline.)
const (
AttrBold AttrMask = 1 << iota
AttrBlink
AttrReverse
AttrUnderline // Deprecated: Use UnderlineStyle
AttrDim
AttrItalic
AttrStrikeThrough
AttrInvalid AttrMask = 1 << 31 // Mark the style or attributes invalid
AttrNone AttrMask = 0 // Just normal text.
)

View File

@ -0,0 +1,249 @@
// Copyright 2024 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"os"
"reflect"
runewidth "github.com/mattn/go-runewidth"
)
type cell struct {
currMain rune
currComb []rune
currStyle Style
lastMain rune
lastStyle Style
lastComb []rune
width int
lock bool
}
// CellBuffer represents a two-dimensional array of character cells.
// This is primarily intended for use by Screen implementors; it
// contains much of the common code they need. To create one, just
// declare a variable of its type; no explicit initialization is necessary.
//
// CellBuffer is not thread safe.
type CellBuffer struct {
w int
h int
cells []cell
}
// SetContent sets the contents (primary rune, combining runes,
// and style) for a cell at a given location. If the background or
// foreground of the style is set to ColorNone, then the respective
// color is left un changed.
func (cb *CellBuffer) SetContent(x int, y int,
mainc rune, combc []rune, style Style,
) {
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x]
// Wide characters: we want to mark the "wide" cells
// dirty as well as the base cell, to make sure we consider
// both cells as dirty together. We only need to do this
// if we're changing content
if (c.width > 0) && (mainc != c.currMain || len(combc) != len(c.currComb) || (len(combc) > 0 && !reflect.DeepEqual(combc, c.currComb))) {
for i := 0; i < c.width; i++ {
cb.SetDirty(x+i, y, true)
}
}
c.currComb = append([]rune{}, combc...)
if c.currMain != mainc {
c.width = runewidth.RuneWidth(mainc)
}
c.currMain = mainc
if style.fg == ColorNone {
style.fg = c.currStyle.fg
}
if style.bg == ColorNone {
style.bg = c.currStyle.bg
}
c.currStyle = style
}
}
// GetContent returns the contents of a character cell, including the
// primary rune, any combining character runes (which will usually be
// nil), the style, and the display width in cells. (The width can be
// either 1, normally, or 2 for East Asian full-width characters.)
func (cb *CellBuffer) GetContent(x, y int) (rune, []rune, Style, int) {
var mainc rune
var combc []rune
var style Style
var width int
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x]
mainc, combc, style = c.currMain, c.currComb, c.currStyle
if width = c.width; width == 0 || mainc < ' ' {
width = 1
mainc = ' '
}
}
return mainc, combc, style, width
}
// Size returns the (width, height) in cells of the buffer.
func (cb *CellBuffer) Size() (int, int) {
return cb.w, cb.h
}
// Invalidate marks all characters within the buffer as dirty.
func (cb *CellBuffer) Invalidate() {
for i := range cb.cells {
cb.cells[i].lastMain = rune(0)
}
}
// Dirty checks if a character at the given location needs to be
// refreshed on the physical display. This returns true if the cell
// content is different since the last time it was marked clean.
func (cb *CellBuffer) Dirty(x, y int) bool {
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x]
if c.lock {
return false
}
if c.lastMain == rune(0) {
return true
}
if c.lastMain != c.currMain {
return true
}
if c.lastStyle != c.currStyle {
return true
}
if len(c.lastComb) != len(c.currComb) {
return true
}
for i := range c.lastComb {
if c.lastComb[i] != c.currComb[i] {
return true
}
}
}
return false
}
// SetDirty is normally used to indicate that a cell has
// been displayed (in which case dirty is false), or to manually
// force a cell to be marked dirty.
func (cb *CellBuffer) SetDirty(x, y int, dirty bool) {
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x]
if dirty {
c.lastMain = rune(0)
} else {
if c.currMain == rune(0) {
c.currMain = ' '
}
c.lastMain = c.currMain
c.lastComb = c.currComb
c.lastStyle = c.currStyle
}
}
}
// LockCell locks a cell from being drawn, effectively marking it "clean" until
// the lock is removed. This can be used to prevent tcell from drawing a given
// cell, even if the underlying content has changed. For example, when drawing a
// sixel graphic directly to a TTY screen an implementer must lock the region
// underneath the graphic to prevent tcell from drawing on top of the graphic.
func (cb *CellBuffer) LockCell(x, y int) {
if x < 0 || y < 0 {
return
}
if x >= cb.w || y >= cb.h {
return
}
c := &cb.cells[(y*cb.w)+x]
c.lock = true
}
// UnlockCell removes a lock from the cell and marks it as dirty
func (cb *CellBuffer) UnlockCell(x, y int) {
if x < 0 || y < 0 {
return
}
if x >= cb.w || y >= cb.h {
return
}
c := &cb.cells[(y*cb.w)+x]
c.lock = false
cb.SetDirty(x, y, true)
}
// Resize is used to resize the cells array, with different dimensions,
// while preserving the original contents. The cells will be invalidated
// so that they can be redrawn.
func (cb *CellBuffer) Resize(w, h int) {
if cb.h == h && cb.w == w {
return
}
newc := make([]cell, w*h)
for y := 0; y < h && y < cb.h; y++ {
for x := 0; x < w && x < cb.w; x++ {
oc := &cb.cells[(y*cb.w)+x]
nc := &newc[(y*w)+x]
nc.currMain = oc.currMain
nc.currComb = oc.currComb
nc.currStyle = oc.currStyle
nc.width = oc.width
nc.lastMain = rune(0)
}
}
cb.cells = newc
cb.h = h
cb.w = w
}
// Fill fills the entire cell buffer array with the specified character
// and style. Normally choose ' ' to clear the screen. This API doesn't
// support combining characters, or characters with a width larger than one.
// If either the foreground or background are ColorNone, then the respective
// color is unchanged.
func (cb *CellBuffer) Fill(r rune, style Style) {
for i := range cb.cells {
c := &cb.cells[i]
c.currMain = r
c.currComb = nil
cs := style
if cs.fg == ColorNone {
cs.fg = c.currStyle.fg
}
if cs.bg == ColorNone {
cs.bg = c.currStyle.bg
}
c.currStyle = cs
c.width = 1
}
}
var runeConfig *runewidth.Condition
func init() {
// The defaults for the runewidth package are poorly chosen for terminal
// applications. We however will honor the setting in the environment if
// it is set.
if os.Getenv("RUNEWIDTH_EASTASIAN") == "" {
runewidth.DefaultCondition.EastAsianWidth = false
}
}

View File

@ -0,0 +1,22 @@
//go:build plan9 || nacl
// +build plan9 nacl
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
func getCharset() string {
return ""
}

View File

@ -0,0 +1,50 @@
//go:build !windows && !nacl && !plan9
// +build !windows,!nacl,!plan9
// Copyright 2016 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"os"
"strings"
)
func getCharset() string {
// Determine the character set. This can help us later.
// Per POSIX, we search for LC_ALL first, then LC_CTYPE, and
// finally LANG. First one set wins.
locale := ""
if locale = os.Getenv("LC_ALL"); locale == "" {
if locale = os.Getenv("LC_CTYPE"); locale == "" {
locale = os.Getenv("LANG")
}
}
if locale == "POSIX" || locale == "C" {
return "US-ASCII"
}
if i := strings.IndexRune(locale, '@'); i >= 0 {
locale = locale[:i]
}
if i := strings.IndexRune(locale, '.'); i >= 0 {
locale = locale[i+1:]
} else {
// Default assumption, and on Linux we can see LC_ALL
// without a character set, which we assume implies UTF-8.
return "UTF-8"
}
// XXX: add support for aliases
return locale
}

View File

@ -0,0 +1,22 @@
//go:build windows
// +build windows
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
func getCharset() string {
return "UTF-16"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
// Copyright 2016 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"math"
"github.com/lucasb-eyer/go-colorful"
)
// FindColor attempts to find a given color, or the best match possible for it,
// from the palette given. This is an expensive operation, so results should
// be cached by the caller.
func FindColor(c Color, palette []Color) Color {
match := ColorDefault
dist := float64(0)
r, g, b := c.RGB()
c1 := colorful.Color{
R: float64(r) / 255.0,
G: float64(g) / 255.0,
B: float64(b) / 255.0,
}
for _, d := range palette {
r, g, b = d.RGB()
c2 := colorful.Color{
R: float64(r) / 255.0,
G: float64(g) / 255.0,
B: float64(b) / 255.0,
}
// CIE94 is more accurate, but really really expensive.
nd := c1.DistanceCIE76(c2)
if math.IsNaN(nd) {
nd = math.Inf(1)
}
if match == ColorDefault || nd < dist {
match = d
dist = nd
}
}
return match
}

View File

@ -0,0 +1,24 @@
//go:build !windows
// +build !windows
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
// NewConsoleScreen returns a console based screen. This platform
// doesn't have support for any, so it returns nil and a suitable error.
func NewConsoleScreen() (Screen, error) {
return nil, ErrNoScreen
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
// Copyright 2018 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package tcell provides a lower-level, portable API for building
// programs that interact with terminals or consoles. It works with
// both common (and many uncommon!) terminals or terminal emulators,
// and Windows console implementations.
//
// It provides support for up to 256 colors, text attributes, and box drawing
// elements. A database of terminals built from a real terminfo database
// is provided, along with code to generate new database entries.
//
// Tcell offers very rich support for mice, dependent upon the terminal
// of course. (Windows, XTerm, and iTerm 2 are known to work very well.)
//
// If the environment is not Unicode by default, such as an ISO8859 based
// locale or GB18030, Tcell can convert input and output, so that your
// terminal can operate in whatever locale is most convenient, while the
// application program can just assume "everything is UTF-8". Reasonable
// defaults are used for updating characters to something suitable for
// display. Unicode box drawing characters will be converted to use the
// alternate character set of your terminal, if native conversions are
// not available. If no ACS is available, then some ASCII fallbacks will
// be used.
//
// Note that support for non-UTF-8 locales (other than C) must be enabled
// by the application using RegisterEncoding() -- we don't have them all
// enabled by default to avoid bloating the application unnecessarily.
// (These days UTF-8 is good enough for almost everyone, and nobody should
// be using legacy locales anymore.) Also, actual glyphs for various code
// point will only be displayed if your terminal or emulator (or the font
// the emulator is using) supports them.
//
// A rich set of key codes is supported, with support for up to 65 function
// keys, and various other special keys.
package tcell

View File

@ -0,0 +1,140 @@
// Copyright 2022 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"strings"
"sync"
"golang.org/x/text/encoding"
gencoding "github.com/gdamore/encoding"
)
var encodings map[string]encoding.Encoding
var encodingLk sync.Mutex
var encodingFallback EncodingFallback = EncodingFallbackFail
// RegisterEncoding may be called by the application to register an encoding.
// The presence of additional encodings will facilitate application usage with
// terminal environments where the I/O subsystem does not support Unicode.
//
// Windows systems use Unicode natively, and do not need any of the encoding
// subsystem when using Windows Console screens.
//
// Please see the Go documentation for golang.org/x/text/encoding -- most of
// the common ones exist already as stock variables. For example, ISO8859-15
// can be registered using the following code:
//
// import "golang.org/x/text/encoding/charmap"
//
// ...
// RegisterEncoding("ISO8859-15", charmap.ISO8859_15)
//
// Aliases can be registered as well, for example "8859-15" could be an alias
// for "ISO8859-15".
//
// For POSIX systems, this package will check the environment variables
// LC_ALL, LC_CTYPE, and LANG (in that order) to determine the character set.
// These are expected to have the following pattern:
//
// $language[.$codeset[@$variant]
//
// We extract only the $codeset part, which will usually be something like
// UTF-8 or ISO8859-15 or KOI8-R. Note that if the locale is either "POSIX"
// or "C", then we assume US-ASCII (the POSIX 'portable character set'
// and assume all other characters are somehow invalid.)
//
// Modern POSIX systems and terminal emulators may use UTF-8, and for those
// systems, this API is also unnecessary. For example, Darwin (MacOS X) and
// modern Linux running modern xterm generally will out of the box without
// any of this. Use of UTF-8 is recommended when possible, as it saves
// quite a lot processing overhead.
//
// Note that some encodings are quite large (for example GB18030 which is a
// superset of Unicode) and so the application size can be expected to
// increase quite a bit as each encoding is added.
// The East Asian encodings have been seen to add 100-200K per encoding to the
// size of the resulting binary.
func RegisterEncoding(charset string, enc encoding.Encoding) {
encodingLk.Lock()
charset = strings.ToLower(charset)
encodings[charset] = enc
encodingLk.Unlock()
}
// EncodingFallback describes how the system behaves when the locale
// requires a character set that we do not support. The system always
// supports UTF-8 and US-ASCII. On Windows consoles, UTF-16LE is also
// supported automatically. Other character sets must be added using the
// RegisterEncoding API. (A large group of nearly all of them can be
// added using the RegisterAll function in the encoding sub package.)
type EncodingFallback int
const (
// EncodingFallbackFail behavior causes GetEncoding to fail
// when it cannot find an encoding.
EncodingFallbackFail = iota
// EncodingFallbackASCII behavior causes GetEncoding to fall back
// to a 7-bit ASCII encoding, if no other encoding can be found.
EncodingFallbackASCII
// EncodingFallbackUTF8 behavior causes GetEncoding to assume
// UTF8 can pass unmodified upon failure. Note that this behavior
// is not recommended, unless you are sure your terminal can cope
// with real UTF8 sequences.
EncodingFallbackUTF8
)
// SetEncodingFallback changes the behavior of GetEncoding when a suitable
// encoding is not found. The default is EncodingFallbackFail, which
// causes GetEncoding to simply return nil.
func SetEncodingFallback(fb EncodingFallback) {
encodingLk.Lock()
encodingFallback = fb
encodingLk.Unlock()
}
// GetEncoding is used by Screen implementors who want to locate an encoding
// for the given character set name. Note that this will return nil for
// either the Unicode (UTF-8) or ASCII encodings, since we don't use
// encodings for them but instead have our own native methods.
func GetEncoding(charset string) encoding.Encoding {
charset = strings.ToLower(charset)
encodingLk.Lock()
defer encodingLk.Unlock()
if enc, ok := encodings[charset]; ok {
return enc
}
switch encodingFallback {
case EncodingFallbackASCII:
return gencoding.ASCII
case EncodingFallbackUTF8:
return encoding.Nop
}
return nil
}
func init() {
// We always support UTF-8 and ASCII.
encodings = make(map[string]encoding.Encoding)
encodings["utf-8"] = gencoding.UTF8
encodings["utf8"] = gencoding.UTF8
encodings["us-ascii"] = gencoding.ASCII
encodings["ascii"] = gencoding.ASCII
encodings["iso646"] = gencoding.ASCII
}

View File

@ -0,0 +1,73 @@
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"errors"
"time"
"github.com/gdamore/tcell/v2/terminfo"
)
var (
// ErrTermNotFound indicates that a suitable terminal entry could
// not be found. This can result from either not having TERM set,
// or from the TERM failing to support certain minimal functionality,
// in particular absolute cursor addressability (the cup capability)
// is required. For example, legacy "adm3" lacks this capability,
// whereas the slightly newer "adm3a" supports it. This failure
// occurs most often with "dumb".
ErrTermNotFound = terminfo.ErrTermNotFound
// ErrNoScreen indicates that no suitable screen could be found.
// This may result from attempting to run on a platform where there
// is no support for either termios or console I/O (such as nacl),
// or from running in an environment where there is no access to
// a suitable console/terminal device. (For example, running on
// without a controlling TTY or with no /dev/tty on POSIX platforms.)
ErrNoScreen = errors.New("no suitable screen available")
// ErrNoCharset indicates that the locale environment the
// program is not supported by the program, because no suitable
// encoding was found for it. This problem never occurs if
// the environment is UTF-8 or UTF-16.
ErrNoCharset = errors.New("character set not supported")
// ErrEventQFull indicates that the event queue is full, and
// cannot accept more events.
ErrEventQFull = errors.New("event queue full")
)
// An EventError is an event representing some sort of error, and carries
// an error payload.
type EventError struct {
t time.Time
err error
}
// When returns the time when the event was created.
func (ev *EventError) When() time.Time {
return ev.t
}
// Error implements the error.
func (ev *EventError) Error() string {
return ev.err.Error()
}
// NewEventError creates an ErrorEvent with the given error payload.
func NewEventError(err error) *EventError {
return &EventError{t: time.Now(), err: err}
}

View File

@ -0,0 +1,53 @@
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"time"
)
// Event is a generic interface used for passing around Events.
// Concrete types follow.
type Event interface {
// When reports the time when the event was generated.
When() time.Time
}
// EventTime is a simple base event class, suitable for easy reuse.
// It can be used to deliver actual timer events as well.
type EventTime struct {
when time.Time
}
// When returns the time stamp when the event occurred.
func (e *EventTime) When() time.Time {
return e.when
}
// SetEventTime sets the time of occurrence for the event.
func (e *EventTime) SetEventTime(t time.Time) {
e.when = t
}
// SetEventNow sets the time of occurrence for the event to the current time.
func (e *EventTime) SetEventNow() {
e.SetEventTime(time.Now())
}
// EventHandler is anything that handles events. If the handler has
// consumed the event, it should return true. False otherwise.
type EventHandler interface {
HandleEvent(Event) bool
}

View File

@ -0,0 +1,28 @@
// Copyright 2023 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
// EventFocus is a focus event. It is sent when the terminal window (or tab)
// gets or loses focus.
type EventFocus struct {
*EventTime
// True if the window received focus, false if it lost focus
Focused bool
}
func NewEventFocus(focused bool) *EventFocus {
return &EventFocus{Focused: focused}
}

View File

@ -0,0 +1,41 @@
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"time"
)
// EventInterrupt is a generic wakeup event. Its can be used to
// to request a redraw. It can carry an arbitrary payload, as well.
type EventInterrupt struct {
t time.Time
v interface{}
}
// When returns the time when this event was created.
func (ev *EventInterrupt) When() time.Time {
return ev.t
}
// Data is used to obtain the opaque event payload.
func (ev *EventInterrupt) Data() interface{} {
return ev.v
}
// NewEventInterrupt creates an EventInterrupt with the given payload.
func NewEventInterrupt(data interface{}) *EventInterrupt {
return &EventInterrupt{t: time.Now(), v: data}
}

View File

@ -0,0 +1,470 @@
// Copyright 2016 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"fmt"
"strings"
"time"
)
// EventKey represents a key press. Usually this is a key press followed
// by a key release, but since terminal programs don't have a way to report
// key release events, we usually get just one event. If a key is held down
// then the terminal may synthesize repeated key presses at some predefined
// rate. We have no control over that, nor visibility into it.
//
// In some cases, we can have a modifier key, such as ModAlt, that can be
// generated with a key press. (This usually is represented by having the
// high bit set, or in some cases, by sending an ESC prior to the rune.)
//
// If the value of Key() is KeyRune, then the actual key value will be
// available with the Rune() method. This will be the case for most keys.
// In most situations, the modifiers will not be set. For example, if the
// rune is 'A', this will be reported without the ModShift bit set, since
// really can't tell if the Shift key was pressed (it might have been CAPSLOCK,
// or a terminal that only can send capitals, or keyboard with separate
// capital letters from lower case letters).
//
// Generally, terminal applications have far less visibility into keyboard
// activity than graphical applications. Hence, they should avoid depending
// overly much on availability of modifiers, or the availability of any
// specific keys.
type EventKey struct {
t time.Time
mod ModMask
key Key
ch rune
}
// When returns the time when this Event was created, which should closely
// match the time when the key was pressed.
func (ev *EventKey) When() time.Time {
return ev.t
}
// Rune returns the rune corresponding to the key press, if it makes sense.
// The result is only defined if the value of Key() is KeyRune.
func (ev *EventKey) Rune() rune {
return ev.ch
}
// Key returns a virtual key code. We use this to identify specific key
// codes, such as KeyEnter, etc. Most control and function keys are reported
// with unique Key values. Normal alphanumeric and punctuation keys will
// generally return KeyRune here; the specific key can be further decoded
// using the Rune() function.
func (ev *EventKey) Key() Key {
return ev.key
}
// Modifiers returns the modifiers that were present with the key press. Note
// that not all platforms and terminals support this equally well, and some
// cases we will not not know for sure. Hence, applications should avoid
// using this in most circumstances.
func (ev *EventKey) Modifiers() ModMask {
return ev.mod
}
// KeyNames holds the written names of special keys. Useful to echo back a key
// name, or to look up a key from a string value.
var KeyNames = map[Key]string{
KeyEnter: "Enter",
KeyBackspace: "Backspace",
KeyTab: "Tab",
KeyBacktab: "Backtab",
KeyEsc: "Esc",
KeyBackspace2: "Backspace2",
KeyDelete: "Delete",
KeyInsert: "Insert",
KeyUp: "Up",
KeyDown: "Down",
KeyLeft: "Left",
KeyRight: "Right",
KeyHome: "Home",
KeyEnd: "End",
KeyUpLeft: "UpLeft",
KeyUpRight: "UpRight",
KeyDownLeft: "DownLeft",
KeyDownRight: "DownRight",
KeyCenter: "Center",
KeyPgDn: "PgDn",
KeyPgUp: "PgUp",
KeyClear: "Clear",
KeyExit: "Exit",
KeyCancel: "Cancel",
KeyPause: "Pause",
KeyPrint: "Print",
KeyF1: "F1",
KeyF2: "F2",
KeyF3: "F3",
KeyF4: "F4",
KeyF5: "F5",
KeyF6: "F6",
KeyF7: "F7",
KeyF8: "F8",
KeyF9: "F9",
KeyF10: "F10",
KeyF11: "F11",
KeyF12: "F12",
KeyF13: "F13",
KeyF14: "F14",
KeyF15: "F15",
KeyF16: "F16",
KeyF17: "F17",
KeyF18: "F18",
KeyF19: "F19",
KeyF20: "F20",
KeyF21: "F21",
KeyF22: "F22",
KeyF23: "F23",
KeyF24: "F24",
KeyF25: "F25",
KeyF26: "F26",
KeyF27: "F27",
KeyF28: "F28",
KeyF29: "F29",
KeyF30: "F30",
KeyF31: "F31",
KeyF32: "F32",
KeyF33: "F33",
KeyF34: "F34",
KeyF35: "F35",
KeyF36: "F36",
KeyF37: "F37",
KeyF38: "F38",
KeyF39: "F39",
KeyF40: "F40",
KeyF41: "F41",
KeyF42: "F42",
KeyF43: "F43",
KeyF44: "F44",
KeyF45: "F45",
KeyF46: "F46",
KeyF47: "F47",
KeyF48: "F48",
KeyF49: "F49",
KeyF50: "F50",
KeyF51: "F51",
KeyF52: "F52",
KeyF53: "F53",
KeyF54: "F54",
KeyF55: "F55",
KeyF56: "F56",
KeyF57: "F57",
KeyF58: "F58",
KeyF59: "F59",
KeyF60: "F60",
KeyF61: "F61",
KeyF62: "F62",
KeyF63: "F63",
KeyF64: "F64",
KeyCtrlA: "Ctrl-A",
KeyCtrlB: "Ctrl-B",
KeyCtrlC: "Ctrl-C",
KeyCtrlD: "Ctrl-D",
KeyCtrlE: "Ctrl-E",
KeyCtrlF: "Ctrl-F",
KeyCtrlG: "Ctrl-G",
KeyCtrlJ: "Ctrl-J",
KeyCtrlK: "Ctrl-K",
KeyCtrlL: "Ctrl-L",
KeyCtrlN: "Ctrl-N",
KeyCtrlO: "Ctrl-O",
KeyCtrlP: "Ctrl-P",
KeyCtrlQ: "Ctrl-Q",
KeyCtrlR: "Ctrl-R",
KeyCtrlS: "Ctrl-S",
KeyCtrlT: "Ctrl-T",
KeyCtrlU: "Ctrl-U",
KeyCtrlV: "Ctrl-V",
KeyCtrlW: "Ctrl-W",
KeyCtrlX: "Ctrl-X",
KeyCtrlY: "Ctrl-Y",
KeyCtrlZ: "Ctrl-Z",
KeyCtrlSpace: "Ctrl-Space",
KeyCtrlUnderscore: "Ctrl-_",
KeyCtrlRightSq: "Ctrl-]",
KeyCtrlBackslash: "Ctrl-\\",
KeyCtrlCarat: "Ctrl-^",
}
// Name returns a printable value or the key stroke. This can be used
// when printing the event, for example.
func (ev *EventKey) Name() string {
s := ""
m := []string{}
if ev.mod&ModShift != 0 {
m = append(m, "Shift")
}
if ev.mod&ModAlt != 0 {
m = append(m, "Alt")
}
if ev.mod&ModMeta != 0 {
m = append(m, "Meta")
}
if ev.mod&ModCtrl != 0 {
m = append(m, "Ctrl")
}
ok := false
if s, ok = KeyNames[ev.key]; !ok {
if ev.key == KeyRune {
s = "Rune[" + string(ev.ch) + "]"
} else {
s = fmt.Sprintf("Key[%d,%d]", ev.key, int(ev.ch))
}
}
if len(m) != 0 {
if ev.mod&ModCtrl != 0 && strings.HasPrefix(s, "Ctrl-") {
s = s[5:]
}
return fmt.Sprintf("%s+%s", strings.Join(m, "+"), s)
}
return s
}
// NewEventKey attempts to create a suitable event. It parses the various
// ASCII control sequences if KeyRune is passed for Key, but if the caller
// has more precise information it should set that specifically. Callers
// that aren't sure about modifier state (most) should just pass ModNone.
func NewEventKey(k Key, ch rune, mod ModMask) *EventKey {
if k == KeyRune && (ch < ' ' || ch == 0x7f) {
// Turn specials into proper key codes. This is for
// control characters and the DEL.
k = Key(ch)
if mod == ModNone && ch < ' ' {
switch Key(ch) {
case KeyBackspace, KeyTab, KeyEsc, KeyEnter:
// these keys are directly typeable without CTRL
default:
// most likely entered with a CTRL keypress
mod = ModCtrl
}
}
}
return &EventKey{t: time.Now(), key: k, ch: ch, mod: mod}
}
// ModMask is a mask of modifier keys. Note that it will not always be
// possible to report modifier keys.
type ModMask int16
// These are the modifiers keys that can be sent either with a key press,
// or a mouse event. Note that as of now, due to the confusion associated
// with Meta, and the lack of support for it on many/most platforms, the
// current implementations never use it. Instead, they use ModAlt, even for
// events that could possibly have been distinguished from ModAlt.
const (
ModShift ModMask = 1 << iota
ModCtrl
ModAlt
ModMeta
ModNone ModMask = 0
)
// Key is a generic value for representing keys, and especially special
// keys (function keys, cursor movement keys, etc.) For normal keys, like
// ASCII letters, we use KeyRune, and then expect the application to
// inspect the Rune() member of the EventKey.
type Key int16
// This is the list of named keys. KeyRune is special however, in that it is
// a place holder key indicating that a printable character was sent. The
// actual value of the rune will be transported in the Rune of the associated
// EventKey.
const (
KeyRune Key = iota + 256
KeyUp
KeyDown
KeyRight
KeyLeft
KeyUpLeft
KeyUpRight
KeyDownLeft
KeyDownRight
KeyCenter
KeyPgUp
KeyPgDn
KeyHome
KeyEnd
KeyInsert
KeyDelete
KeyHelp
KeyExit
KeyClear
KeyCancel
KeyPrint
KeyPause
KeyBacktab
KeyF1
KeyF2
KeyF3
KeyF4
KeyF5
KeyF6
KeyF7
KeyF8
KeyF9
KeyF10
KeyF11
KeyF12
KeyF13
KeyF14
KeyF15
KeyF16
KeyF17
KeyF18
KeyF19
KeyF20
KeyF21
KeyF22
KeyF23
KeyF24
KeyF25
KeyF26
KeyF27
KeyF28
KeyF29
KeyF30
KeyF31
KeyF32
KeyF33
KeyF34
KeyF35
KeyF36
KeyF37
KeyF38
KeyF39
KeyF40
KeyF41
KeyF42
KeyF43
KeyF44
KeyF45
KeyF46
KeyF47
KeyF48
KeyF49
KeyF50
KeyF51
KeyF52
KeyF53
KeyF54
KeyF55
KeyF56
KeyF57
KeyF58
KeyF59
KeyF60
KeyF61
KeyF62
KeyF63
KeyF64
)
const (
// These key codes are used internally, and will never appear to applications.
keyPasteStart Key = iota + 16384
keyPasteEnd
)
// These are the control keys. Note that they overlap with other keys,
// perhaps. For example, KeyCtrlH is the same as KeyBackspace.
const (
KeyCtrlSpace Key = iota
KeyCtrlA
KeyCtrlB
KeyCtrlC
KeyCtrlD
KeyCtrlE
KeyCtrlF
KeyCtrlG
KeyCtrlH
KeyCtrlI
KeyCtrlJ
KeyCtrlK
KeyCtrlL
KeyCtrlM
KeyCtrlN
KeyCtrlO
KeyCtrlP
KeyCtrlQ
KeyCtrlR
KeyCtrlS
KeyCtrlT
KeyCtrlU
KeyCtrlV
KeyCtrlW
KeyCtrlX
KeyCtrlY
KeyCtrlZ
KeyCtrlLeftSq // Escape
KeyCtrlBackslash
KeyCtrlRightSq
KeyCtrlCarat
KeyCtrlUnderscore
)
// Special values - these are fixed in an attempt to make it more likely
// that aliases will encode the same way.
// These are the defined ASCII values for key codes. They generally match
// with KeyCtrl values.
const (
KeyNUL Key = iota
KeySOH
KeySTX
KeyETX
KeyEOT
KeyENQ
KeyACK
KeyBEL
KeyBS
KeyTAB
KeyLF
KeyVT
KeyFF
KeyCR
KeySO
KeySI
KeyDLE
KeyDC1
KeyDC2
KeyDC3
KeyDC4
KeyNAK
KeySYN
KeyETB
KeyCAN
KeyEM
KeySUB
KeyESC
KeyFS
KeyGS
KeyRS
KeyUS
KeyDEL Key = 0x7F
)
// These keys are aliases for other names.
const (
KeyBackspace = KeyBS
KeyTab = KeyTAB
KeyEsc = KeyESC
KeyEscape = KeyESC
KeyEnter = KeyCR
KeyBackspace2 = KeyDEL
)

View File

@ -0,0 +1,103 @@
// Copyright 2020 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"time"
)
// EventMouse is a mouse event. It is sent on either mouse up or mouse down
// events. It is also sent on mouse motion events - if the terminal supports
// it. We make every effort to ensure that mouse release events are delivered.
// Hence, click drag can be identified by a motion event with the mouse down,
// without any intervening button release. On some terminals only the initiating
// press and terminating release event will be delivered.
//
// Mouse wheel events, when reported, may appear on their own as individual
// impulses; that is, there will normally not be a release event delivered
// for mouse wheel movements.
//
// Most terminals cannot report the state of more than one button at a time --
// and some cannot report motion events unless a button is pressed.
//
// Applications can inspect the time between events to resolve double or
// triple clicks.
type EventMouse struct {
t time.Time
btn ButtonMask
mod ModMask
x int
y int
}
// When returns the time when this EventMouse was created.
func (ev *EventMouse) When() time.Time {
return ev.t
}
// Buttons returns the list of buttons that were pressed or wheel motions.
func (ev *EventMouse) Buttons() ButtonMask {
return ev.btn
}
// Modifiers returns a list of keyboard modifiers that were pressed
// with the mouse button(s).
func (ev *EventMouse) Modifiers() ModMask {
return ev.mod
}
// Position returns the mouse position in character cells. The origin
// 0, 0 is at the upper left corner.
func (ev *EventMouse) Position() (int, int) {
return ev.x, ev.y
}
// NewEventMouse is used to create a new mouse event. Applications
// shouldn't need to use this; its mostly for screen implementors.
func NewEventMouse(x, y int, btn ButtonMask, mod ModMask) *EventMouse {
return &EventMouse{t: time.Now(), x: x, y: y, btn: btn, mod: mod}
}
// ButtonMask is a mask of mouse buttons and wheel events. Mouse button presses
// are normally delivered as both press and release events. Mouse wheel events
// are normally just single impulse events. Windows supports up to eight
// separate buttons plus all four wheel directions, but XTerm can only support
// mouse buttons 1-3 and wheel up/down. Its not unheard of for terminals
// to support only one or two buttons (think Macs). Old terminals, and true
// emulations (such as vt100) won't support mice at all, of course.
type ButtonMask int16
// These are the actual button values. Note that tcell version 1.x reversed buttons
// two and three on *nix based terminals. We use button 1 as the primary, and
// button 2 as the secondary, and button 3 (which is often missing) as the middle.
const (
Button1 ButtonMask = 1 << iota // Usually the left (primary) mouse button.
Button2 // Usually the right (secondary) mouse button.
Button3 // Usually the middle mouse button.
Button4 // Often a side button (thumb/next).
Button5 // Often a side button (thumb/prev).
Button6
Button7
Button8
WheelUp // Wheel motion up/away from user.
WheelDown // Wheel motion down/towards user.
WheelLeft // Wheel motion to left.
WheelRight // Wheel motion to right.
ButtonNone ButtonMask = 0 // No button or wheel events.
ButtonPrimary = Button1
ButtonSecondary = Button2
ButtonMiddle = Button3
)

View File

@ -0,0 +1,43 @@
// Copyright 2021 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
// +build darwin dragonfly freebsd netbsd openbsd
package tcell
import (
"syscall"
"golang.org/x/sys/unix"
)
// BSD systems use TIOC style ioctls.
// tcSetBufParams is used by the tty driver on UNIX systems to configure the
// buffering parameters (minimum character count and minimum wait time in msec.)
// This also waits for output to drain first.
func tcSetBufParams(fd int, vMin uint8, vTime uint8) error {
_ = syscall.SetNonblock(fd, true)
tio, err := unix.IoctlGetTermios(fd, unix.TIOCGETA)
if err != nil {
return err
}
tio.Cc[unix.VMIN] = vMin
tio.Cc[unix.VTIME] = vTime
if err = unix.IoctlSetTermios(fd, unix.TIOCSETAW, tio); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,41 @@
// Copyright 2021 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build linux || aix || zos || solaris
// +build linux aix zos solaris
package tcell
import (
"syscall"
"golang.org/x/sys/unix"
)
// tcSetBufParams is used by the tty driver on UNIX systems to configure the
// buffering parameters (minimum character count and minimum wait time in msec.)
// This also waits for output to drain first.
func tcSetBufParams(fd int, vMin uint8, vTime uint8) error {
_ = syscall.SetNonblock(fd, true)
tio, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return err
}
tio.Cc[unix.VMIN] = vMin
tio.Cc[unix.VTIME] = vTime
if err = unix.IoctlSetTermios(fd, unix.TCSETSW, tio); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,72 @@
// Copyright 2024 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"time"
)
// EventPaste is used to mark the start and end of a bracketed paste.
//
// An event with .Start() true will be sent to mark the start of a bracketed paste,
// followed by a number of keys (string data) for the content, ending with the
// an event with .End() true.
type EventPaste struct {
start bool
t time.Time
data []byte
}
// When returns the time when this EventPaste was created.
func (ev *EventPaste) When() time.Time {
return ev.t
}
// Start returns true if this is the start of a paste.
func (ev *EventPaste) Start() bool {
return ev.start
}
// End returns true if this is the end of a paste.
func (ev *EventPaste) End() bool {
return !ev.start
}
// NewEventPaste returns a new EventPaste.
func NewEventPaste(start bool) *EventPaste {
return &EventPaste{t: time.Now(), start: start}
}
// NewEventClipboard returns a new NewEventClipboard with a data payload
func NewEventClipboard(data []byte) *EventClipboard {
return &EventClipboard{t: time.Now(), data: data}
}
// EventClipboard represents data from the clipboard,
// in response to a GetClipboard request.
type EventClipboard struct {
t time.Time
data []byte
}
// Data returns the attached binary data.
func (ev *EventClipboard) Data() []byte {
return ev.data
}
// When returns the time when this event was created.
func (ev *EventClipboard) When() time.Time {
return ev.t
}

View File

@ -0,0 +1,66 @@
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"time"
)
// EventResize is sent when the window size changes.
type EventResize struct {
t time.Time
ws WindowSize
}
// NewEventResize creates an EventResize with the new updated window size,
// which is given in character cells.
func NewEventResize(width, height int) *EventResize {
ws := WindowSize{
Width: width,
Height: height,
}
return &EventResize{t: time.Now(), ws: ws}
}
// When returns the time when the Event was created.
func (ev *EventResize) When() time.Time {
return ev.t
}
// Size returns the new window size as width, height in character cells.
func (ev *EventResize) Size() (int, int) {
return ev.ws.Width, ev.ws.Height
}
// PixelSize returns the new window size as width, height in pixels. The size
// will be 0,0 if the screen doesn't support this feature
func (ev *EventResize) PixelSize() (int, int) {
return ev.ws.PixelWidth, ev.ws.PixelHeight
}
type WindowSize struct {
Width int
Height int
PixelWidth int
PixelHeight int
}
// CellDimensions returns the dimensions of a single cell, in pixels
func (ws WindowSize) CellDimensions() (int, int) {
if ws.PixelWidth == 0 || ws.PixelHeight == 0 {
return 0, 0
}
return (ws.PixelWidth / ws.Width), (ws.PixelHeight / ws.Height)
}

View File

@ -0,0 +1,111 @@
// Copyright 2015 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
// The names of these constants are chosen to match Terminfo names,
// modulo case, and changing the prefix from ACS_ to Rune. These are
// the runes we provide extra special handling for, with ASCII fallbacks
// for terminals that lack them.
const (
RuneSterling = '£'
RuneDArrow = '↓'
RuneLArrow = '←'
RuneRArrow = '→'
RuneUArrow = '↑'
RuneBullet = '·'
RuneBoard = '░'
RuneCkBoard = '▒'
RuneDegree = '°'
RuneDiamond = '◆'
RuneGEqual = '≥'
RunePi = 'π'
RuneHLine = '─'
RuneLantern = '§'
RunePlus = '┼'
RuneLEqual = '≤'
RuneLLCorner = '└'
RuneLRCorner = '┘'
RuneNEqual = '≠'
RunePlMinus = '±'
RuneS1 = '⎺'
RuneS3 = '⎻'
RuneS7 = '⎼'
RuneS9 = '⎽'
RuneBlock = '█'
RuneTTee = '┬'
RuneRTee = '┤'
RuneLTee = '├'
RuneBTee = '┴'
RuneULCorner = '┌'
RuneURCorner = '┐'
RuneVLine = '│'
)
// RuneFallbacks is the default map of fallback strings that will be
// used to replace a rune when no other more appropriate transformation
// is available, and the rune cannot be displayed directly.
//
// New entries may be added to this map over time, as it becomes clear
// that such is desirable. Characters that represent either letters or
// numbers should not be added to this list unless it is certain that
// the meaning will still convey unambiguously.
//
// As an example, it would be appropriate to add an ASCII mapping for
// the full width form of the letter 'A', but it would not be appropriate
// to do so a glyph representing the country China.
//
// Programs that desire richer fallbacks may register additional ones,
// or change or even remove these mappings with Screen.RegisterRuneFallback
// Screen.UnregisterRuneFallback methods.
//
// Note that Unicode is presumed to be able to display all glyphs.
// This is a pretty poor assumption, but there is no easy way to
// figure out which glyphs are supported in a given font. Hence,
// some care in selecting the characters you support in your application
// is still appropriate.
var RuneFallbacks = map[rune]string{
RuneSterling: "f",
RuneDArrow: "v",
RuneLArrow: "<",
RuneRArrow: ">",
RuneUArrow: "^",
RuneBullet: "o",
RuneBoard: "#",
RuneCkBoard: ":",
RuneDegree: "\\",
RuneDiamond: "+",
RuneGEqual: ">",
RunePi: "*",
RuneHLine: "-",
RuneLantern: "#",
RunePlus: "+",
RuneLEqual: "<",
RuneLLCorner: "+",
RuneLRCorner: "+",
RuneNEqual: "!",
RunePlMinus: "#",
RuneS1: "~",
RuneS3: "-",
RuneS7: "-",
RuneS9: "_",
RuneBlock: "#",
RuneTTee: "+",
RuneRTee: "+",
RuneLTee: "+",
RuneBTee: "+",
RuneULCorner: "+",
RuneURCorner: "+",
RuneVLine: "|",
}

View File

@ -0,0 +1,495 @@
// Copyright 2024 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import "sync"
// Screen represents the physical (or emulated) screen.
// This can be a terminal window or a physical console. Platforms implement
// this differently.
type Screen interface {
// Init initializes the screen for use.
Init() error
// Fini finalizes the screen also releasing resources.
Fini()
// Clear logically erases the screen.
// This is effectively a short-cut for Fill(' ', StyleDefault).
Clear()
// Fill fills the screen with the given character and style.
// The effect of filling the screen is not visible until Show
// is called (or Sync).
Fill(rune, Style)
// SetCell is an older API, and will be removed. Please use
// SetContent instead; SetCell is implemented in terms of SetContent.
SetCell(x int, y int, style Style, ch ...rune)
// GetContent returns the contents at the given location. If the
// coordinates are out of range, then the values will be 0, nil,
// StyleDefault. Note that the contents returned are logical contents
// and may not actually be what is displayed, but rather are what will
// be displayed if Show() or Sync() is called. The width is the width
// in screen cells; most often this will be 1, but some East Asian
// characters and emoji require two cells.
GetContent(x, y int) (primary rune, combining []rune, style Style, width int)
// SetContent sets the contents of the given cell location. If
// the coordinates are out of range, then the operation is ignored.
//
// The first rune is the primary non-zero width rune. The array
// that follows is a possible list of combining characters to append,
// and will usually be nil (no combining characters.)
//
// The results are not displayed until Show() or Sync() is called.
//
// Note that wide (East Asian full width and emoji) runes occupy two cells,
// and attempts to place character at next cell to the right will have
// undefined effects. Wide runes that are printed in the
// last column will be replaced with a single width space on output.
SetContent(x int, y int, primary rune, combining []rune, style Style)
// SetStyle sets the default style to use when clearing the screen
// or when StyleDefault is specified. If it is also StyleDefault,
// then whatever system/terminal default is relevant will be used.
SetStyle(style Style)
// ShowCursor is used to display the cursor at a given location.
// If the coordinates -1, -1 are given or are otherwise outside the
// dimensions of the screen, the cursor will be hidden.
ShowCursor(x int, y int)
// HideCursor is used to hide the cursor. It's an alias for
// ShowCursor(-1, -1).sim
HideCursor()
// SetCursorStyle is used to set the cursor style. If the style
// is not supported (or cursor styles are not supported at all),
// then this will have no effect. Color will be changed if supplied,
// and the terminal supports doing so.
SetCursorStyle(CursorStyle, ...Color)
// Size returns the screen size as width, height. This changes in
// response to a call to Clear or Flush.
Size() (width, height int)
// ChannelEvents is an infinite loop that waits for an event and
// channels it into the user provided channel ch. Closing the
// quit channel and calling the Fini method are cancellation
// signals. When a cancellation signal is received the method
// returns after closing ch.
//
// This method should be used as a goroutine.
//
// NOTE: PollEvent should not be called while this method is running.
ChannelEvents(ch chan<- Event, quit <-chan struct{})
// PollEvent waits for events to arrive. Main application loops
// must spin on this to prevent the application from stalling.
// Furthermore, this will return nil if the Screen is finalized.
PollEvent() Event
// HasPendingEvent returns true if PollEvent would return an event
// without blocking. If the screen is stopped and PollEvent would
// return nil, then the return value from this function is unspecified.
// The purpose of this function is to allow multiple events to be collected
// at once, to minimize screen redraws.
HasPendingEvent() bool
// PostEvent tries to post an event into the event stream. This
// can fail if the event queue is full. In that case, the event
// is dropped, and ErrEventQFull is returned.
PostEvent(ev Event) error
// Deprecated: PostEventWait is unsafe, and will be removed
// in the future.
//
// PostEventWait is like PostEvent, but if the queue is full, it
// blocks until there is space in the queue, making delivery
// reliable. However, it is VERY important that this function
// never be called from within whatever event loop is polling
// with PollEvent(), otherwise a deadlock may arise.
//
// For this reason, when using this function, the use of a
// Goroutine is recommended to ensure no deadlock can occur.
PostEventWait(ev Event)
// EnableMouse enables the mouse. (If your terminal supports it.)
// If no flags are specified, then all events are reported, if the
// terminal supports them.
EnableMouse(...MouseFlags)
// DisableMouse disables the mouse.
DisableMouse()
// EnablePaste enables bracketed paste mode, if supported.
EnablePaste()
// DisablePaste disables bracketed paste mode.
DisablePaste()
// EnableFocus enables reporting of focus events, if your terminal supports it.
EnableFocus()
// DisableFocus disables reporting of focus events.
DisableFocus()
// HasMouse returns true if the terminal (apparently) supports a
// mouse. Note that the return value of true doesn't guarantee that
// a mouse/pointing device is present; a false return definitely
// indicates no mouse support is available.
HasMouse() bool
// Colors returns the number of colors. All colors are assumed to
// use the ANSI color map. If a terminal is monochrome, it will
// return 0.
Colors() int
// Show makes all the content changes made using SetContent() visible
// on the display.
//
// It does so in the most efficient and least visually disruptive
// manner possible.
Show()
// Sync works like Show(), but it updates every visible cell on the
// physical display, assuming that it is not synchronized with any
// internal model. This may be both expensive and visually jarring,
// so it should only be used when believed to actually be necessary.
//
// Typically, this is called as a result of a user-requested redraw
// (e.g. to clear up on-screen corruption caused by some other program),
// or during a resize event.
Sync()
// CharacterSet returns information about the character set.
// This isn't the full locale, but it does give us the input/output
// character set. Note that this is just for diagnostic purposes,
// we normally translate input/output to/from UTF-8, regardless of
// what the user's environment is.
CharacterSet() string
// RegisterRuneFallback adds a fallback for runes that are not
// part of the character set -- for example one could register
// o as a fallback for ø. This should be done cautiously for
// characters that might be displayed ordinarily in language
// specific text -- characters that could change the meaning of
// written text would be dangerous. The intention here is to
// facilitate fallback characters in pseudo-graphical applications.
//
// If the terminal has fallbacks already in place via an alternate
// character set, those are used in preference. Also, standard
// fallbacks for graphical characters in the alternate character set
// terminfo string are registered implicitly.
//
// The display string should be the same width as original rune.
// This makes it possible to register two character replacements
// for full width East Asian characters, for example.
//
// It is recommended that replacement strings consist only of
// 7-bit ASCII, since other characters may not display everywhere.
RegisterRuneFallback(r rune, subst string)
// UnregisterRuneFallback unmaps a replacement. It will unmap
// the implicit ASCII replacements for alternate characters as well.
// When an unmapped char needs to be displayed, but no suitable
// glyph is available, '?' is emitted instead. It is not possible
// to "disable" the use of alternate characters that are supported
// by your terminal except by changing the terminal database.
UnregisterRuneFallback(r rune)
// CanDisplay returns true if the given rune can be displayed on
// this screen. Note that this is a best-guess effort -- whether
// your fonts support the character or not may be questionable.
// Mostly this is for folks who work outside of Unicode.
//
// If checkFallbacks is true, then if any (possibly imperfect)
// fallbacks are registered, this will return true. This will
// also return true if the terminal can replace the glyph with
// one that is visually indistinguishable from the one requested.
CanDisplay(r rune, checkFallbacks bool) bool
// Resize does nothing, since it's generally not possible to
// ask a screen to resize, but it allows the Screen to implement
// the View interface.
Resize(int, int, int, int)
// HasKey returns true if the keyboard is believed to have the
// key. In some cases a keyboard may have keys with this name
// but no support for them, while in others a key may be reported
// as supported but not actually be usable (such as some emulators
// that hijack certain keys). Its best not to depend to strictly
// on this function, but it can be used for hinting when building
// menus, displayed hot-keys, etc. Note that KeyRune (literal
// runes) is always true.
HasKey(Key) bool
// Suspend pauses input and output processing. It also restores the
// terminal settings to what they were when the application started.
// This can be used to, for example, run a sub-shell.
Suspend() error
// Resume resumes after Suspend().
Resume() error
// Beep attempts to sound an OS-dependent audible alert and returns an error
// when unsuccessful.
Beep() error
// SetSize attempts to resize the window. It also invalidates the cells and
// calls the resize function. Note that if the window size is changed, it will
// not be restored upon application exit.
//
// Many terminals cannot support this. Perversely, the "modern" Windows Terminal
// does not support application-initiated resizing, whereas the legacy terminal does.
// Also, some emulators can support this but may have it disabled by default.
SetSize(int, int)
// LockRegion sets or unsets a lock on a region of cells. A lock on a
// cell prevents the cell from being redrawn.
LockRegion(x, y, width, height int, lock bool)
// Tty returns the underlying Tty. If the screen is not a terminal, the
// returned bool will be false
Tty() (Tty, bool)
// SetTitle sets a window title on the screen.
// Terminals may be configured to ignore this, or unable to.
// Tcell may attempt to save and restore the window title on entry and exit, but
// the results may vary. Use of unicode characters may not be supported.
SetTitle(string)
// SetClipboard is used to post arbitrary data to the system clipboard.
// This need not be UTF-8 string data. It's up to the recipient to decode the
// data meaningfully. Terminals may prevent this for security reasons.
SetClipboard([]byte)
// GetClipboard is used to request the clipboard contents. It may be ignored.
// If the terminal is willing, it will be post the clipboard contents using an
// EventPaste with the clipboard content as the Data() field. Terminals may
// prevent this for security reasons.
GetClipboard()
}
// NewScreen returns a default Screen suitable for the user's terminal
// environment.
func NewScreen() (Screen, error) {
// Windows is happier if we try for a console screen first.
if s, _ := NewConsoleScreen(); s != nil {
return s, nil
} else if s, e := NewTerminfoScreen(); s != nil {
return s, nil
} else {
return nil, e
}
}
// MouseFlags are options to modify the handling of mouse events.
// Actual events can be ORed together.
type MouseFlags int
const (
MouseButtonEvents = MouseFlags(1) // Click events only
MouseDragEvents = MouseFlags(2) // Click-drag events (includes button events)
MouseMotionEvents = MouseFlags(4) // All mouse events (includes click and drag events)
)
// CursorStyle represents a given cursor style, which can include the shape and
// whether the cursor blinks or is solid. Support for changing this is not universal.
type CursorStyle int
const (
CursorStyleDefault = CursorStyle(iota) // The default
CursorStyleBlinkingBlock
CursorStyleSteadyBlock
CursorStyleBlinkingUnderline
CursorStyleSteadyUnderline
CursorStyleBlinkingBar
CursorStyleSteadyBar
)
// screenImpl is a subset of Screen that can be used with baseScreen to formulate
// a complete implementation of Screen. See Screen for doc comments about methods.
type screenImpl interface {
Init() error
Fini()
SetStyle(style Style)
ShowCursor(x int, y int)
HideCursor()
SetCursor(CursorStyle, Color)
Size() (width, height int)
EnableMouse(...MouseFlags)
DisableMouse()
EnablePaste()
DisablePaste()
EnableFocus()
DisableFocus()
HasMouse() bool
Colors() int
Show()
Sync()
CharacterSet() string
RegisterRuneFallback(r rune, subst string)
UnregisterRuneFallback(r rune)
CanDisplay(r rune, checkFallbacks bool) bool
Resize(int, int, int, int)
HasKey(Key) bool
Suspend() error
Resume() error
Beep() error
SetSize(int, int)
SetTitle(string)
Tty() (Tty, bool)
SetClipboard([]byte)
GetClipboard()
// Following methods are not part of the Screen api, but are used for interaction with
// the common layer code.
// Locker locks the underlying data structures so that we can access them
// in a thread-safe way.
sync.Locker
// GetCells returns a pointer to the underlying CellBuffer that the implementation uses.
// Various methods will write to these for performance, but will use the lock to do so.
GetCells() *CellBuffer
// StopQ is closed when the screen is shut down via Fini. It remains open if the screen
// is merely suspended.
StopQ() <-chan struct{}
// EventQ delivers events. Events are posted to this by the screen in response to
// key presses, resizes, etc. Application code receives events from this via the
// Screen.PollEvent, Screen.ChannelEvents APIs.
EventQ() chan Event
}
type baseScreen struct {
screenImpl
}
func (b *baseScreen) SetCell(x int, y int, style Style, ch ...rune) {
if len(ch) > 0 {
b.SetContent(x, y, ch[0], ch[1:], style)
} else {
b.SetContent(x, y, ' ', nil, style)
}
}
func (b *baseScreen) Clear() {
b.Fill(' ', StyleDefault)
}
func (b *baseScreen) Fill(r rune, style Style) {
cb := b.GetCells()
b.Lock()
cb.Fill(r, style)
b.Unlock()
}
func (b *baseScreen) SetContent(x, y int, mainc rune, combc []rune, st Style) {
cells := b.GetCells()
b.Lock()
cells.SetContent(x, y, mainc, combc, st)
b.Unlock()
}
func (b *baseScreen) GetContent(x, y int) (rune, []rune, Style, int) {
var primary rune
var combining []rune
var style Style
var width int
cells := b.GetCells()
b.Lock()
primary, combining, style, width = cells.GetContent(x, y)
b.Unlock()
return primary, combining, style, width
}
func (b *baseScreen) LockRegion(x, y, width, height int, lock bool) {
cells := b.GetCells()
b.Lock()
for j := y; j < (y + height); j += 1 {
for i := x; i < (x + width); i += 1 {
switch lock {
case true:
cells.LockCell(i, j)
case false:
cells.UnlockCell(i, j)
}
}
}
b.Unlock()
}
func (b *baseScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-b.StopQ():
return
case ev := <-b.EventQ():
select {
case <-quit:
return
case <-b.StopQ():
return
case ch <- ev:
}
}
}
}
func (b *baseScreen) PollEvent() Event {
select {
case <-b.StopQ():
return nil
case ev := <-b.EventQ():
return ev
}
}
func (b *baseScreen) HasPendingEvent() bool {
return len(b.EventQ()) > 0
}
func (b *baseScreen) PostEventWait(ev Event) {
select {
case b.EventQ() <- ev:
case <-b.StopQ():
}
}
func (b *baseScreen) PostEvent(ev Event) error {
select {
case b.EventQ() <- ev:
return nil
default:
return ErrEventQFull
}
}
func (b *baseScreen) SetCursorStyle(cs CursorStyle, ccs ...Color) {
if len(ccs) > 0 {
b.SetCursor(cs, ccs[0])
} else {
b.SetCursor(cs, ColorNone)
}
}

View File

@ -0,0 +1,528 @@
// Copyright 2024 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tcell
import (
"sync"
"unicode/utf8"
"golang.org/x/text/transform"
)
// NewSimulationScreen returns a SimulationScreen. Note that
// SimulationScreen is also a Screen.
func NewSimulationScreen(charset string) SimulationScreen {
if charset == "" {
charset = "UTF-8"
}
ss := &simscreen{charset: charset}
ss.Screen = &baseScreen{screenImpl: ss}
return ss
}
// SimulationScreen represents a screen simulation. This is intended to
// be a superset of normal Screens, but also adds some important interfaces
// for testing.
type SimulationScreen interface {
Screen
// InjectKeyBytes injects a stream of bytes corresponding to
// the native encoding (see charset). It turns true if the entire
// set of bytes were processed and delivered as KeyEvents, false
// if any bytes were not fully understood. Any bytes that are not
// fully converted are discarded.
InjectKeyBytes(buf []byte) bool
// InjectKey injects a key event. The rune is a UTF-8 rune, post
// any translation.
InjectKey(key Key, r rune, mod ModMask)
// InjectMouse injects a mouse event.
InjectMouse(x, y int, buttons ButtonMask, mod ModMask)
// GetContents returns screen contents as an array of
// cells, along with the physical width & height. Note that the
// physical contents will be used until the next time SetSize()
// is called.
GetContents() (cells []SimCell, width int, height int)
// GetCursor returns the cursor details.
GetCursor() (x int, y int, visible bool)
// GetTitle gets the previously set title.
GetTitle() string
// GetClipboardData gets the actual data for the clipboard.
GetClipboardData() []byte
}
// SimCell represents a simulated screen cell. The purpose of this
// is to track on screen content.
type SimCell struct {
// Bytes is the actual character bytes. Normally this is
// rune data, but it could be be data in another encoding system.
Bytes []byte
// Style is the style used to display the data.
Style Style
// Runes is the list of runes, unadulterated, in UTF-8.
Runes []rune
}
type simscreen struct {
physw int
physh int
fini bool
style Style
evch chan Event
quit chan struct{}
front []SimCell
back CellBuffer
clear bool
cursorx int
cursory int
cursorvis bool
mouse bool
paste bool
charset string
encoder transform.Transformer
decoder transform.Transformer
fillchar rune
fillstyle Style
fallback map[rune]string
title string
clipboard []byte
Screen
sync.Mutex
}
func (s *simscreen) Init() error {
s.evch = make(chan Event, 10)
s.quit = make(chan struct{})
s.fillchar = 'X'
s.fillstyle = StyleDefault
s.mouse = false
s.physw = 80
s.physh = 25
s.cursorx = -1
s.cursory = -1
s.style = StyleDefault
if enc := GetEncoding(s.charset); enc != nil {
s.encoder = enc.NewEncoder()
s.decoder = enc.NewDecoder()
} else {
return ErrNoCharset
}
s.front = make([]SimCell, s.physw*s.physh)
s.back.Resize(80, 25)
// default fallbacks
s.fallback = make(map[rune]string)
for k, v := range RuneFallbacks {
s.fallback[k] = v
}
return nil
}
func (s *simscreen) Fini() {
s.Lock()
s.fini = true
s.back.Resize(0, 0)
s.Unlock()
if s.quit != nil {
close(s.quit)
}
s.physw = 0
s.physh = 0
s.front = nil
}
func (s *simscreen) SetStyle(style Style) {
s.Lock()
s.style = style
s.Unlock()
}
func (s *simscreen) drawCell(x, y int) int {
mainc, combc, style, width := s.back.GetContent(x, y)
if !s.back.Dirty(x, y) {
return width
}
if x >= s.physw || y >= s.physh || x < 0 || y < 0 {
return width
}
simc := &s.front[(y*s.physw)+x]
if style == StyleDefault {
style = s.style
}
simc.Style = style
simc.Runes = append([]rune{mainc}, combc...)
// now emit runes - taking care to not overrun width with a
// wide character, and to ensure that we emit exactly one regular
// character followed up by any residual combing characters
simc.Bytes = nil
if x > s.physw-width {
simc.Runes = []rune{' '}
simc.Bytes = []byte{' '}
return width
}
lbuf := make([]byte, 12)
ubuf := make([]byte, 12)
nout := 0
for _, r := range simc.Runes {
l := utf8.EncodeRune(ubuf, r)
nout, _, _ = s.encoder.Transform(lbuf, ubuf[:l], true)
if nout == 0 || lbuf[0] == '\x1a' {
// skip combining
if subst, ok := s.fallback[r]; ok {
simc.Bytes = append(simc.Bytes,
[]byte(subst)...)
} else if r >= ' ' && r <= '~' {
simc.Bytes = append(simc.Bytes, byte(r))
} else if simc.Bytes == nil {
simc.Bytes = append(simc.Bytes, '?')
}
} else {
simc.Bytes = append(simc.Bytes, lbuf[:nout]...)
}
}
s.back.SetDirty(x, y, false)
return width
}
func (s *simscreen) ShowCursor(x, y int) {
s.Lock()
s.cursorx, s.cursory = x, y
s.showCursor()
s.Unlock()
}
func (s *simscreen) HideCursor() {
s.ShowCursor(-1, -1)
}
func (s *simscreen) showCursor() {
x, y := s.cursorx, s.cursory
if x < 0 || y < 0 || x >= s.physw || y >= s.physh {
s.cursorvis = false
} else {
s.cursorvis = true
}
}
func (s *simscreen) hideCursor() {
// does not update cursor position
s.cursorvis = false
}
func (s *simscreen) SetCursor(CursorStyle, Color) {}
func (s *simscreen) Show() {
s.Lock()
s.resize()
s.draw()
s.Unlock()
}
func (s *simscreen) clearScreen() {
// We emulate a hardware clear by filling with a specific pattern
for i := range s.front {
s.front[i].Style = s.fillstyle
s.front[i].Runes = []rune{s.fillchar}
s.front[i].Bytes = []byte{byte(s.fillchar)}
}
s.clear = false
}
func (s *simscreen) draw() {
s.hideCursor()
if s.clear {
s.clearScreen()
}
w, h := s.back.Size()
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
width := s.drawCell(x, y)
x += width - 1
}
}
s.showCursor()
}
func (s *simscreen) EnableMouse(...MouseFlags) {
s.mouse = true
}
func (s *simscreen) DisableMouse() {
s.mouse = false
}
func (s *simscreen) EnablePaste() {
s.paste = true
}
func (s *simscreen) DisablePaste() {
s.paste = false
}
func (s *simscreen) EnableFocus() {
}
func (s *simscreen) DisableFocus() {
}
func (s *simscreen) Size() (int, int) {
s.Lock()
w, h := s.back.Size()
s.Unlock()
return w, h
}
func (s *simscreen) resize() {
w, h := s.physw, s.physh
ow, oh := s.back.Size()
if w != ow || h != oh {
s.back.Resize(w, h)
ev := NewEventResize(w, h)
s.postEvent(ev)
}
}
func (s *simscreen) Colors() int {
return 256
}
func (s *simscreen) postEvent(ev Event) {
select {
case s.evch <- ev:
case <-s.quit:
}
}
func (s *simscreen) InjectMouse(x, y int, buttons ButtonMask, mod ModMask) {
ev := NewEventMouse(x, y, buttons, mod)
s.postEvent(ev)
}
func (s *simscreen) InjectKey(key Key, r rune, mod ModMask) {
ev := NewEventKey(key, r, mod)
s.postEvent(ev)
}
func (s *simscreen) InjectKeyBytes(b []byte) bool {
failed := false
outer:
for len(b) > 0 {
if b[0] >= ' ' && b[0] <= 0x7F {
// printable ASCII easy to deal with -- no encodings
ev := NewEventKey(KeyRune, rune(b[0]), ModNone)
s.postEvent(ev)
b = b[1:]
continue
}
if b[0] < 0x80 {
mod := ModNone
// No encodings start with low numbered values
if Key(b[0]) >= KeyCtrlA && Key(b[0]) <= KeyCtrlZ {
mod = ModCtrl
}
ev := NewEventKey(Key(b[0]), 0, mod)
s.postEvent(ev)
b = b[1:]
continue
}
utfb := make([]byte, len(b)*4) // worst case
for l := 1; l < len(b); l++ {
s.decoder.Reset()
nout, nin, _ := s.decoder.Transform(utfb, b[:l], true)
if nout != 0 {
r, _ := utf8.DecodeRune(utfb[:nout])
if r != utf8.RuneError {
ev := NewEventKey(KeyRune, r, ModNone)
s.postEvent(ev)
}
b = b[nin:]
continue outer
}
}
failed = true
b = b[1:]
continue
}
return !failed
}
func (s *simscreen) Sync() {
s.Lock()
s.clear = true
s.resize()
s.back.Invalidate()
s.draw()
s.Unlock()
}
func (s *simscreen) CharacterSet() string {
return s.charset
}
func (s *simscreen) SetSize(w, h int) {
s.Lock()
newc := make([]SimCell, w*h)
for row := 0; row < h && row < s.physh; row++ {
for col := 0; col < w && col < s.physw; col++ {
newc[(row*w)+col] = s.front[(row*s.physw)+col]
}
}
s.cursorx, s.cursory = -1, -1
s.physw, s.physh = w, h
s.front = newc
s.back.Resize(w, h)
s.Unlock()
}
func (s *simscreen) GetContents() ([]SimCell, int, int) {
s.Lock()
cells, w, h := s.front, s.physw, s.physh
s.Unlock()
return cells, w, h
}
func (s *simscreen) GetCursor() (int, int, bool) {
s.Lock()
x, y, vis := s.cursorx, s.cursory, s.cursorvis
s.Unlock()
return x, y, vis
}
func (s *simscreen) RegisterRuneFallback(r rune, subst string) {
s.Lock()
s.fallback[r] = subst
s.Unlock()
}
func (s *simscreen) UnregisterRuneFallback(r rune) {
s.Lock()
delete(s.fallback, r)
s.Unlock()
}
func (s *simscreen) CanDisplay(r rune, checkFallbacks bool) bool {
if enc := s.encoder; enc != nil {
nb := make([]byte, 6)
ob := make([]byte, 6)
num := utf8.EncodeRune(ob, r)
enc.Reset()
dst, _, err := enc.Transform(nb, ob[:num], true)
if dst != 0 && err == nil && nb[0] != '\x1A' {
return true
}
}
if !checkFallbacks {
return false
}
if _, ok := s.fallback[r]; ok {
return true
}
return false
}
func (s *simscreen) HasMouse() bool {
return false
}
func (s *simscreen) Resize(int, int, int, int) {}
func (s *simscreen) HasKey(Key) bool {
return true
}
func (s *simscreen) Beep() error {
return nil
}
func (s *simscreen) Suspend() error {
return nil
}
func (s *simscreen) Resume() error {
return nil
}
func (s *simscreen) Tty() (Tty, bool) {
return nil, false
}
func (s *simscreen) GetCells() *CellBuffer {
return &s.back
}
func (s *simscreen) EventQ() chan Event {
return s.evch
}
func (s *simscreen) StopQ() <-chan struct{} {
return s.quit
}
func (s *simscreen) SetTitle(title string) {
s.title = title
}
func (s *simscreen) GetTitle() string {
return s.title
}
func (s *simscreen) SetClipboard(data []byte) {
s.clipboard = data
}
func (s *simscreen) GetClipboard() {
if s.clipboard != nil {
ev := NewEventClipboard(s.clipboard)
s.postEvent(ev)
}
}
func (s *simscreen) GetClipboardData() []byte {
return s.clipboard
}

View File

@ -0,0 +1,186 @@
// Copyright 2021 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
// You may obtain a copy of the license at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package tcell
import (
"errors"
"fmt"
"os"
"os/signal"
"strconv"
"sync"
"syscall"
"time"
"golang.org/x/sys/unix"
"golang.org/x/term"
)
// stdIoTty is an implementation of the Tty API based upon stdin/stdout.
type stdIoTty struct {
fd int
in *os.File
out *os.File
saved *term.State
sig chan os.Signal
cb func()
stopQ chan struct{}
dev string
wg sync.WaitGroup
l sync.Mutex
}
func (tty *stdIoTty) Read(b []byte) (int, error) {
return tty.in.Read(b)
}
func (tty *stdIoTty) Write(b []byte) (int, error) {
return tty.out.Write(b)
}
func (tty *stdIoTty) Close() error {
return nil
}
func (tty *stdIoTty) Start() error {
tty.l.Lock()
defer tty.l.Unlock()
// We open another copy of /dev/tty. This is a workaround for unusual behavior
// observed in macOS, apparently caused when a sub-shell (for example) closes our
// own tty device (when it exits for example). Getting a fresh new one seems to
// resolve the problem. (We believe this is a bug in the macOS tty driver that
// fails to account for dup() references to the same file before applying close()
// related behaviors to the tty.) We're also holding the original copy we opened
// since closing that might have deleterious effects as well. The upshot is that
// we will have up to two separate file handles open on /dev/tty. (Note that when
// using stdin/stdout instead of /dev/tty this problem is not observed.)
var err error
tty.in = os.Stdin
tty.out = os.Stdout
tty.fd = int(tty.in.Fd())
if !term.IsTerminal(tty.fd) {
return errors.New("device is not a terminal")
}
_ = tty.in.SetReadDeadline(time.Time{})
saved, err := term.MakeRaw(tty.fd) // also sets vMin and vTime
if err != nil {
return err
}
tty.saved = saved
tty.stopQ = make(chan struct{})
tty.wg.Add(1)
go func(stopQ chan struct{}) {
defer tty.wg.Done()
for {
select {
case <-tty.sig:
tty.l.Lock()
cb := tty.cb
tty.l.Unlock()
if cb != nil {
cb()
}
case <-stopQ:
return
}
}
}(tty.stopQ)
signal.Notify(tty.sig, syscall.SIGWINCH)
return nil
}
func (tty *stdIoTty) Drain() error {
_ = tty.in.SetReadDeadline(time.Now())
if err := tcSetBufParams(tty.fd, 0, 0); err != nil {
return err
}
return nil
}
func (tty *stdIoTty) Stop() error {
tty.l.Lock()
if err := term.Restore(tty.fd, tty.saved); err != nil {
tty.l.Unlock()
return err
}
_ = tty.in.SetReadDeadline(time.Now())
signal.Stop(tty.sig)
close(tty.stopQ)
tty.l.Unlock()
tty.wg.Wait()
return nil
}
func (tty *stdIoTty) WindowSize() (WindowSize, error) {
size := WindowSize{}
ws, err := unix.IoctlGetWinsize(tty.fd, unix.TIOCGWINSZ)
if err != nil {
return size, err
}
w := int(ws.Col)
h := int(ws.Row)
if w == 0 {
w, _ = strconv.Atoi(os.Getenv("COLUMNS"))
}
if w == 0 {
w = 80 // default
}
if h == 0 {
h, _ = strconv.Atoi(os.Getenv("LINES"))
}
if h == 0 {
h = 25 // default
}
size.Width = w
size.Height = h
size.PixelWidth = int(ws.Xpixel)
size.PixelHeight = int(ws.Ypixel)
return size, nil
}
func (tty *stdIoTty) NotifyResize(cb func()) {
tty.l.Lock()
tty.cb = cb
tty.l.Unlock()
}
// NewStdioTty opens a tty using standard input/output.
func NewStdIoTty() (Tty, error) {
tty := &stdIoTty{
sig: make(chan os.Signal),
in: os.Stdin,
out: os.Stdout,
}
var err error
tty.fd = int(tty.in.Fd())
if !term.IsTerminal(tty.fd) {
return nil, errors.New("not a terminal")
}
if tty.saved, err = term.GetState(tty.fd); err != nil {
return nil, fmt.Errorf("failed to get state: %w", err)
}
return tty, nil
}

Some files were not shown because too many files have changed in this diff Show More