* Fix data race in ProfileExManager
Parallel speed tests over many profiles corrupt the save queue of test results: IndexIdEnqueue touches a plain Queue<string> from every test thread, so Contains plus Enqueue race - the same profile gets queued twice, and Queue.Contains can even throw ArgumentOutOfRangeException out of SetTestDelay, losing the result. SaveQueueIndexIds has the same class of bug: it snapshots Count and then dequeues in a loop, so concurrent enqueues throw or lose entries. GetProfileExItem could create duplicate rows for the same index the same way.
Guard the queue and the profile lookup with a lock and drain a snapshot instead of a stale count. No behavior change besides correctness.
* Fix data race in ProfileExManager
Parallel speed tests over many profiles corrupt the save queue of test results: IndexIdEnqueue touches a plain Queue<string> from every test thread, so Contains plus Enqueue race - the same profile gets queued twice, and Queue.Contains can even throw ArgumentOutOfRangeException out of SetTestDelay, losing the result. SaveQueueIndexIds has the same class of bug: it snapshots Count and then dequeues in a loop, so concurrent enqueues throw or lose entries.
Switch the queue to ConcurrentQueue and drain it with TryDequeue. As suggested in review, duplicates are not filtered anymore: this is a helper, and the save loop just writes the same row more than once.
Fetch and display tested server IP and country (with emoji) in speed tests. Adds CountryExtension for country->emoji mapping and a new IpInfoResult type; ConnectionHandler now retrieves/parses IP API results and GetRealPingTime signature adjusted. Models and entities (ProfileItemModel, ProfileExItem, SpeedTestResult) gain IpInfo fields; ProfileExManager can store test IP info. UI/UX updated: new IpInfo column in ProfilesView (desktop and Avalonia), ResUI resource strings for "IP Info", and EServerColName ordering supports IpInfo. SpeedtestService now captures IP info and forwards it to the view model via the update function.