summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Merge remote-tracking branch 'origin/5.15' into devQt Forward Merge Bot2019-12-09528-4388/+6537
|\ | | | | | | Change-Id: Ia24cc8b86def0d9d9c17d6775cc519e491b860b1
| * QMetaType: add more static-less APIOlivier Goffart2019-12-073-2/+84
| | | | | | | | | | | | | | | | | | | | | | | | | | | | In prevision to Qt6 which is going to discourrage the use of the integer id, add some missing API to the staticless QMetaType API: - Add a way to construct a QMetaType from a type without calling qMetaTypeId: QMetaType::fromType<T>() - Add equality operators - Add a QMetaType::name() function - Add a default constructor (by adding a default parameter to the existing ctor) Change-Id: I95487c1c31bdf0d773717daa9d5452cbced30673 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
| * Tidy nullptr usageAllan Sandfeld Jensen2019-12-06502-4329/+4329
| | | | | | | | | | | | | | | | | | | | | | Move away from using 0 as pointer literal. Done using clang-tidy. This is not complete as run-clang-tidy can't handle all of qtbase in one go. Change-Id: I1076a21f32aac0dab078af6f175f7508145eece0 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
| * QByteArray: add a strict mode to fromBase64Giuseppe D'Angelo2019-12-054-84/+461
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QByteArray::fromBase64 was liberal in its input, simply skipping over invalid characters. As a side-effect of this, it had no error reporting, meaning it could not be used to convert fromBase64 _and_ validate the input in one go. Add more option flags to make fromBase64 strictly validate its input. Since we want to know whether it has succeeded or not, and the existing fromBase64 overloads do not allow for that, introduce a new function that returns an optional-like datatype. While at it: base64 decoding can be done in-place; add an rvalue overload to enable this use case. [ChangeLog][QtCore][QByteArray] Added the new fromBase64Encoding function. [ChangeLog][QtCore][QByteArray] Added new flags to make fromBase64 / fromBase64Encoding strictly validate their input, instead of skipping over invalid characters. Change-Id: I99cd5f2230f3d62970b28b4cb102913301da6ccd Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
| * Fix compile with we use QT_DISABLE_DEPRECATED_BEFORE=0x060000 in appsLaurent Montel2019-12-051-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | in qt5.15 you deprecated iterator &operator--() in qhash but QDataStream needs it. (see writeAssociativeContainer) So when we compile without deprecated method we can see: qdatastream.h:333:9: error: no match for ‘operator--’ (operand type is ‘QHash<QString, QImage>::const_iterator’) 333 | --it; | ^~~~ The current code is only QHash<QString, QImage> m_images; QDataStream stream(&file); stream << m_images; Change-Id: I12e61c0c60615455ac1eeff02969f155edb12e56 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
| * Don't use QHash::unite to merge hashesLars Knoll2019-12-051-1/+1
| | | | | | | | | | | | | | | | | | QHash::unite can silently turn a regular QHash into a multi hash, something that is not intended here. Use a regular insert() instead. Change-Id: I9244a8553e84eed5367939019347b51491765ea0 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
| * Add QHash::insert(const QHash &other)Lars Knoll2019-12-053-0/+111
| | | | | | | | | | | | | | | | | | | | As opposed to unite(), this inserts one hash into the other without duplicating elements. Change-Id: Ifc786c48f5dc3ab18c29782e73eac3c1a3ef8981 Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
| * QDoubleValidator: Fix thousand separator handlingFabian Kosmale2019-12-052-1/+2
| | | | | | | | | | | | | | | | | | | | | | QDoubleValidator would accept "1,23" as valid in a locale which has ',' as a thousand separator. However, it should have been Intermediate instead, as there is still one digit missing. Fixes: QTBUG-75110 Change-Id: I6de90f0b6f1eae95dc8dfc8e5f9658e482e46db3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
| * QGraphicsItem: Fix mouse tracking with modal panelsPaul Olav Tvete2019-12-051-2/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes the case where a mouse tracking item is added to the scene while a modal panel is blocking. In order to optimize event delivery, mouse tracking is enabled for the view only when an item that needs it is added. This means that we cannot use itemAcceptsHoverEvents_helper(), since that returns whether the item _currently_ needs hover events, and we need to know whether it will need them in the future. [ChangeLog][QtWidgets][QGraphicsView] Fixed a bug where hover events would not be delivered if the item was added while blocked by a modal panel. Fixes: QTBUG-77233 Change-Id: Ifc95869f2cc9c8c048330928ef8a13cd27cfd0f9 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Andreas Aardal Hanssen <andreas@hanssen.name>
| * RHI: new native texture APIPaul Olav Tvete2019-12-0514-4/+276
| | | | | | | | | | | | | | | | | | | | | | | | The new version takes/returns a value that can be unpacked and passed to other functions without knowing which backend is in use. The old API will be removed in a later change when dependent modules have been updated Task-number: QTBUG-78570 Change-Id: I18d928ceef3cb617c0c509ecccb345551a7990af Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
| * Deprecate QVariant::operator< and related operatorsOlivier Goffart2019-12-052-4/+20
| | | | | | | | | | | | | | | | | | | | | | Since the operator does not have a total order, it is kind of pointless, and this is going to be removed in Qt6 Change-Id: I754be059726bf30993550a2d753f8b865f2d4a5f Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
* | Use QString::DataPointer instead of QStringPrivateLars Knoll2019-12-085-15/+16
| | | | | | | | | | | | | | | | Preparations to move QString over to use QArrayDataPointer instead of it's own private struct. Change-Id: I7796a595393394083f6a85863e3c710ebbdea149 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* | Use QArrayDataPointer to implement QByteArrayLars Knoll2019-12-086-178/+129
| | | | | | | | | | Change-Id: I2ee28023c2dea9fc3160400112c59a47566a4868 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Use the QByteArray::DataPointer typedef instead of QByteArrayDataLars Knoll2019-12-087-15/+15
| | | | | | | | | | | | | | | | The goal here is to move things over to QArrayDataPointer. This prepares for it. Change-Id: I32f54a47594274799600c618f7341c200ceaa306 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Fix out of bounds read in tst_qsqlqueryLars Knoll2019-12-081-2/+3
| | | | | | | | | | Change-Id: I87962a17b13d212fa7fcc30bcd40174f2a7cded0 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* | Get rid of QCharRef and QByteRefLars Knoll2019-12-0811-347/+25
| | | | | | | | | | | | | | | | | | | | We already detach immediately since change c2d2757bccc68e1b981df059786c2e76f2969530. That basically removes the main purpose of having QChar/ByteRef, and we can just as well get rid of those classes for Qt 6. Change-Id: I8dc566a1948ddc29c0cb8a77ec7310654a7219a4 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Use <type_traits> to properly have QVector<T>::parameter_typeThiago Macieira2019-12-084-42/+24
| | | | | | | | | | | | | | | | | | | | | | | | That allows us to pass by value for all fundamental and pointer types. This requires some magic to remove methods taking a T&& to avoid ambiguous overloads for QVector<int/qsizetype>. Remove them for all cases where parameter_type is T, as copying or moving will do exactly the same thing for those types. Change-Id: I8133fecd3ac29bb8f6ae57376e680bc3d616afbf Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Optimize QArrayDataOps::compare for primitive typesLars Knoll2019-12-081-0/+5
| | | | | | | | | | Change-Id: If726e3ee8a3635dcec2a316f1a829392de298634 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Enlarge QVariant's private to fit the new QString and QByteArrayThiago Macieira2019-12-082-3/+3
| | | | | | | | | | Change-Id: I8baecd0a4db13200b34cdd7c8aebc2a1cc0a0c75 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Final removal of the size and offset members from QArrayDataThiago Macieira2019-12-085-60/+13
| | | | | | | | | | | | | | | | Those members are not required anymore and now part of the object itself. Change-Id: If9eb5355ca8f2cf9528f6f63ca4e172acc9f9aed Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Inline the size and data pointers in QByteArrayThiago Macieira2019-12-089-395/+343
| | | | | | | | | | Change-Id: I82feeb2c9bd2900f421fc0c8d78698b1e83db043 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Change representation of string data in the meta objectLars Knoll2019-12-086-39/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | Don't store our string data as QByteArrayLiterals anymore, but revert back to simply storing them as an array of char* and offsets into that array. This is required to be able to inline size and begin into QByteArray itself. Once that change is done, we can then avoid creating copies of the string data again. Change-Id: I362a54581caefdb1b3da4a7ab922d37e2e63dc02 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Inline the size and data pointer members in QStringThiago Macieira2019-12-087-303/+313
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I'd have preferred to use QArrayDataPointer<ushort> for QString, but that option wasn't the best one. QArrayDataPointer try to do some operations using QArrayDataOps and that would expand to unnecessary code. What's more, the existing code expected to be able to modify and access the d pointer. Instead, this commit introduces QStringPrivate (named differently from QStringData to catch potential users), which contains the three members. This POD class is also used in QJsonValue to store the "inlined" QString. QHashedString in qtdeclarative will need a similar solution. Change-Id: I33f072158e6e2cd031d4d2ffc81f4a8dbaf4e616 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Inline the size and begin pointer in QVectorThiago Macieira2019-12-089-652/+439
| | | | | | | | | | | | | | | | | | | | | | Add QGenericArray to simplify operations. This class can be shared by other tool classes. If there is nothing else to share it, we can move the code onto qvector.h. The one candidate is QList. All tests pass and valgrind is good. Change-Id: Ieaa80709caf5f50520aa97312ab726396f5475eb Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Fix potential out of bounds write in the JSON writerLars Knoll2019-12-081-1/+2
| | | | | | | | | | | | | | | | | | If a small string (1 or 2 chars) would require a JSON escape sequence when writing out the string, the code could write out of bounds of the byte array. Fix that by always allocating at least 16 bytes of space. Change-Id: I4d023e7ed837b25b0a5dcf6cfaaf94aa55695b9f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* | Get rid of the operator[](uint) overloadsLars Knoll2019-12-084-35/+0
| | | | | | | | | | | | | | | | Those make no sense and where probably only there to workaround bugs in some old compilers. Change-Id: I5b196cc5306ac1c6307257b70179278d82d383c1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* | Various cleanups in qarraydataops and qarraydatapointerThiago Macieira2019-12-082-87/+304
| | | | | | | | | | | | | | | | Various cleanups. Add copyAppend overload for forward iterators and a insert overload for inserting n elements. Change-Id: Ic41cd20818b8307e957948d04ef6379368defa55 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Remove bad test in QVectorThiago Macieira2019-12-081-83/+0
| | | | | | | | | | | | | | | | | | | | | | This test hardcodes the allocation behaviour instead of testing what it should be testing. Unfortunately, it can't test the actual problem directly since the problem was "it crashed when using vectors with 1 billion elements". Change-Id: Iec6a26ae490b8fdd4a7db1269e3bae85fc77ee52 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Start moving QArrayData's size and data pointer to the main classThiago Macieira2019-12-089-243/+268
| | | | | | | | | | | | | | | | | | | | | | | | | | This requires that the allocation functions return two pointers: the d pointer and the pointer to the actual data. Ported QArrayDataPointer & SimpleVector to the inlined size & data. For now, the size and offset members are not yet removed from QArrayData, to let QVector, QByteArray and QString compile unmodified. Change-Id: I8489300976723d75b8fd5831427b1e2bba486196 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Add QArrayDataOps::moveAppend()Thiago Macieira2019-12-081-0/+56
| | | | | | | | | | | | | | Same as copyAppend() but calls the move constructor Change-Id: I7de033f80b0e4431b7f1ffff13f9399e39b5fee4 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Add the QArrayDataOps::parameter_type typedefThiago Macieira2019-12-081-2/+6
| | | | | | | | | | | | | | | | | | It's a typedef meant to replace the "const T &" parameters (hence the name). But it's actually just a T for POD types, so we don't create references to them. Change-Id: I10c746d5e852c957ec84319712597478c4dc872c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Stop using the reference counter to store data stateThiago Macieira2019-12-087-39/+47
| | | | | | | | | | | | | | | | | | | | | | Instead of using the reference count to store whether the data is sharable and whether the header is immutable, move the settings to the flags member. This allows us to save one comparison per deref() or needsDetach(). It also allows for the possibility of mutable data pointed to by a static header. Change-Id: Ie678a2ff2bb9bce73497cb6138b431c465b0f3bb Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Add reference-count manipulation functions to QArrayData and hide refThiago Macieira2019-12-0816-107/+124
| | | | | | | | | | | | | | | | The next change will stop using some values in the reference counter as settings from the data. Change-Id: I94df1fe643896373fac2f000fff55bc7708fc807 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Introduce the Mutable flag and move QArrayDataPointer::needsDetachThiago Macieira2019-12-0810-43/+54
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Mutable flag now contains the information on whether the data this QArrayData points to is mutable. This decouples the mutability / immutability setting from the allocation and from the type of data, opening the way for mutable raw or foreign data. There are still plenty of places in the source code that check the size of the allocation when it actually wants d->isMutable(). Fixing this will require reviewing all the code, so is left for later. The needsDetach() function is moved to QArrayData and de-constified. It returns true when a reallocation is necessary if the data is to be modified. Change-Id: I17e2bc5a3f6ef1f3eba8a205acd9852b95524f57 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Make the AllocOptions flag to QVector::reallocData mandatoryThiago Macieira2019-12-081-8/+12
| | | | | | | | | | | | | | This forces us to calculate the reallocation flags properly. Change-Id: I3486b193ad6732df666fc9ddad96831c9fbe068c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Fix a use-after-free problem in QByteArray::replaceLars Knoll2019-12-071-3/+3
| | | | | | | | | | | | | | | | | | | | if the string pointed to by after is part of the QByteArray, we were trying to protect against a use-after-free by copying after. Unfortunately, it was not used later on in the code instead of the original after. Change-Id: I2f2263e4bb1855e802bba2fc08db34762c66887a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Remove unused private methodLars Knoll2019-12-071-102/+0
| | | | | | | | | | Change-Id: I3502c3c0451e7829fff0159a5d0891df34d04fe7 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* | Introduce flags to indicate the QArrayData typeThiago Macieira2019-12-078-62/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These flags allow us to determine what type of data QArrayData is carrying. There are currently only two supported types: - raw data type: constructed via fromRawData or static data - allocated data type: regular data done via heap allocation The QArrayData object is usually allocated on the heap, unless its own reference count is -1 (indicating static const QArrayData). Such object should have a type of RawDataType, since we can't call free(). Add GrowsBackward for completeness as well as the StaticDataFlags default for static data. Change-Id: Icc915a468a2acf2eae91a94e82451f852d382c92 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Introduce QArrayData::allocatedCapacity() and use it instead of d->allocThiago Macieira2019-12-0710-79/+90
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In almost all cases, use d->allocatedCapacity() or d->constAllocatedCapacity() instead of d->alloc, since they do the same thing (right now). In the future, the functions will be changed. There is a separate const version because most const code should not need to know the allocation size -- only mutating code should need to know that There are a few cases where d->alloc was replaced with a better alternative, like d->size. The one case that remains in the code will be replaced by a different test when it's available. Change-Id: I48135469db4caf150f82df93fff42d2309b23719 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Replace QArrayData::capacityReserved with a full flags fieldThiago Macieira2019-12-079-42/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | Instead of stealing one bit from the alloc field, let's use a full 32-bit for the flags. The first flag to be in the field is the CapacityReserved (even though the allocate() function will store some others there, not relevant for now). This is done in preparation for the need for more flags necessary anyway. Change-Id: I4c997d14743495e0d4558a6fb0a6042eb3d4975d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Rename QArrayData::AllocateOptions enum and update some flagsThiago Macieira2019-12-079-58/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rename to QArrayData::ArrayOptions in preparation for these flags being in the array itself, instead of used just for allocating new ones. For that reason, rename QArrayData::Default to DefaultAllocationFlags. And introduce QArray::DefaultRawFlags to mean the flags needed for creating a raw (static) QArrayData. Also rename QArrayData::Grow to GrowsForward, so we may add GrowsBackward in the future. Change-Id: I536d9b34124f775d53cf810f62d6b0eaada8daef Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Add QArrayData::sharedNullData()Thiago Macieira2019-12-071-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | Just to simplify a few operations, like detecting when a QChar* or char* coming from a QString or QByteArray, respectively, were null data. While you're not supposed to dereference the pointer returned by QVector::data() unless you know that the array is non-empty, that is permitted for QString and QByteArray. That is, QString().constData() must return a valid pointer to a null QChar. Change-Id: I80b4b62f203dc841e5c99c20c51d92ca576e4bfe Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Tell the compiler that QArrayData::allocate allocates memoryThiago Macieira2019-12-071-1/+5
| | | | | | | | | | | | | | | | | | | | ICC, GCC and Clang support __attribute__((malloc)) that tells them that the function returns newly allocated memory which doesn't alias anything else. Though technically we may return memory that has already been used (the shared null or such), that should not be a problem. Change-Id: Id3d5c7bf4d4c45069621ffff13f7f81f8b08ea3d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Tell the compiler that QArrayData returns aligned pointersThiago Macieira2019-12-071-4/+11
| | | | | | | | | | | | | | | | | | | | | | GCC 4.9 and later support the __attribute__((alloc_align)) attributes that indicate the alignment of the data. To make it work on GCC since 4.7 and Clang as of 3.6, we instead use __builtin_assume_aligned(). I don't know which version of ICC first implemented this, but ICC 15 does and it also reports itself as GCC 4.9. Change-Id: I58bd914b9bdd0ed3349ba56fa78220ab06114852 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* | Fix qChecksum testLars Knoll2019-12-071-5/+6
| | | | | | | | | | | | | | | | | | | | The test passed mostly by accident so far, as the created QByteArray was shorter than what the test assumed. Change-Id: I06858801d83a504eadc73ec2be281c88f8ffad5d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* | Use Q_NAMESPACE for the Qt namespace, and remove the old moc hack to support itOlivier Goffart2019-12-067-313/+326
| | | | | | | | | | | | | | | | | | | | Since I can't #include qobjectdefs from qnamespace because of circular dependency, move the Qt macro in the qtmetamacros.h header. Deprecate QObject::staticQtMetaObject since now one can just use Qt::staticMetaObject Change-Id: I11982aa17c2afa2067486b113f8052672f3695eb Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* | Fix tst_moc for C++17Olivier Goffart2019-12-064-118/+5
| | | | | | | | | | | | | | | | | | The throw() specification is no longer accepted in C++17 mode, so remove that. Also pass the -std=c++1z to the compiler as Qt is going to require C++17 soon Change-Id: I6d249e574d90cd1cf5c0ea595830d2db07681050 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* | Make setModel() virtualAndrew Patterson2019-12-061-1/+1
| | | | | | | | | | | | | | Task-number: QTBUG-74255 Change-Id: I354e547dd75019a964f4b8e4f087a72e610816f3 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* | Merge remote-tracking branch 'origin/5.15' into devQt Forward Merge Bot2019-12-0514-57/+130
|\| | | | | | | Change-Id: I9d63a4c4b229a831b5369f6ec74ac97ba6d6556a
| * Document that toggleViewAction can't be used to toggle the dock widgetVolker Hilsheimer2019-12-041-2/+5
| | | | | | | | | | | | | | | | | | | | | | ...from code. This is by design; the action is updated when the dock widget changes, not the other way around (which would easily result in infinite loops). Change-Id: I9e71784d239a9cbb6c8efaeaa3e3adc6dc590f65 Fixes: QTBUG-80022 Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>