German Business Morale Surprises With Highest Result In Over Three Years
/*jshint esversion: 6 */
var socket;
var assigned_server = 3001;
var distributor_server = 3010;
var publisher_channel = '';
var broadcaster_channel = '';
var remote_ip = '';
var session_info = {};
var logging_interval;
var logging_interval_time = 120000;
var socket_emits = 0;
var session_start_time;
var reconnectionDelayGrowFactor = 1.2;
var reconnection_delay = 1000;
var playing = false;
var connected_to_assigned = false;
var socket_close_timeout;
var player_disconnected_annoucement_play_delay = 1500;
var player_disconnected_annoucement_play_timeout = null;
const TOKEN_ENDPOINT = "https://www.livesquawk.com/api/get_token.php";
self.onmessage = function (msg) {
switch(msg.data.action) {
case 'Reactivate': reactivate(); break;
case 'ConnectDistributor': connect_to_distributor(msg); break;
case 'SessionStaticInfo': session_static_info(msg); break;
case 'SessionInfo': update_session_info(msg.data); break;
case 'PauseLogging': clearTimeout(logging_interval); break;
case 'RestartLogging': postMessage({action: 'RequestSessionStaticInfo' }); break;
case 'JoinPublisherChannel': join_publisher_channel(msg.data); break;
case 'JoinPlayerChannel': join_player_channel(msg.data); break;
case 'CheckChannelStatus': check_channel_status(msg.data); break;
case 'PlayerLogResponse': player_log_response(msg.data); break;
case 'CloseSocket': close_socket(); break;
case 'RequestMessageSearch': request_message_search(msg.data); break;
case 'RequestMoreMessages': request_more_messages(msg.data); break;
case 'PlayerDisconnectedAnnoucementTimeoutStart': player_disconnected_annoucement_timeout_start(); break;
case 'PlayerDisconnectedAnnoucementTimeoutClear': player_disconnected_annoucement_timeout_clear(); break;
case 'GetConnectionState': checkSocketConnectionState(); break;
}
};
function player_disconnected_annoucement_timeout_clear() {
clearTimeout(player_disconnected_annoucement_play_timeout);
player_disconnected_annoucement_play_timeout = null;
}
function player_disconnected_annoucement_timeout_start() {
player_disconnected_annoucement_play_timeout = setTimeout(function() { send_play_disconnect_annoucement(); }, player_disconnected_annoucement_play_delay );
}
function send_play_disconnect_annoucement() {
postMessage({action: "PlayDisconnectAnnoucement"});
}
function reactivate() {
playing = false;
connect_to_assigned_server();
}
function player_log_response(data) {
var data_array = {};
data_array.type = 'PlayerLogResponse';
data_array.respond_to_socket_final = data.respond_to_socket_final;
data_array.respond_to_socket = data.respond_to_socket;
data_array.player_socket_id = data.player_socket_id;
data_array.logs = data.logs;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function request_message_search(data) {
var data_array = {};
data_array.type = 'request_message_search';
data_array.publisher_channel = data.publisher_channel;
data_array.search_term = data.search_term;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function request_more_messages(data) {
var data_array = {};
data_array.type = 'request_more_messages';
data_array.publisher_channel = data.publisher_channel;
data_array.last_record_id = data.last_record_id;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function check_channel_status(data) {
var data_array = {};
data_array.type = 'check_channel_status';
data_array.app_name = data.app_name;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1 && connected_to_assigned) { socket.send(msg_string); }
else { setTimeout(function() { check_channel_status(data); },500); }
}
function check_channel_status_response(data) {
postMessage({ action: 'CheckChannelStatusReponse', stream_status: data.stream_status.status, onair: data.stream_status.onair, connected: data.stream_status.connected });
}
async function join_publisher_channel(data) {
if (typeof data.jwt_token === 'string' && data.jwt_token !== '') {
if (!socket || socket.readyState !== WebSocket.OPEN) {
console.warn("[Page worker] JWT join skipped: socket not open");
return;
}
socket.send(JSON.stringify({
type: "join_publisher_channel",
jwt_token: data.jwt_token,
publisher_channel: data.publisher_channel,
username: data.username,
subscriber_group: data.subscriber_group,
display_name: data.display_name,
single_sign_on: data.single_sign_on,
remote_ip: data.remote_ip,
http_referrer: data.http_referrer,
current_page: data.current_page,
php_session_id: data.php_session_id,
from_react: data.from_react,
...(typeof data.api_key === "string" && data.api_key.trim() !== "" ? { api_key: data.api_key } : {}),
}));
console.log("[Page worker] Sent supplied JWT join");
postMessage({ action: 'PublisherChannelJoined' });
return;
}
const joinSocket = socket; if (!joinSocket || joinSocket.readyState !== WebSocket.OPEN) { return; }
const apiKey = typeof data.api_key === "string" ? data.api_key.trim() : "";
const partnerName = partnerFromCurrentPage(data.current_page);
let tokenBody;
if (apiKey !== "") { tokenBody = { api_key: apiKey }; }
else if (partnerName) { tokenBody = { partner_name: partnerName }; }
else { tokenBody = { username: data.username || "", publisher_channel: data.publisher_channel || "", }; }
let jwtToken = null;
try {
const requestStartedAt = Date.now();
const response = await fetch(TOKEN_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(tokenBody),
credentials: "same-origin",
cache: "no-store",
});
if (!response.ok) {
throw new Error(`token endpoint returned ${response.status}`);
}
const tokenData = await response.json();
if ( !tokenData || typeof tokenData.token !== "string" || tokenData.token === "" ) {
throw new Error("token endpoint returned no token");
}
const expiresIn = Number(tokenData.expires_in);
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
throw new Error("token endpoint returned an invalid lifetime");
}
const expiresAt = requestStartedAt + (expiresIn * 1000);
if (expiresAt <= Date.now() + 30000) {
throw new Error("token response has insufficient remaining lifetime");
}
jwtToken = tokenData.token;
}
catch (error) {
console.warn("[Page worker] Token request failed", error);
// API-key requests must not silently bypass token authentication.
if (apiKey !== "") { postMessage({ action: "auth_failed" }); return; }
}
// A reconnect during the fetch makes this join attempt obsolete.
if ( socket !== joinSocket || joinSocket.readyState !== WebSocket.OPEN ) { return; }
const payload = {
type: "join_publisher_channel",
publisher_channel: data.publisher_channel,
username: data.username,
subscriber_group: data.subscriber_group,
display_name: data.display_name,
single_sign_on: data.single_sign_on,
remote_ip: data.remote_ip,
http_referrer: data.http_referrer,
current_page: data.current_page,
php_session_id: data.php_session_id,
from_react: data.from_react,
};
if (apiKey !== "") { payload.api_key = apiKey; }
if (jwtToken) { payload.jwt_token = jwtToken; }
console.log( jwtToken ? "[Page worker] Sending fetched JWT with legacy details" : "[Page worker] Sending legacy join without JWT" );
joinSocket.send(JSON.stringify(payload));
postMessage({ action: "PublisherChannelJoined" });
}
function partnerFromCurrentPage(current_page) {
try {
if (!current_page) return '';
const fullUrl = current_page.startsWith('http') ? current_page : `https://${current_page}`;
return new URL(fullUrl).searchParams.get('partner_name') || '';
} catch (e) { return ''; }
}
function session_static_info(msg) {
set_static_session_info(msg.data);
start_log();
}
function connect_to_distributor(msg) {
publisher_channel = msg.data.publisher_channel;
remote_ip = msg.data.remote_ip;
socket = new WebSocket("wss://ws.livesquawk.com/ws"+distributor_server);
socket.onopen = function(event) { request_server_assignment(); };
socket.onmessage = function(event) {
var msg_string = event.data.toString();
var data = JSON.parse(msg_string);
switch(data.type) {
case 'server_assignment_response': server_assignment_response(data); break;
}
};
}
function session_info_interval() {
postMessage({action: 'RequestSessionInfo' });
logging_interval = setTimeout(session_info_interval,logging_interval_time);
}
function server_assignment_response(data) {
assigned_server = data.selected_server;
socket.close();
connect_to_assigned_server();
}
function request_server_assignment() {
var data_array = {};
data_array.type = 'request_server_assignment';
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function connect_to_assigned_server() {
socket = new WebSocket("wss://ws.livesquawk.com/ws"+assigned_server);
socket.onopen = function(event) {
postMessage({ action: 'VisibleConsole',console_string: "Connected to server "+assigned_server });
console.log("Connected to server "+assigned_server);
postMessage({ action: 'ConnectedToAssigned' });
connected_to_assigned = true;
if (playing) {
postMessage({ action: 'RejoinPlayerChannel' });
}
};
socket.onmessage = function(event) {
var msg_string = event.data.toString();
var data = JSON.parse(msg_string);
if (data.type != 'server_ping') { /* console.log(data.type); */ }
switch(data.type) {
case 'reconnect': postMessage({ action: 'VisibleConsole',console_string: "Reconnected" }); break;
case 'reload': postMessage({ action: 'Reload' }); break;
case 'start_log_response': start_log_response(data); break;
case 'application_refresh_start': application_refresh_start(data); break;
case 'application_refresh_stop': application_refresh_stop(data); break;
case 'player_log_request':
case 'check_channel_status_response': check_channel_status_response(data); break;
case 'PlayerLogRequest':
case 'new_tweet':
case 'new_latest_news':
case 'delete_report':
case 'add_report':
case 'add_ref_doc':
case 'calendar_change':
case 'calendar_insert':
case 'calendar_delete':
case 'new_note':
case 'AppStart':
case 'AppStop':
case 'BroadcasterStarted':
case 'BroadcasterStopped':
case 'added_cme_report':
case 'updated_cme_report':
case 'added_cme_commentary':
case 'updated_cme_commentary':
case 'server_assignment_response':
case 'initial_messages':
case 'message_categories':
case 'more_messages':
case 'matched_messages':
pass_straight_to_post_message(data);
break;
case 'output':
case 'server_ping':
case 'reconnect':
case 'disconnect':
break;
}
};
socket.onerror = function(event) {
postMessage({ action: 'VisibleConsole',console_string: "LS Socket Error" + event.type });
console.log(event);
postMessage({ action: 'LSSocketConnectionError' });
};
socket.onclose = function(event) {
console.log('Socket is closed. Reconnect will be attempted in 1 second.', event.reason);
socket_close_timeout = setTimeout(connect_to_assigned_server, reconnection_delay);
reconnection_delay = reconnection_delay*reconnectionDelayGrowFactor;
connected_to_assigned = false;
};
}
function checkSocketConnectionState() {
postMessage({ action: 'SocketConnectionState', connected: Boolean(socket && socket.readyState === WebSocket.OPEN && connected_to_assigned ), });
}
function close_socket() {
clearTimeout(socket_close_timeout);
socket_close_timeout = null;
socket.onclose = function(event) {};
socket.onmessage = function(event) {};
socket.onerror = function(event) {};
socket.close(1000);
console.log('Socket Closed');
}
function pass_straight_to_post_message(data) {
data.action = data.type;
postMessage(data);
}
function join_player_channel(data) {
var data_array = {};
data_array.type = 'join_player_channel';
data_array.player_channel = data.player_channel;
data_array.remote_ip = data.remote_ip;
data_array.username = data.username;
data_array.app_name = data.app_name;
data_array.onair_status = data.onair_status;
data_array.http_referrer = data.http_referrer;
data_array.current_page = data.current_page;
data_array.php_session_id = data.php_session_id;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
postMessage({action: 'PlayerChannelJoined' });
playing = true;
}
function start_log_response(data) {
session_info.session_id = data.log_record_id;
session_info_interval();
}
function application_refresh_start(data) {
if (data.app_name == session_info.application_name) { postMessage({action: 'ApplicationRefreshStart' }); }
}
function application_refresh_stop(data) {
if (data.app_name == session_info.application_name) { postMessage({action: 'ApplicationRefreshStop' }); }
}
function set_static_session_info(data) {
session_info.browser_codename = data.browser_codename;
session_info.browser_name = data.browser_name;
session_info.user_agent = data.user_agent;
session_info.browser_version = data.browser_version;
session_info.cookies_enabled = data.cookies_enabled;
session_info.platform = data.platform;
session_info.player_version = data.player_version;
session_info.stream = data.stream;
session_info.connection_protocol = data.protocol;
session_info.delay_target = data.delay_target;
session_info.session_email = data.session_email;
session_info.remote_ip = data.remote_ip;
session_info.php_session_id = data.php_session_id;
session_info.application_name = data.application_name;
session_info.http_referrer = data.http_referrer;
}
function start_log() {
var session_start_date = new Date();
session_start_time = session_start_date.getTime();
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var session_start_date_string = session_start_date.getDate() + " " + months[session_start_date.getMonth()] + " " + session_start_date.getFullYear();
var data_array = {};
data_array.type = 'webrtc_start_log';
data_array.remote_ip = session_info.remote_ip;
data_array.username = session_info.session_email;
data_array.php_session_id = session_info.php_session_id;
data_array.webrtc_protocol = '';
data_array.session_start_time = (session_start_time/1000).toFixed(0);
data_array.stream_name = session_info.stream;
data_array.session_start_date = session_start_date_string;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function update_session_info(data) {
var data_array = {};
var msg_string = '';
var current_date = new Date();
var current_time = current_date.getTime();
session_info.protocol = data.protocol;
session_info.curr_delay = (data.effective_latency / 1000).toFixed(2);
session_info.session_length = current_time - session_start_time;
session_info.ping_time = data.ping_time;
session_info.jitter = data.jitter;
session_info.packet_loss = data.packet_loss;
session_info.effective_latency = data.effective_latency;
session_info.mean_opinion_score = data.mean_opinion_score;
session_info.restarts = data.restarts;
if (socket_emits == 0) {
data_array = {};
data_array.type = 'webrtc_log_data_full';
data_array.connection_protocol = session_info.protocol;
data_array.threshold = 0;
data_array.curr_delay = session_info.curr_delay;
data_array.session_length = session_info.session_length;
data_array.date = current_time;
data_array.browser_codename = session_info.browser_codename;
data_array.browser_name = session_info.browser_name;
data_array.user_agent = session_info.user_agent;
data_array.browser_version = session_info.browser_version;
data_array.cookies_enabled = session_info.cookies_enabled;
data_array.platform = session_info.platform;
data_array.player_version = session_info.player_version;
data_array.stream = session_info.stream;
data_array.restarts = session_info.restarts;
data_array.delay_target = 0;
data_array.op_sys = '';
data_array.flash_version = '';
data_array.remote_ip = session_info.remote_ip;
data_array.http_referrer = session_info.http_referrer;
data_array.php_session_id = session_info.php_session_id;
data_array.user_email = session_info.session_email;
data_array.webrtc_protocol = session_info.protocol;
data_array.ping_time = session_info.ping_time;
data_array.jitter = session_info.jitter;
data_array.packet_loss = session_info.packet_loss;
data_array.effective_latency = session_info.effective_latency;
data_array.mean_opinion_score = session_info.mean_opinion_score;
data_array.session_id = session_info.session_id;
msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
else {
data_array = {};
data_array.type = 'webrtc_log_data';
data_array.session_id = session_info.session_id;
data_array.php_session_id = session_info.php_session_id;
data_array.connection_protocol = session_info.protocol;
data_array.restarts = session_info.restarts;
data_array.threshold = 0;
data_array.curr_delay = session_info.curr_delay;
data_array.session_length = session_info.session_length;
data_array.date = current_time;
data_array.webrtc_protocol = session_info.protocol;
data_array.ping_time = session_info.ping_time;
data_array.jitter = session_info.jitter;
data_array.packet_loss = session_info.packet_loss;
data_array.effective_latency = session_info.effective_latency;
data_array.mean_opinion_score = session_info.mean_opinion_score;
data_array.stream = session_info.stream;
msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
socket_emits++;
if (socket_emits == 100) { socket_emits = 0; }
}
- Outlook reading highest 2022
- Current situation reading slips
- Brent prices holding above USD 114/bbl
By Eric Culp, European Editor
LiveSquawk News
@eculp.bsky.social
@EricCulpLS
October 26 2026 | 10:00 GMT
FRANKFURT –– Confidence among business leaders in Europe’s largest economy has pushed to its strongest level since May 2023 even as energy prices remained high due to the Iran war.
Germany’s Ifo economics institute said Monday that its October survey of domestic companies showed an increase in its headline business climate index to 90.2 points versus the market estimate of 89.9, which was also the reading last month. It was the first time the measure exceeded 90 points in over three years, and the improvement continued the rebound from April, when the reading hit its lowest mark in nearly six years.
“The economic recovery is continuing,” the thinktank said, citing more confidence among manufacturing and construction companies. The mood of commercial firms was little changed, and service companies reported less satisfaction with their performance, Ifo said.
EUR/USD continued to trade just over 1.12 after the news. Brent crude remained above USD 114/bbl in early Monday trading, down from more than USD 117/bbl on Friday. The DAX took a bid on the report, rising nearly 0.9% versus Friday’s close.
Ifo said its October expectations component for the coming six months improved to 91.6 points, the highest since February 2022. The reading followed a market forecast for a decline to 90.0 and last month’s result of 90.4.
The current conditions measure also surprised analysts by easing to 88.8 points; economists had predicted a rise to 89.8 versus last month’s 89.5
Which way is Germany heading?
The results followed Friday’s mixed purchasing managers’ indices for Germany. Initial October data from S&P Global said the composite PMI for Germany sank to a two-month low of 52.8 points to remain in growth territory above the 50 mark. The services reading declined to 51.7, also a 2-month low. Manufacturing climbed to a two-month high of 54.2.
Compared to managers who responded to the Ifo poll, financial market experts last week offered an opposing view of the situation in Germany, namely that the current environment had improved and the outlook had dimmed.
Helaba noted that despite the improvement in Ifo’s forward-looking measure, “Germany’s economic outlook remains virtually unchanged, providing no reason to ramp up expectations regarding interest rate hikes by the ECB. The prevailing view in the market is that the ECB’s key interest rates will not be raised this week. Such a move is largely—though not entirely—already priced in for December.”
Sign up for LiveSquawk and receive a discount with the code LSQEC$