Connect with us

Maryland

Former Maryland election board member who stormed US Capitol, donated to election deniers slipped through state’s vetting process

Published

on

Former Maryland election board member who stormed US Capitol, donated to election deniers slipped through state’s vetting process


Agents involved in the largest federal investigation in U.S. history first received a tip about Salisbury’s Carlos Ayala just seven days after the Jan. 6, 2021, attack on the Capitol.

By the time they charged him a full three years later — with a civil disorder felony and related misdemeanors for his alleged role in the riot that day — Ayala hadn’t just retreated to a quiet life on the Eastern Shore.

He stayed involved in local Republican politics, helping out with some party efforts and attending social functions. He picked up the pace of his political donations, spending tens of thousands of dollars on candidates — including $1,826 to 2022 gubernatorial nominee Dan Cox, a far-right Republican who questioned the legitimacy of the 2020 election and took legal action against Maryland’s election system.

And he was vetted by, dined with and earned the trust of state officials on his way to becoming a member of Maryland’s most important elections board, a position he resigned only after his arrest last month.

Advertisement

How an executive who was a member of rural Maryland’s most prominent business family came to climb over police barriers with a flag depicting an M-16-style rifle in a crowd trying to overthrow a presidential election, according to court documents, has rocked officials and acquaintances.

It’s also raised concerns about Maryland’s backgrounding process for appointments to boards as vital as the State Board of Elections, prompting Democratic Gov. Wes Moore’s administration to explore changes to that process and legislators to begin more thorough questioning of the governor’s nominees.

“I was blown away,” said Senate President Bill Ferguson, a Baltimore Democrat whose chamber is constitutionally required to reject or approve the governor’s nominees, as it did with Ayala after Moore accepted the Maryland Republican Party’s recommendation of him last year for one of two minority seats on the five-member board.

Ferguson and other legislators said the nomination and vetting process — which includes background checks from both the governor’s office and the Senate but no formal interviews and sometimes little questioning from senators in confirmation hearings — is unlikely to change in major ways moving forward.

The vetting begins with the governor’s appointments office reviewing only publicly available documents, including court and criminal records, sex offender registries, voting history, campaign finance donations and social media posts, according the governor’s office.

Advertisement

That type of search led Moore to reject the first GOP recommendation last year, William Newton, in part for his past statements of denying “the legitimacy of Maryland’s elections,” the governor wrote in a letter last February. A second nominee, Christine McCloud, passed the governor’s vetting but was then rejected by senators who pressed her on her knowledge and faith in the elections system and found she did not support mail-in ballots, which have skyrocketed in use since the pandemic and subsequently come under fire from many Republicans.

In Ayala’s case, neither the administration’s nor the Senate’s background checks raised red flags. Any information about the then-active Department of Justice investigation was kept tightly under wraps, making it difficult to learn about Ayala’s alleged participation in Jan. 6 without asking him directly, legislators and others said.

“While no amount of investigation of public material could have prevented this appointment, which is statutorily required to be submitted to the governor by the Republican Party of Maryland, the office is committed to exploring changes to the appointments process to ensure that all appointees to board[s] and commissions in the Moore-Miller Administration reflect the values we seek to uphold,” said Moore spokesman Carter Elliot IV.

David Levine, an elections integrity expert, said parts of the FBI’s Jan. 6 investigation have been slow to trickle out over the last three years. But he said there should still be a close examination of whether anyone in Moore’s administration, the Maryland General Assembly or the Republican Party knew or could have known about the investigation in order to strengthen vetting and implement safeguards in the future.

“I would be stunned if there wasn’t an after-action review to examine what went awry here,” said Levine, an elections integrity fellow at the Alliance for Securing Democracy, a nonpartisan initiative within the German Marshall Fund of the United States. “Something went awry and you need the full landscape of what took place and when.”

Advertisement

Levine said Ayala’s presence on the board “raises profound questions” about election security concerns and the ability or willingness of Republicans to put someone on the board who could have had a “powerful megaphone” to spread potentially false claims about future elections. While the five-member board does not carry out election administration duties on a day-to-day basis, it chooses the state official who does and decides other important matters like voting locations and changes to some voting-related deadlines.

“If there had been any hint of it, of any participation in Jan. 6, there is no question in my mind that would have been a non-starter,” said Ferguson, who sits on the committee that approved Ayala and whose members did not ask the nominee a single question during his confirmation hearing in March.

State Sen. Antonio Hayes, another Baltimore Democrat, is beginning his first year chairing the Executive Nominations Committee, which considered roughly 1,000 of Moore’s appointments last year. He said in a news conference Friday that the committee would be “probing a little bit more” behind the scenes.

“It’s not a perfect process. We’re not able to capture everything,” Hayes acknowledged in a separate interview. “Given the latest incident, it will adjust some of the questions we will ask [future nominees].”

State Sen. Cheryl Kagan, a Montgomery County Democrat who is active in elections policymaking, said she expects her colleagues will be “especially diligent about asking a lot of direct questions of the next nominee” from the GOP.

Advertisement

Still, honesty could remain an issue even then — especially because nominees, aside from judicial candidates, are not asked questions under oath, Kagan said. She said Ayala had appeared “engaging and eager to learn” in his time working on the board for nearly a year, raising questions for her about whether other nominees could just tell lawmakers what they want to hear. Hayes said the committee has not considered expanding the oath requirement to other nominees.

“I have thought about this a lot,” Kagan said when asked if she believed Ayala had been telling the truth. “It has troubled me because I had dinner with him. I had many phone conversations. We texted back and forth. I voted for him. I supported him.”

Republicans who have been acquainted with Ayala also had only kind things to say about him, with several calling him quiet and smart in interviews with The Baltimore Sun.

“I was as surprised as anyone else,” said John Cannon, the Wicomico County Council president and a member of the Wicomico County Republican Central Committee. “Carlos is a nice guy. He’s a quiet guy, a very respectful guy.”

Wendy Anspacher, who chairs the central committee, said Ayala has not been a member of the group but that he “is an upstanding member of the community” and is “always willing to lend a helping hand,” including volunteering during early voting efforts.

Advertisement

Anspacher said her group did not have a role in recommending him to the state party for his nomination to the state board. She said she believed the charges against him are “all political” and that he is innocent until proven guilty.

State Sen. Mary Beth Carozza, a Wicomico County Republican who called Ayala a “very well-respected business and community leader” while introducing him at his Senate confirmation hearing, did not initially recommend him to the state party and was not aware that he was in Washington, D.C., on Jan. 6, a staffer for Carozza said in an email. The staffer did not respond to a question about whether that knowledge would have precluded her from supporting Ayala.

It’s unclear when Ayala, a 52-year-old former Perdue Farms executive and stepson of Frank Perdue, discovered he was the subject of a federal investigation. According to the criminal complaint and arrest warrant, the FBI first learned “through routine law enforcement” that Ayala was at the Capitol on Jan. 12. “On or about” the next day, the bureau received an anonymous tip that Ayala had been inside the building and had worn a gas mask. Agents over the next few months interviewed at least one unidentified witness who traveled with Ayala to the Capitol, according to the documents.

Ayala’s attorney, James Trusty, declined to comment about when Ayala became aware of the investigation or when and why he left Perdue.

Ayala eventually submitted his own application for the State Board of Elections on Jan. 31, 2023, in the same process as anyone looking to join one of the state’s many boards and commissions, according to the governor’s office.

Advertisement

Maryland Republican Party Chair Nicole Beus Harris notified the governor’s appointments office she would recommend Ayala on March 3, about two weeks after one of her previous nominees was rejected. With the governor required to submit one of the GOP’s recommendations, the appointments office submitted Ayala’s name to the Senate for confirmation on March 10.

Harris, who did not return multiple requests for comment, is married to Republican U.S. Rep. Andy Harris, a staunch supporter of former President Donald Trump who met with him and other GOP members of Congress at the White House in December 2020 to discuss overturning the election.

Ayala had donated $9,400 to Andy Harris’ campaign committee since 2016. That included $1,000 donations on both Feb. 20 and March 14 in 2023, directly before and after Nicole Beus Harris submitted his name.

Ayala drastically scaled up campaign contributions to Republicans in recent years, according to a Sun review of state and federal campaign finance records.

After spending $25,287 on federal political committees between 2008 and 2017, he spent $29,232 between 2020 and 2023, including $21,025 in 2022, according to Federal Elections Commission data. His most recent donations, $47 on March 30 — three days after his Senate confirmation hearing — and $100 on April 3 last year were through the Republican online donation platform WinRed and were earmarked for former Republican President Donald Trump’s “Save America” fundraising committee, according to FEC data.

Advertisement

Ayala’s donations to state-level candidates also spiked in 2022, with $24,301 that year. They included two donations to Cox — $1,776 on Oct. 17, 2022, and $50 on Nov. 16, 2022, after the election — while the gubernatorial candidate was taking legal action opposing the State Board of Elections over its push to count mail-in ballots faster during the election. Cox lost the case and the election to Moore in a landslide.

Elliott, the spokesman for Moore, said the administration realized Ayala had a track record of donating to Republican candidates including Cox.

“This was not — and is not — considered a disqualifying factor in vetting for board appointments,” Elliott said. “The Governor’s Office of Appointments is committed to creating a state government that accurately reflects the State of Maryland while following applicable statutory requirements.”

Levine, the elections expert, said a donation alone shouldn’t be considered an endorsement of the recipient’s actions — like Cox’s actions or statements questioning Maryland’s election integrity — especially as the Republican Party remains dominated by, through Trump’s leadership, people who question the legitimacy of elections.

Ayala’s 2022 donations also included $1,000 to Carozza and $3,000 to Julie Giordano, a Republican who won that year to become the Wicomico County executive. Giordano did not return multiple requests for comment.

Advertisement

Jared Schablein, who chairs the Lower Shore Progressive Caucus, said his organization is calling on anyone who received donations from Ayala to return them or give them to charity.

“There’s overwhelming evidence that Carlos was there that day. To really restore trust in the community and faith in our democratic processes, we want them to renounce this man and give back the money,” Schablein said. “Who you take money from matters.”

Carozza, in a statement provided by a staffer, said, “Under our criminal justice system, a person accused of a crime is presumed innocent until proven guilty in a court of law. If Carlos Ayala is convicted, I will review the matter at that time.”

Del. Carl Anderton, a Republican who’s represented Salisbury in Annapolis since 2015, is not one of the local politicians who received campaign donations from Ayala, whom he said he thinks he met at various social functions and Republican events in the county over the years.

Anderton said he did not know Ayala well, that he’d attended the Jan. 6 attack or, until the charges and resignation, that he’d even been appointed to the elections board.

Advertisement

While Anderton said he personally believes the 2020 election was not stolen, as Trump has continued to falsely claim in his pursuit for the White House again in 2024, he said Republicans in his county are probably split “half and half” over the issue.

He said he’s been in touch with the governor’s office about making sure there’s more communication in the future with legislators if a constituent of theirs is up for an important nomination. Even though the House does not vet or confirm any gubernatorial appointments, Anderton said former Republican Gov. Larry Hogan’s administration would typically call him in those cases. That didn’t happen for Ayala but, Anderton said, “I know now it’s going to happen.” He also said, however, that a call would not have made a difference in Ayala’s case.

“We’ve got to make sure something like this doesn’t happen again,” Anderton said.



Source link

Advertisement

Maryland

Deadly motorcycle crash closes busy stretch of Connecticut Avenue in Montgomery Co. – WTOP News

Published

on

Deadly motorcycle crash closes busy stretch of Connecticut Avenue in Montgomery Co. – WTOP News


A deadly crash involving a motorcycle shut down a stretch of Connecticut Avenue in Chevy Chase, Maryland, early Tuesday.

A deadly crash involving a motorcycle shut down a stretch of Connecticut Avenue in Chevy Chase, Maryland, early Tuesday.

Montgomery County police said officers responded around 6:15 a.m. to a report of a crash involving a car and a motorcycle at Manor Road and Connecticut Avenue.

A motorcyclist was found in serious condition. Police said the man died at the scene.

Advertisement

A woman driving the car was hospitalized with minor injuries.

Connecticut Avenue is closed in both directions between Jones Bridge Road and Manor Road as police investigate the collision.

The crash is the latest in a series of deadly motorcycle incidents across Maryland, including a deadly hit-and-run in Charles County that left one man dead Saturday.

A map of the area is below.

CLICK MAP FOR THE LATEST ROAD CONDITIONS FROM THE WTOP TRAFFIC CENTER: Map shows closure of Connecticut Avenue in both directions, south of Interstate 495 in Chevy Chase, Md.

Get breaking news and daily headlines delivered to your email inbox by signing up here.

Advertisement

© 2026 WTOP. All Rights Reserved. This website is not intended for users located within the European Economic Area.



Source link

Continue Reading

Maryland

Maryland House passes bill to end automatic charging of some juveniles as adults

Published

on

Maryland House passes bill to end automatic charging of some juveniles as adults


Maryland lawmakers have approved a bill that would end the automatic charging of certain juveniles as adults and is now on its way to the governor’s office for review.

The Youth Charging Reform Act passed the House of Delegates on Monday after clearing the Senate last week. The bill aims to end the automatic charging of 16- and 17-year-olds as adults for certain drug, assault, and gun offenses.

ALSO READ | Bill to end automatic charging of some juveniles as adults inches closer to passage

The bill drew significant opposition from several top prosecutors in Maryland, including Baltimore City State’s Attorney Ivan Bates, Prince George’s County State’s Attorney Tara Jackson, Montgomery County State’s Attorney John McCarthy, and Anne Arundel County State’s Attorney Anne Colt Leitess.

Advertisement

For months, they’ve warned that the change could weaken accountability and pose public safety risks.

“DJS is not equipped to deal with these increased violent offenders, and the legislature should defer the implementation of this bill until the programs are in place,” McCarthy said.

Maryland sheriffs also joined the pushback, including Carroll County Sheriff Jim Dewees, who previously said, “This is not a smart move, by any means, I don’t like it because, and I think by and large, law enforcement doesn’t like it, because we don’t have a whole lot of trust in the juvenile court system and the DJS system.”

ALSO READ | FOX45 sends video of prosecutors’ concerns to lawmakers backing juvenile justice bill

Supporters of the bill argued that most cases end up in the juvenile system regardless, and therefore, it makes sense to start them in the Department of Juvenile Services.

Advertisement

“They’re already ingesting that work anyway; they’re already doing that workload anyway,” Sen. Will Smith, lead sponsor of the legislation, previously told FOX45 News. “We’re just wasting time and money by sending them to the adult system first.”

Comment with Bubbles

JOIN THE CONVERSATION (6)

The bill now awaits at Gov. Wes Moore’s desk for a final decision.



Source link

Advertisement
Continue Reading

Maryland

B-W Parkway to close for bridge replacement

Published

on

B-W Parkway to close for bridge replacement


WBAL

Maryland Route 295

Advertisement

SOURCE: WBAL

Advertisement

Baltimore-Washington Parkway, exit ramps to close in Jessup for bridge replacement

WBAL logo

Updated: 10:31 AM EDT Apr 6, 2026

Editorial Standards

Advertisement

A portion of the Baltimore-Washington Parkway will close for two weekends in Jessup, where a bridge will be demolished.Check our LIVE traffic map and cameras in the WBAL-TV 11 News appThe Maryland State Highway Administration said Maryland Route 295 ramps will close, weather permitting, at Maryland Route 175 for an interchange reconstruction project.Southbound MD 295 will close between Maryland Routes 100 and 32 starting at 10 p.m. on April 10 until 5 a.m. on April 13 with the following lane and ramp closures.Both ramps from MD 100 onto southbound MD 295.Both ramps from Arundel Mills Boulevard onto southbound MD 295.Southbound MD 295 ramp to eastbound and westbound MD 175.Westbound MD 175 ramp to southbound MD 295.Northbound MD 295 will close between Maryland Routes 32 and 100 starting at 10 p.m. on April 17 until 5 a.m. on April 20 with the following ramp closures.Both ramps from MD 32 onto northbound MD 295.Eastbound MD 175 ramp to northbound MD 295.Northbound MD 295 ramp to eastbound and westbound MD 175.The mainline MD 175 lanes on the new bridge will remain open to traffic. The SHA said signs will be posted for detours to include MD 100, Interstate 95 and MD 32. Those going to Baltimore-Washington International Thurgood Marshall Airport are advised to use alternate north-south routes such as I-95, U.S. Route 1 or I-97 to reach I-195.The overall interchange reconstruction project completion is scheduled for Fall 2027, schedule and weather permitting.

A portion of the Baltimore-Washington Parkway will close for two weekends in Jessup, where a bridge will be demolished.

Advertisement

The Maryland State Highway Administration said Maryland Route 295 ramps will close, weather permitting, at Maryland Route 175 for an interchange reconstruction project.

Southbound MD 295 will close between Maryland Routes 100 and 32 starting at 10 p.m. on April 10 until 5 a.m. on April 13 with the following lane and ramp closures.

  • Both ramps from MD 100 onto southbound MD 295.
  • Both ramps from Arundel Mills Boulevard onto southbound MD 295.
  • Southbound MD 295 ramp to eastbound and westbound MD 175.
  • Westbound MD 175 ramp to southbound MD 295.

Northbound MD 295 will close between Maryland Routes 32 and 100 starting at 10 p.m. on April 17 until 5 a.m. on April 20 with the following ramp closures.

  • Both ramps from MD 32 onto northbound MD 295.
  • Eastbound MD 175 ramp to northbound MD 295.
  • Northbound MD 295 ramp to eastbound and westbound MD 175.

The mainline MD 175 lanes on the new bridge will remain open to traffic.

The SHA said signs will be posted for detours to include MD 100, Interstate 95 and MD 32.

Advertisement

Those going to Baltimore-Washington International Thurgood Marshall Airport are advised to use alternate north-south routes such as I-95, U.S. Route 1 or I-97 to reach I-195.

The overall interchange reconstruction project completion is scheduled for Fall 2027, schedule and weather permitting.

Advertisement

`;
}

function refreshWeatherIframe(containerId) {
var iframeId = ‘weather-iframe-‘ + containerId;
var iframe = document.getElementById(iframeId);
if (iframe && iframe.src) {
var originalSrc = iframe.src;
iframe.src = originalSrc + (originalSrc.indexOf(‘?’) > -1 ? ‘&’ : ‘?’) + ‘t=” + Date.now();
}
}

function initializeWeatherBox(container) {
var containerId = container.getAttribute(“data-container-id’);
var isWeatherBoxV2 = containerId === ‘home-weather-v2’;

Advertisement

function switchWeatherTab(tabName, clickedElement) {
container.querySelectorAll(‘[data-tab-id]’).forEach(function(tab) {
tab.classList.remove(‘open’);
tab.setAttribute(‘aria-selected’, ‘false’);
});

clickedElement.classList.add(‘open’);
clickedElement.setAttribute(‘aria-selected’, ‘true’);

container.querySelectorAll(‘[data-content-id]’).forEach(function(content) {
content.style.display = ‘none’;
content.setAttribute(‘hidden’, ‘true’);
});

var targetContent = container.querySelector(‘[data-content-id=”‘ + tabName + ‘”]’);
if (targetContent) {
targetContent.style.display = ‘block’;
targetContent.removeAttribute(‘hidden’);
}
}

function loadWeatherData() {
// If weather data is already being loaded, wait for it
if (window.weatherDataPromise) {
window.weatherDataPromise.then(function(data) {
if (data && data.data) {
var weatherContainer = container.closest(‘.weather-box-container’);
if (weatherContainer) {
weatherContainer.style.display = ‘flex’;
updateCurrentWeather(data.data);
updateForecastTabs(data.data);
updateWeatherAlertsBar(data.data);
}
}
});
return;
}

Advertisement

var location = { zip: window.DEFAULT_ZIPCODE };

try {
var storedLocations = localStorage.getItem(‘hrst.zip.history’);
if (storedLocations) {
var locations = JSON.parse(storedLocations);
if (locations && locations.length > 0) {
location = locations[0];
}
}
} catch (e) {}

var apiUrl = (window.DEWY_HOSTNAME || ”) + ‘/api/v1/weather/full/’ + location.zip;

if (window.fetch) {
window.weatherDataPromise = fetch(apiUrl)
.then(function(response) { return response.json(); })
.then(function(data) {
if (data && data.data) {
var article = container.closest(‘.article–wrapper’);
var weatherContainer = container.closest(‘.weather-box-container’);
if (weatherContainer) {
weatherContainer.style.display = ‘flex’;
updateCurrentWeather(data.data);
updateForecastTabs(data.data);
updateWeatherAlertsBar(data.data);
}
return data;
}
})
.catch(function(error) {
console.error(‘Error loading weather:’, error);
// Reset to unknown background on error
updateWeatherBackground(‘unknown’);
});
}
}

function updateWeatherAlertsBar(weatherData) {
var weatherWatchHeader = container.querySelector(‘.weather-watch-header’);
if (!weatherWatchHeader) return;

Advertisement

var weatherWatchText = weatherWatchHeader.querySelector(‘.weather-watch-text’);
var weatherWatchLink = weatherWatchHeader.querySelector(‘.weather-watch-link’);

if (weatherData.alerts_count > 0) {
weatherWatchHeader.className=”weather-watch-header has-alerts”;
if (weatherWatchText) {
weatherWatchText.textContent = `Weather Alerts (${weatherData.alerts_count})`;
}
if (weatherWatchLink) {
if (!weatherWatchLink.getAttribute(‘data-initial-href’)) {
weatherWatchLink.setAttribute(‘data-initial-href’, weatherWatchLink.getAttribute(‘href’));
weatherWatchLink.setAttribute(‘data-initial-onclick’, weatherWatchLink.getAttribute(‘onclick’) || ”);
}
weatherWatchLink.setAttribute(‘href’, “https://www.wbaltv.com/alerts”);
weatherWatchLink.setAttribute(‘onclick’, “return handleWeatherLinkClick(event, ‘click_alerts’, ‘click’, ‘mobile-weather’, “https://www.wbaltv.com/alerts”);”);
}
} else {
weatherWatchHeader.className=”weather-watch-header”;
if (weatherWatchText) {
weatherWatchText.textContent = containerId === ‘home-weather-v2’ ? ‘Watch Latest Forecast’ : ‘Latest Forecast’;
}
if (weatherWatchLink) {
var initialHref = weatherWatchLink.getAttribute(‘data-initial-href’);
var initialOnclick = weatherWatchLink.getAttribute(‘data-initial-onclick’);
if (initialHref) {
weatherWatchLink.setAttribute(‘href’, initialHref);
}
if (initialOnclick) {
weatherWatchLink.setAttribute(‘onclick’, initialOnclick);
}
}
}
}

function updateCurrentWeather(weatherData) {
if (weatherData.current) {
var tempValue = weatherData.current.temp_f || ”;
var skyValue = weatherData.current.sky || ”;
var feelsLikeValue = weatherData.current.feels_like_f || weatherData.current.temp_f || ”;

var tempEl = container.querySelector(‘.weather-grid–current-temp-value’);
if (tempEl) {
tempEl.textContent = tempValue;
tempEl.setAttribute(‘aria-label’, tempValue + ‘ degrees Fahrenheit’);
}

var iconEl = container.querySelector(‘.weather-grid–current-icon’);
if (iconEl && weatherData.current.icon_name) {
iconEl.className=”weather-grid–current-icon weather-current-icon icon icon-weather-” + weatherData.current.icon_name;
}

Advertisement

var skyEl = container.querySelector(‘.weather-grid–sky’);
if (skyEl) {
skyEl.textContent = skyValue;
skyEl.setAttribute(‘aria-label’, ‘Current condition: ‘ + skyValue);
}

var feelsEl = container.querySelector(‘.weather-grid–feels’);
if (feelsEl) {
feelsEl.textContent = feelsLikeValue + ‘°F’;
feelsEl.setAttribute(‘aria-label’, feelsLikeValue + ‘ degrees Fahrenheit’);
}

var weatherContainer = container.querySelector(‘.weather-temp-container’);
if (weatherContainer) {
var summary = ‘Current temperature ‘ + tempValue + ‘ degrees Fahrenheit, ‘ +
skyValue + ‘, feels like ‘ + feelsLikeValue + ‘ degrees’;
weatherContainer.setAttribute(‘aria-label’, summary);
}

updateWeatherBackground(weatherData.current.icon_name);
}
}

function updateWeatherBackground(iconName) {
try {
var bgPath = weatherImages.backgrounds[iconName] || weatherImages.backgrounds.unknown;
container.style.backgroundImage=”url(” + bgPath + ‘)’;
} catch (e) {
console.log(‘Error updating weather background:’, e);
}
}

Advertisement

function updateForecastTabs(weatherData) {
var visibleItems = isWeatherBoxV2 ? 6 : 5;

if (weatherData.hourly) {
var hourlyContainer = container.querySelector(‘.weather-hourly-forecast’);
if (hourlyContainer) {
var html=””;
var maxHours = Math.min(visibleItems, weatherData.hourly.length);

for (var i = 0; i 0 ? currentIndex – 1 : tabs.length – 1;
tabs[prevIndex].focus();
break;
case ‘ArrowRight’:
e.preventDefault();
var nextIndex = currentIndex

`;
}

function refreshWeatherIframe(containerId) {
var iframeId = ‘weather-iframe-‘ + containerId;
var iframe = document.getElementById(iframeId);
if (iframe && iframe.src) {
var originalSrc = iframe.src;
iframe.src = originalSrc + (originalSrc.indexOf(‘?’) > -1 ? ‘&’ : ‘?’) + ‘t=” + Date.now();
}
}

Advertisement

function initializeWeatherBox(container) {
var containerId = container.getAttribute(“data-container-id’);
var isWeatherBoxV2 = containerId === ‘home-weather-v2’;

function switchWeatherTab(tabName, clickedElement) {
container.querySelectorAll(‘[data-tab-id]’).forEach(function(tab) {
tab.classList.remove(‘open’);
tab.setAttribute(‘aria-selected’, ‘false’);
});

clickedElement.classList.add(‘open’);
clickedElement.setAttribute(‘aria-selected’, ‘true’);

container.querySelectorAll(‘[data-content-id]’).forEach(function(content) {
content.style.display = ‘none’;
content.setAttribute(‘hidden’, ‘true’);
});

var targetContent = container.querySelector(‘[data-content-id=”‘ + tabName + ‘”]’);
if (targetContent) {
targetContent.style.display = ‘block’;
targetContent.removeAttribute(‘hidden’);
}
}

Advertisement

function loadWeatherData() {
// If weather data is already being loaded, wait for it
if (window.weatherDataPromise) {
window.weatherDataPromise.then(function(data) {
if (data && data.data) {
var weatherContainer = container.closest(‘.weather-box-container’);
if (weatherContainer) {
weatherContainer.style.display = ‘flex’;
updateCurrentWeather(data.data);
updateForecastTabs(data.data);
updateWeatherAlertsBar(data.data);
}
}
});
return;
}

var location = { zip: window.DEFAULT_ZIPCODE };

try {
var storedLocations = localStorage.getItem(‘hrst.zip.history’);
if (storedLocations) {
var locations = JSON.parse(storedLocations);
if (locations && locations.length > 0) {
location = locations[0];
}
}
} catch (e) {}

var apiUrl = (window.DEWY_HOSTNAME || ”) + ‘/api/v1/weather/full/’ + location.zip;

if (window.fetch) {
window.weatherDataPromise = fetch(apiUrl)
.then(function(response) { return response.json(); })
.then(function(data) {
if (data && data.data) {
var article = container.closest(‘.article–wrapper’);
var weatherContainer = container.closest(‘.weather-box-container’);
if (weatherContainer) {
weatherContainer.style.display = ‘flex’;
updateCurrentWeather(data.data);
updateForecastTabs(data.data);
updateWeatherAlertsBar(data.data);
}
return data;
}
})
.catch(function(error) {
console.error(‘Error loading weather:’, error);
// Reset to unknown background on error
updateWeatherBackground(‘unknown’);
});
}
}

Advertisement

function updateWeatherAlertsBar(weatherData) {
var weatherWatchHeader = container.querySelector(‘.weather-watch-header’);
if (!weatherWatchHeader) return;

var weatherWatchText = weatherWatchHeader.querySelector(‘.weather-watch-text’);
var weatherWatchLink = weatherWatchHeader.querySelector(‘.weather-watch-link’);

if (weatherData.alerts_count > 0) {
weatherWatchHeader.className=”weather-watch-header has-alerts”;
if (weatherWatchText) {
weatherWatchText.textContent = `Weather Alerts (${weatherData.alerts_count})`;
}
if (weatherWatchLink) {
if (!weatherWatchLink.getAttribute(‘data-initial-href’)) {
weatherWatchLink.setAttribute(‘data-initial-href’, weatherWatchLink.getAttribute(‘href’));
weatherWatchLink.setAttribute(‘data-initial-onclick’, weatherWatchLink.getAttribute(‘onclick’) || ”);
}
weatherWatchLink.setAttribute(‘href’, “https://www.wbaltv.com/alerts”);
weatherWatchLink.setAttribute(‘onclick’, “return handleWeatherLinkClick(event, ‘click_alerts’, ‘click’, ‘sidelist-weather’, “https://www.wbaltv.com/alerts”);”);
}
} else {
weatherWatchHeader.className=”weather-watch-header”;
if (weatherWatchText) {
weatherWatchText.textContent = containerId === ‘home-weather-v2’ ? ‘Watch Latest Forecast’ : ‘Latest Forecast’;
}
if (weatherWatchLink) {
var initialHref = weatherWatchLink.getAttribute(‘data-initial-href’);
var initialOnclick = weatherWatchLink.getAttribute(‘data-initial-onclick’);
if (initialHref) {
weatherWatchLink.setAttribute(‘href’, initialHref);
}
if (initialOnclick) {
weatherWatchLink.setAttribute(‘onclick’, initialOnclick);
}
}
}
}

function updateCurrentWeather(weatherData) {
if (weatherData.current) {
var tempValue = weatherData.current.temp_f || ”;
var skyValue = weatherData.current.sky || ”;
var feelsLikeValue = weatherData.current.feels_like_f || weatherData.current.temp_f || ”;

var tempEl = container.querySelector(‘.weather-grid–current-temp-value’);
if (tempEl) {
tempEl.textContent = tempValue;
tempEl.setAttribute(‘aria-label’, tempValue + ‘ degrees Fahrenheit’);
}

Advertisement

var iconEl = container.querySelector(‘.weather-grid–current-icon’);
if (iconEl && weatherData.current.icon_name) {
iconEl.className=”weather-grid–current-icon weather-current-icon icon icon-weather-” + weatherData.current.icon_name;
}

var skyEl = container.querySelector(‘.weather-grid–sky’);
if (skyEl) {
skyEl.textContent = skyValue;
skyEl.setAttribute(‘aria-label’, ‘Current condition: ‘ + skyValue);
}

var feelsEl = container.querySelector(‘.weather-grid–feels’);
if (feelsEl) {
feelsEl.textContent = feelsLikeValue + ‘°F’;
feelsEl.setAttribute(‘aria-label’, feelsLikeValue + ‘ degrees Fahrenheit’);
}

var weatherContainer = container.querySelector(‘.weather-temp-container’);
if (weatherContainer) {
var summary = ‘Current temperature ‘ + tempValue + ‘ degrees Fahrenheit, ‘ +
skyValue + ‘, feels like ‘ + feelsLikeValue + ‘ degrees’;
weatherContainer.setAttribute(‘aria-label’, summary);
}

updateWeatherBackground(weatherData.current.icon_name);
}
}

Advertisement

function updateWeatherBackground(iconName) {
try {
var bgPath = weatherImages.backgrounds[iconName] || weatherImages.backgrounds.unknown;
container.style.backgroundImage=”url(” + bgPath + ‘)’;
} catch (e) {
console.log(‘Error updating weather background:’, e);
}
}

function updateForecastTabs(weatherData) {
var visibleItems = isWeatherBoxV2 ? 6 : 5;

if (weatherData.hourly) {
var hourlyContainer = container.querySelector(‘.weather-hourly-forecast’);
if (hourlyContainer) {
var html=””;
var maxHours = Math.min(visibleItems, weatherData.hourly.length);

for (var i = 0; i 0 ? currentIndex – 1 : tabs.length – 1;
tabs[prevIndex].focus();
break;
case ‘ArrowRight’:
e.preventDefault();
var nextIndex = currentIndex

Loading more articles…

Advertisement



Source link

Continue Reading

Trending