summaryrefslogtreecommitdiffstats
path: root/Include/methodobject.h
Commit message (Expand)AuthorAgeFilesLines
* Removed trailing whitespaces in miscalenous files.Serhiy Storchaka2015-04-031-2/+2
* Issue #22116: C functions and methods (of the 'builtin_function_or_method' ty...Antoine Pitrou2014-08-061-0/+1
* Revert back PyCFunction_New macro. Keep PyCFunction_NewEx usage in python cor...Andrew Svetlov2012-12-261-1/+1
* Issue #15422: get rid of PyCFunction_New macroAndrew Svetlov2012-12-251-1/+1
* Issue #14785: Add sys._debugmallocstats() to help debug low-level memory allo...David Malcolm2012-06-221-0/+5
* Reformat by replacing tabs with 4-spaces. Makes the code more PEP-7 compliantEli Bendersky2012-04-051-8/+8
* Issue #13577: Built-in methods and functions now have a __qualname__.Antoine Pitrou2011-12-231-1/+2
* Merge branches/pep-0384.Martin v. Löwis2010-12-031-0/+4
* #3247: get rid of Py_FindMethodAmaury Forgeot d'Arc2008-07-021-10/+0
* Oops, forgot that there are modules outside the win32 world.Amaury Forgeot d'Arc2008-07-021-0/+10
* #3247: Get rid of Py_FindMethod:Amaury Forgeot d'Arc2008-07-021-10/+0
* Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,...Christian Heimes2008-02-161-0/+2
* #1629: Renamed Py_Size, Py_Type and Py_Refcnt to Py_SIZE, Py_TYPE and Py_REFCNT.Christian Heimes2007-12-191-1/+1
* Get rid of METH_OLDARGS.Georg Brandl2007-09-011-1/+1
* Merged revisions 56467-56482 via svnmerge fromMartin v. Löwis2007-07-211-1/+1
* Completely get rid of PyClass and PyInstance.Guido van Rossum2006-08-171-1/+1
* Add const to several API functions that take char *.Jeremy Hylton2005-12-101-4/+4
* Wrote down the invariants of some common objects whose structure isArmin Rigo2004-10-281-7/+12
* * Added a new method flag, METH_COEXIST.Raymond Hettinger2003-12-131-0/+7
* Provide __module__ attributes for functions defined in C and Python.Jeremy Hylton2003-01-311-1/+4
* Excise DL_EXPORT from Include.Mark Hammond2002-08-121-8/+8
* Introduce two new flag bits that can be set in a PyMethodDef methodFred Drake2002-03-281-1/+7
* Remove much dead code from ceval.cJeremy Hylton2001-08-121-0/+5
* REMOVED all CWI, CNRI and BeOpen copyright markings.Guido van Rossum2000-09-011-9/+0
* Added #define for oldest version of argument callingAndrew M. Kuchling2000-08-031-0/+1
* Nuke all remaining occurrences of Py_PROTO and Py_FPROTO.Tim Peters2000-07-091-3/+3
* ANSI-fication and Py_PROTO extermination.Fred Drake2000-07-091-24/+22
* Change copyright notice - 2nd try.Guido van Rossum2000-06-301-6/+0
* Change copyright notice.Guido van Rossum2000-06-301-22/+7
* Add DL_IMPORT(returntype) for all officially exported functions.Guido van Rossum1998-12-041-6/+6
* Marc-Andre Lemburg's patch to move the typedef for PyCFunctionObjectGuido van Rossum1998-07-101-0/+15
* New permission notice, includes CNRI.Guido van Rossum1996-10-251-13/+20
* changes for keyword args to built-in functions and classesGuido van Rossum1995-07-261-1/+4
* make the type a parameter of the DL_IMPORT macro, for Borland CGuido van Rossum1995-02-271-1/+1
* added findmethodinchain and methodchain data typesGuido van Rossum1995-01-261-0/+8
* The great renaming, phase two: all header files have been updated toGuido van Rossum1995-01-121-13/+16
* added ml_doc and changed newmethodlist interfaceGuido van Rossum1995-01-071-4/+5
* Added 1995 copyright.Guido van Rossum1995-01-041-2/+6
* Changes for dynamic linking under NTGuido van Rossum1994-08-181-1/+1
* Merge alpha100 branch back to main trunkGuido van Rossum1994-08-011-1/+1
* * Added support for X11 modules.Guido van Rossum1993-07-281-0/+11
* * Changed all copyright messages to include 1993.Guido van Rossum1993-03-291-2/+2
* Copyright for 1992 addedGuido van Rossum1992-04-051-1/+1
* Add "varargs" attribute.Guido van Rossum1991-12-161-3/+5
* Added copyright notice.Guido van Rossum1991-02-191-0/+24
* "Compiling" versionGuido van Rossum1990-12-201-0/+7
* Initial revisionGuido van Rossum1990-10-141-0/+11
; + climbTree(insertVisitor, item->sceneBoundingRect()); +} + +void QGraphicsSceneBspTree::insertItems(const QList &items) +{ + foreach(QGraphicsItem *item, items) { + insertItem(item); + } } -void QGraphicsSceneBspTree::removeItem(QGraphicsItem *item, const QRectF &rect) +void QGraphicsSceneBspTree::removeItem(QGraphicsItem *item) { removeVisitor->item = item; - climbTree(removeVisitor, rect); + climbTree(removeVisitor, item->sceneBoundingRect()); } -void QGraphicsSceneBspTree::removeItems(const QSet &items) +void QGraphicsSceneBspTree::removeItems(const QList &items) { for (int i = 0; i < leaves.size(); ++i) { QList newItemList; @@ -302,7 +319,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con QRectF QGraphicsSceneBspTree::rectForIndex(int index) const { if (index <= 0) - return rect; + return sceneRect; int parentIdx = parentIndex(index); QRectF rect = rectForIndex(parentIdx); diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index e6ceb78..4114b3b 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -60,6 +60,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -69,7 +70,7 @@ class QGraphicsSceneInsertItemBspTreeVisitor; class QGraphicsSceneRemoveItemBspTreeVisitor; class QGraphicsSceneFindItemBspTreeVisitor; -class QGraphicsSceneBspTree +class QGraphicsSceneBspTree : public QGraphicsSceneIndex { public: struct Node @@ -87,10 +88,13 @@ public: void initialize(const QRectF &rect, int depth); void clear(); + QRectF rect() const; + void setRect(const QRectF &rect); - void insertItem(QGraphicsItem *item, const QRectF &rect); - void removeItem(QGraphicsItem *item, const QRectF &rect); - void removeItems(const QSet &items); + void insertItem(QGraphicsItem *item); + void insertItems(const QList &items); + void removeItem(QGraphicsItem *item); + void removeItems(const QList &items); QList items(const QRectF &rect); QList items(const QPointF &pos); @@ -116,7 +120,7 @@ private: QVector nodes; QVector > leaves; int leafCnt; - QRectF rect; + QRectF sceneRect; QGraphicsSceneInsertItemBspTreeVisitor *insertVisitor; QGraphicsSceneRemoveItemBspTreeVisitor *removeVisitor; @@ -130,6 +134,8 @@ public: virtual void visit(QList *items) = 0; }; +Q_DECLARE_TYPEINFO(QGraphicsSceneBspTree::Node, Q_PRIMITIVE_TYPE); + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index fe36fbd..aacbc40 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -132,7 +132,7 @@ public: bool purgePending; void _q_removeItemLater(QGraphicsItem *item); - QSet removedItems; + QList removedItems; void purgeRemovedItems(); QBrush backgroundBrush; diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index 5e825ba..bda6f5e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -69,9 +69,9 @@ public: virtual void clear() = 0; virtual void insertItem(QGraphicsItem *item) = 0; - virtual void insertItems(QList items) = 0; + virtual void insertItems(const QList &items) = 0; virtual void removeItem(QGraphicsItem *item) = 0; - virtual void removeItems(QList items) = 0; + virtual void removeItems(const QList &items) = 0; virtual QList items(const QRectF &rect) = 0; -- cgit v0.12 From 45c70c9834316f39a939b87450099560fd286a6e Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 7 Apr 2009 20:11:32 +0200 Subject: Fixes: Default implementation for QGraphicsSceneIndex::removeItems and QGraphicsSceneIndex::insertItems --- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 7 ------- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 1 - src/gui/graphicsview/qgraphicssceneindex.cpp | 13 +++++++++++++ src/gui/graphicsview/qgraphicssceneindex.h | 5 +++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index c295cb3..bf95893 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -133,13 +133,6 @@ void QGraphicsSceneBspTree::insertItem(QGraphicsItem *item) climbTree(insertVisitor, item->sceneBoundingRect()); } -void QGraphicsSceneBspTree::insertItems(const QList &items) -{ - foreach(QGraphicsItem *item, items) { - insertItem(item); - } -} - void QGraphicsSceneBspTree::removeItem(QGraphicsItem *item) { removeVisitor->item = item; diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index 4114b3b..a35148c 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -92,7 +92,6 @@ public: void setRect(const QRectF &rect); void insertItem(QGraphicsItem *item); - void insertItems(const QList &items); void removeItem(QGraphicsItem *item); void removeItems(const QList &items); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 7868388..d8c28ed 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -60,6 +60,19 @@ QGraphicsScene* QGraphicsSceneIndex::scene() return mscene; } +void QGraphicsSceneIndex::insertItems(const QList &items) +{ + foreach (QGraphicsItem *item, items) + insertItem(item); +} + +void QGraphicsSceneIndex::removeItems(const QList &items) +{ + foreach (QGraphicsItem *item, items) + removeItem(item); +} + + QT_END_NAMESPACE //#include "moc_qgraphicssceneindex.cpp" diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index bda6f5e..df398ae 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -69,9 +69,10 @@ public: virtual void clear() = 0; virtual void insertItem(QGraphicsItem *item) = 0; - virtual void insertItems(const QList &items) = 0; virtual void removeItem(QGraphicsItem *item) = 0; - virtual void removeItems(const QList &items) = 0; + + virtual void insertItems(const QList &items); + virtual void removeItems(const QList &items); virtual QList items(const QRectF &rect) = 0; -- cgit v0.12 From 600beb2a2ed1c3df581230c526f1e64b78112477 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Thu, 12 Mar 2009 16:08:24 +0100 Subject: Fixes: Mark the BSP tree class so we can autotest it. --- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index a35148c..ebcb402 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -70,7 +70,7 @@ class QGraphicsSceneInsertItemBspTreeVisitor; class QGraphicsSceneRemoveItemBspTreeVisitor; class QGraphicsSceneFindItemBspTreeVisitor; -class QGraphicsSceneBspTree : public QGraphicsSceneIndex +class Q_AUTOTEST_EXPORT QGraphicsSceneBspTree : public QGraphicsSceneIndex { public: struct Node -- cgit v0.12 From d5ab1562ea7b8ce8e94e8db9ea2a7fcab17f657f Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Thu, 12 Mar 2009 15:51:19 +0100 Subject: Fixes: Add a simple test for the scene index. Details: This is just the beginning. More complex tests follow. --- tests/auto/auto.pro | 1 + .../qgraphicssceneindex/qgraphicssceneindex.pro | 3 + .../tst_qgraphicssceneindex.cpp | 74 ++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro create mode 100644 tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 443ee7e..9bde383 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -140,6 +140,7 @@ SUBDIRS += bic \ qgraphicsitem \ qgraphicsitemanimation \ qgraphicsscene \ + qgraphicssceneindex \ qgraphicsview \ qgridlayout \ qgroupbox \ diff --git a/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro new file mode 100644 index 0000000..740a23e --- /dev/null +++ b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +SOURCES += tst_qgraphicssceneindex.cpp + diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp new file mode 100644 index 0000000..209e4be --- /dev/null +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include + +#include + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QGraphicsSceneIndex : public QObject +{ + Q_OBJECT +public slots: + void initTestCase(); + +private slots: + void sceneRect(); +}; + +void tst_QGraphicsSceneIndex::initTestCase() +{ +} + +void tst_QGraphicsSceneIndex::sceneRect() +{ + QGraphicsSceneIndex *index = new QGraphicsSceneBspTree; + index->setRect(QRectF(0, 0, 2000, 2000)); + QCOMPARE(index->rect(), QRectF(0, 0, 2000, 2000)); +} + +QTEST_MAIN(tst_QGraphicsSceneIndex) +#include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From 14785a965fc475d220ca8592c6ee4a44a0be25f6 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Mon, 16 Mar 2009 13:54:20 +0100 Subject: Fixes: Parametrize the test with potentially different indexing method. --- .../tst_qgraphicssceneindex.cpp | 28 +++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 209e4be..f2a2bf1 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -44,7 +44,6 @@ #include #include -#include //TESTED_CLASS= //TESTED_FILES= @@ -56,13 +55,40 @@ public slots: void initTestCase(); private slots: + void sceneRect_data(); void sceneRect(); + +private: + void common_data(); + QGraphicsSceneIndex *createIndex(const QString &name); }; void tst_QGraphicsSceneIndex::initTestCase() { } +void tst_QGraphicsSceneIndex::common_data() +{ + QTest::addColumn("indexMethod"); + + QTest::newRow("BSP") << QString("bsp"); +} + +QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMethod) +{ + QGraphicsSceneIndex *index = 0; + + if (indexMethod == "bsp") + index = new QGraphicsSceneBspTree; + + return index; +} + +void tst_QGraphicsSceneIndex::sceneRect_data() +{ + common_data(); +} + void tst_QGraphicsSceneIndex::sceneRect() { QGraphicsSceneIndex *index = new QGraphicsSceneBspTree; -- cgit v0.12 From 7b21055e3966ed8620586decaca4c30f9bf0823a Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Mon, 16 Mar 2009 13:57:05 +0100 Subject: Fixes: Autotest for changing the index method of a scene. --- .../qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index f2a2bf1..9372823 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -41,6 +41,7 @@ #include +#include #include #include @@ -57,6 +58,8 @@ public slots: private slots: void sceneRect_data(); void sceneRect(); + void customIndex_data(); + void customIndex(); private: void common_data(); @@ -96,5 +99,23 @@ void tst_QGraphicsSceneIndex::sceneRect() QCOMPARE(index->rect(), QRectF(0, 0, 2000, 2000)); } +void tst_QGraphicsSceneIndex::customIndex_data() +{ + common_data(); +} + +void tst_QGraphicsSceneIndex::customIndex() +{ + QFETCH(QString, indexMethod); + QGraphicsSceneIndex *index = createIndex(indexMethod); + + QGraphicsScene scene; + scene.setSceneIndex(index); + + scene.addRect(0, 0, 30, 40); + QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1); +} + + QTEST_MAIN(tst_QGraphicsSceneIndex) #include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From 7185361703e2837e4258b18350da791c84f7ef62 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Mon, 16 Mar 2009 13:58:02 +0100 Subject: Fixes: Autotest for inserting non-overlapped items in the scene index. --- .../tst_qgraphicssceneindex.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 9372823..cfe3ef0 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -60,6 +60,8 @@ private slots: void sceneRect(); void customIndex_data(); void customIndex(); + void scatteredItems_data(); + void scatteredItems(); private: void common_data(); @@ -116,6 +118,26 @@ void tst_QGraphicsSceneIndex::customIndex() QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1); } +void tst_QGraphicsSceneIndex::scatteredItems_data() +{ + common_data(); +} + +void tst_QGraphicsSceneIndex::scatteredItems() +{ + QFETCH(QString, indexMethod); + QGraphicsSceneIndex *index = createIndex(indexMethod); + + QGraphicsScene scene; + scene.setSceneIndex(index); + + for (int i = 0; i < 10; ++i) + scene.addRect(i*50, i*50, 40, 35); + + QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1); + QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 10); + QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0); +} QTEST_MAIN(tst_QGraphicsSceneIndex) #include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From 2a1ced292424501d3bf453f337f8ce9c8c17bda9 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Mon, 16 Mar 2009 15:07:06 +0100 Subject: Fixes: Initialize the BSP tree if it has not been initialized before. Details: The BSP tree internal to QGraphicsScene does need this as the scene does call initialize() at proper time. This fix is needed only for using the BSP tree as custom indexing and/or for autotest. --- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index bf95893..b73cba2 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -247,8 +247,10 @@ void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth, int index) void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) { - if (nodes.isEmpty()) - return; + if (nodes.isEmpty()) { + // should never happen for bsp tree internal to QGraphicsScene + initialize(sceneRect, 0); + } const Node &node = nodes.at(index); int childIndex = firstChildIndex(index); @@ -277,8 +279,10 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) { - if (nodes.isEmpty()) - return; + if (nodes.isEmpty()) { + // should never happen for bsp tree internal to QGraphicsScene + initialize(sceneRect, 0); + } const Node &node = nodes.at(index); int childIndex = firstChildIndex(index); -- cgit v0.12 From e30e12306c9cc834eada3ce07b32761748fa423a Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Mon, 16 Mar 2009 15:34:07 +0100 Subject: Fixes: Make some BSP tree functions as 'private'. --- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index ebcb402..a8c54f0 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -96,9 +96,13 @@ public: void removeItems(const QList &items); QList items(const QRectF &rect); - QList items(const QPointF &pos); + int leafCount() const; +private: + + QList items(const QPointF &pos); + inline int firstChildIndex(int index) const { return index * 2 + 1; } @@ -107,7 +111,6 @@ public: QString debug(int index) const; -private: void initialize(const QRectF &rect, int depth, int index); void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0); void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0); -- cgit v0.12 From 79257690c8fe8802e75a642138a2b466a0f54e65 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Thu, 12 Mar 2009 15:43:19 +0100 Subject: Fixes: Added linear scene index class. Not used yet. --- src/gui/graphicsview/graphicsview.pri | 1 + src/gui/graphicsview/qgraphicsscene_linear_p.h | 110 +++++++++++++++++++++ .../tst_qgraphicssceneindex.cpp | 5 + 3 files changed, 116 insertions(+) create mode 100644 src/gui/graphicsview/qgraphicsscene_linear_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index f0bdddc..bc4d9dd 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -7,6 +7,7 @@ HEADERS += \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ + graphicsview/qgraphicsscene_linear_p.h \ graphicsview/qgraphicssceneindex.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicsview_p.h \ diff --git a/src/gui/graphicsview/qgraphicsscene_linear_p.h b/src/gui/graphicsview/qgraphicsscene_linear_p.h new file mode 100644 index 0000000..1ef1902 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscene_linear_p.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENELINEARINDEX_P_H +#define QGRAPHICSSCENELINEARINDEX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex +{ +private: + QRectF m_sceneRect; + QList m_items; + +public: + QGraphicsSceneLinearIndex(): QGraphicsSceneIndex() { + } + + virtual void setRect(const QRectF &rect) { + m_sceneRect = rect; + } + + virtual QRectF rect() const { + return m_sceneRect; + } + + virtual void clear() { + m_items.clear(); + } + + virtual void insertItem(QGraphicsItem *item) { + m_items << item; + } + + virtual void removeItem(QGraphicsItem *item) { + m_items.removeAll(item); + } + + virtual QList items(const QRectF &rect) { + QList result; + foreach (QGraphicsItem *item, m_items) + if (item->sceneBoundingRect().intersects(rect)) + result << item; + return result; + } +}; + +QT_END_NAMESPACE + +#endif // QT_NO_GRAPHICSVIEW + +#endif // QGRAPHICSSCENELINEARINDEX_P_H diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index cfe3ef0..d199351 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -44,6 +44,7 @@ #include #include #include +#include //TESTED_CLASS= @@ -77,6 +78,7 @@ void tst_QGraphicsSceneIndex::common_data() QTest::addColumn("indexMethod"); QTest::newRow("BSP") << QString("bsp"); + QTest::newRow("Linear") << QString("linear"); } QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMethod) @@ -86,6 +88,9 @@ QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMe if (indexMethod == "bsp") index = new QGraphicsSceneBspTree; + if (indexMethod == "linear") + index = new QGraphicsSceneLinearIndex; + return index; } -- cgit v0.12 From ff2f96de0c71f53cc71902e8119c84aed9967226 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Tue, 17 Mar 2009 12:06:44 +0100 Subject: Fixes: New updateItem(s) function with default implementation (of removing and inserting) --- src/gui/graphicsview/qgraphicssceneindex.cpp | 11 +++++++++++ src/gui/graphicsview/qgraphicssceneindex.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index d8c28ed..cb84f6b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -60,6 +60,12 @@ QGraphicsScene* QGraphicsSceneIndex::scene() return mscene; } +void QGraphicsSceneIndex::updateItem(QGraphicsItem *item) +{ + removeItem(item); + insertItem(item); +} + void QGraphicsSceneIndex::insertItems(const QList &items) { foreach (QGraphicsItem *item, items) @@ -72,6 +78,11 @@ void QGraphicsSceneIndex::removeItems(const QList &items) removeItem(item); } +void QGraphicsSceneIndex::updateItems(const QList &items) +{ + foreach (QGraphicsItem *item, items) + updateItem(item); +} QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index df398ae..6246753 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -70,9 +70,11 @@ public: virtual void insertItem(QGraphicsItem *item) = 0; virtual void removeItem(QGraphicsItem *item) = 0; + virtual void updateItem(QGraphicsItem *item); virtual void insertItems(const QList &items); virtual void removeItems(const QList &items); + virtual void updateItems(const QList &items); virtual QList items(const QRectF &rect) = 0; -- cgit v0.12 From 6df288191c5b6de8c6d1f00fd931401dc9f0c342 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Tue, 17 Mar 2009 13:50:05 +0100 Subject: Fixes: Add API documentation for QGraphicsSceneIndex --- src/gui/graphicsview/qgraphicssceneindex.cpp | 80 ++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index cb84f6b..99d1b3b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -46,38 +46,118 @@ QT_BEGIN_NAMESPACE +/*! + Constructs an abstract scene index. +*/ QGraphicsSceneIndex::QGraphicsSceneIndex() { } +/*! + Destroys the scene index. +*/ QGraphicsSceneIndex::~QGraphicsSceneIndex() { } +/*! + \fn virtual void setRect(const QRectF &rect) = 0 + + This pure virtual function is called when the scene changes its bounding + rectangle. + + \sa rect(), QGraphicsScene::setSceneRect +*/ + +/*! + \fn virtual QRectF rect() const = 0 + + This pure virtual function returns the bounding rectangle of this + scene index. It could be as large as or larger than the scene + bounding rectangle, depending on the implementation of the + scene index. + + \sa setRect(), QGraphicsScene::sceneRect +*/ + +/*! + \fn virtual void clear() = 0 + + This pure virtual function removes all items in the scene index. +*/ + +/*! + \fn virtual void insertItem(QGraphicsItem *item) = 0 + + This pure virtual function inserts an item to the scene index. + + \sa removeItem(), updateItem(), insertItems() +*/ + +/*! + \fn virtual void removeItem(QGraphicsItem *item) = 0 + + This pure virtual function removes an item to the scene index. + + \sa insertItem(), updateItem(), removeItems() +*/ + +/*! + Returns the scene of this scene index. +*/ QGraphicsScene* QGraphicsSceneIndex::scene() { return mscene; } +/*! + Updates an item when its geometry has changed. + + The default implemention will remove the item from the index + and then insert it again. + + \sa insertItem(), removeItem(), updateItems() +*/ void QGraphicsSceneIndex::updateItem(QGraphicsItem *item) { removeItem(item); insertItem(item); } +/*! + Inserts a list of items to the index. + + The default implemention will insert the items one by one. + + \sa insertItem(), removeItems(), updateItems() +*/ void QGraphicsSceneIndex::insertItems(const QList &items) { foreach (QGraphicsItem *item, items) insertItem(item); } +/*! + Removes a list of items from the index. + + The default implemention will remove the items one by one. + + \sa removeItem(), removeItems(), updateItems() +*/ void QGraphicsSceneIndex::removeItems(const QList &items) { foreach (QGraphicsItem *item, items) removeItem(item); } +/*! + Update a list of items which have changed the geometry. + + The default implemention will update the items one by one. + + \sa updateItem(), insertItems(), removeItems() +*/ void QGraphicsSceneIndex::updateItems(const QList &items) { foreach (QGraphicsItem *item, items) -- cgit v0.12 From 8e13ebc41ccbf4d1ec6ba552f8865007db5af875 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Tue, 17 Mar 2009 14:56:04 +0100 Subject: Fixes: Add autotest for overlapped rectangles --- .../tst_qgraphicssceneindex.cpp | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index d199351..f03404e 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -63,6 +63,8 @@ private slots: void customIndex(); void scatteredItems_data(); void scatteredItems(); + void overlappedItems_data(); + void overlappedItems(); private: void common_data(); @@ -144,5 +146,32 @@ void tst_QGraphicsSceneIndex::scatteredItems() QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0); } +void tst_QGraphicsSceneIndex::overlappedItems_data() +{ + common_data(); +} + +void tst_QGraphicsSceneIndex::overlappedItems() +{ + QFETCH(QString, indexMethod); + QGraphicsSceneIndex *index = createIndex(indexMethod); + + QGraphicsScene scene; + scene.setSceneIndex(index); + + for (int i = 0; i < 10; ++i) + for (int j = 0; j < 10; ++j) + scene.addRect(i*50, j*50, 200, 200); + + QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 100); + QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0); + QCOMPARE(scene.items(QRectF(0, 0, 200, 200)).count(), 16); + QCOMPARE(scene.items(QRectF(0, 0, 100, 100)).count(), 4); + QCOMPARE(scene.items(QRectF(0, 0, 1, 100)).count(), 2); + QCOMPARE(scene.items(QRectF(0, 0, 1, 1000)).count(), 10); +} + + + QTEST_MAIN(tst_QGraphicsSceneIndex) #include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From 72f34ea254d2ad93e11f740bf2ed2523f1975ee9 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Tue, 17 Mar 2009 15:04:52 +0100 Subject: Fixes: Add autotest for moving rectangle between items. --- .../tst_qgraphicssceneindex.cpp | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index f03404e..9a01cb8 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -65,6 +65,8 @@ private slots: void scatteredItems(); void overlappedItems_data(); void overlappedItems(); + void movingItems_data(); + void movingItems(); private: void common_data(); @@ -171,6 +173,33 @@ void tst_QGraphicsSceneIndex::overlappedItems() QCOMPARE(scene.items(QRectF(0, 0, 1, 1000)).count(), 10); } +void tst_QGraphicsSceneIndex::movingItems_data() +{ + common_data(); +} + +void tst_QGraphicsSceneIndex::movingItems() +{ + QFETCH(QString, indexMethod); + QGraphicsSceneIndex *index = createIndex(indexMethod); + + QGraphicsScene scene; + scene.setSceneIndex(index); + + for (int i = 0; i < 10; ++i) + scene.addRect(i*50, i*50, 40, 35); + + QGraphicsRectItem *box = scene.addRect(0, 0, 10, 10); + QCOMPARE(scene.items(QRectF(0, 0, 5, 5)).count(), 2); + + box->setPos(10, 10); + QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 1); + + box->setPos(-5, -5); + QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 2); + + QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 11); +} QTEST_MAIN(tst_QGraphicsSceneIndex) -- cgit v0.12 From 22a3772006c34e51f446eb3ab1cfaf5e40cab583 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 17 Mar 2009 15:07:53 +0100 Subject: Fixes: Remove from the custom index too (this will change anyway) --- src/gui/graphicsview/qgraphicsscene.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8660853..77711ad 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -822,8 +822,13 @@ void QGraphicsScenePrivate::purgeRemovedItems() return; // Remove stale items from the BSP tree. - if (indexMethod != QGraphicsScene::NoIndex) - bspTree.removeItems(removedItems); + if (indexMethod != QGraphicsScene::NoIndex) { + if (indexMethod == QGraphicsScene::BspTreeIndex) { + bspTree.removeItems(removedItems); + } else { + customIndex->removeItems(removedItems); + } + } // Purge this list. removedItems.clear(); -- cgit v0.12 From 133bded765f224bce31d8abff87cc74a63569715 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 17 Mar 2009 17:26:26 +0100 Subject: Fixes: The bsp and customs index share the same pointer --- src/gui/graphicsview/qgraphicsscene.cpp | 66 ++++++++++++++++++--------------- src/gui/graphicsview/qgraphicsscene_p.h | 6 ++- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 77711ad..4070f11 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -331,7 +331,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() indexMethod(QGraphicsScene::BspTreeIndex), bspTreeDepth(0), lastItemCount(0), - customIndex(0), + index(new QGraphicsSceneBspTree()), hasSceneRect(false), updateAll(false), calledEmitUpdated(false), @@ -361,7 +361,11 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() style(0) { } - +QGraphicsScenePrivate::~QGraphicsScenePrivate() +{ + if (index) + delete index; +} /*! \internal */ @@ -388,13 +392,8 @@ QList QGraphicsScenePrivate::estimateItemsInRect(const QRectF & QGraphicsScenePrivate *that = const_cast(this); QList items; - if (indexMethod == QGraphicsScene::BspTreeIndex) { - // Get items from BSP tree - items = that->bspTree.items(rect); - } else { - //ask to the custom indexing - items = that->customIndex->items(rect); - } + // Get items from index + items = that->index->items(rect); // Fill in with any unindexed items for (int i = 0; i < unindexedItems.size(); ++i) { @@ -443,7 +442,7 @@ void QGraphicsScenePrivate::addToIndex(QGraphicsItem *item) { if (indexMethod == QGraphicsScene::BspTreeIndex) { if (item->d_func()->index != -1) { - bspTree.insertItem(item); + index->insertItem(item); foreach (QGraphicsItem *child, item->children()) child->addToIndex(); } else { @@ -454,7 +453,7 @@ void QGraphicsScenePrivate::addToIndex(QGraphicsItem *item) } } else if (indexMethod == QGraphicsScene::CustomIndex) { if (item->d_func()->index != -1) { - customIndex->insertItem(item); + index->insertItem(item); foreach (QGraphicsItem *child, item->children()) child->addToIndex(); } @@ -469,10 +468,7 @@ void QGraphicsScenePrivate::removeFromIndex(QGraphicsItem *item) if (indexMethod != QGraphicsScene::NoIndex) { int index = item->d_func()->index; if (index != -1) { - if (indexMethod == QGraphicsScene::CustomIndex) - customIndex->removeItem(item); - else - bspTree.removeItem(item); + this->index->removeItem(item); freeItemIndexes << index; indexedItems[index] = 0; item->d_func()->index = -1; @@ -551,7 +547,9 @@ void QGraphicsScenePrivate::_q_updateIndex() int oldDepth = intmaxlog(lastItemCount); depth = intmaxlog(indexedItems.size()); static const int slack = 100; - if (bspTree.leafCount() == 0 || (oldDepth != depth && qAbs(lastItemCount - indexedItems.size()) > slack)) { + //### do something better + QGraphicsSceneBspTree *bsp = static_cast(index); + if (bsp->leafCount() == 0 || (oldDepth != depth && qAbs(lastItemCount - indexedItems.size()) > slack)) { // ### Crude algorithm. regenerateIndex = true; } @@ -560,7 +558,9 @@ void QGraphicsScenePrivate::_q_updateIndex() // Regenerate the tree. if (regenerateIndex) { regenerateIndex = false; - bspTree.initialize(q->sceneRect(), depth); + //### do something better + QGraphicsSceneBspTree *bsp = static_cast(index); + bsp->initialize(q->sceneRect(), depth); unindexedItems = indexedItems; lastItemCount = indexedItems.size(); q->update(); @@ -578,10 +578,9 @@ void QGraphicsScenePrivate::_q_updateIndex() QRectF rect = item->sceneBoundingRect(); if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) continue; - if (indexMethod == QGraphicsScene::BspTreeIndex) - bspTree.insertItem(item); - if (indexMethod == QGraphicsScene::CustomIndex) - customIndex->insertItem(item); + + if (indexMethod != QGraphicsScene::NoIndex) + index->insertItem(item); // If the item ignores view transformations, update our // largest-item-counter to ensure that the view can accurately @@ -823,11 +822,7 @@ void QGraphicsScenePrivate::purgeRemovedItems() // Remove stale items from the BSP tree. if (indexMethod != QGraphicsScene::NoIndex) { - if (indexMethod == QGraphicsScene::BspTreeIndex) { - bspTree.removeItems(removedItems); - } else { - customIndex->removeItems(removedItems); - } + index->removeItems(removedItems); } // Purge this list. @@ -2386,8 +2381,18 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) qWarning("QGraphicsScene: Invalid index type %d", CustomIndex); return; } + if (d->indexMethod == method) { + return; + } d->resetIndex(); + if (d->indexMethod != NoIndex) { + delete d->index; + } d->indexMethod = method; + if (method == BspTreeIndex) { + d->index = new QGraphicsSceneBspTree(); + } + } void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) @@ -2396,8 +2401,11 @@ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) if (!index) { qWarning("QGraphicsScene::setSceneIndex: Attempt to insert a null indexer"); } else { + if (d->indexMethod == BspTreeIndex) { + delete d->index; + } d->indexMethod = CustomIndex; - d->customIndex = index; + d->index = index; index->mscene = this; } } @@ -2405,7 +2413,7 @@ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) QGraphicsSceneIndex* QGraphicsScene::sceneIndex() const { Q_D(const QGraphicsScene); - return d->customIndex; + return d->index; } /*! @@ -2814,7 +2822,7 @@ void QGraphicsScene::clear() d->indexedItems.clear(); d->freeItemIndexes.clear(); d->lastItemCount = 0; - d->bspTree.clear(); + d->index->clear(); d->largestUntransformableItem = QRectF(); d->allItemsIgnoreHoverEvents = true; d->allItemsUseDefaultCursor = true; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index aacbc40..b06db38 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -58,6 +58,7 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include "qgraphicsscene_bsp_p.h" +#include "qgraphicsscene_linear_p.h" #include "qgraphicssceneindex.h" #include "qgraphicsitem_p.h" @@ -80,6 +81,7 @@ class QGraphicsScenePrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QGraphicsScene) public: QGraphicsScenePrivate(); + ~QGraphicsScenePrivate(); void init(); quint32 changedSignalMask; @@ -92,11 +94,11 @@ public: void removeFromIndex(QGraphicsItem *item); void resetIndex(); - QGraphicsSceneBspTree bspTree; void _q_updateIndex(); int lastItemCount; - QGraphicsSceneIndex *customIndex; + QGraphicsSceneIndex *index; + QGraphicsSceneLinearIndex *linearIndex; QRectF sceneRect; bool hasSceneRect; -- cgit v0.12 From 5cf43cf62221e3241e33ea25efc7014c07e4d7ad Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 7 Apr 2009 20:20:53 +0200 Subject: Fixes: Add new virtual QGraphicsSceneIndex::items(QPointF) --- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 3 +-- src/gui/graphicsview/qgraphicsscene_linear_p.h | 8 ++++++++ src/gui/graphicsview/qgraphicssceneindex.h | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index a8c54f0..ed207ea 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -95,14 +95,13 @@ public: void removeItem(QGraphicsItem *item); void removeItems(const QList &items); + QList items(const QPointF &point); QList items(const QRectF &rect); int leafCount() const; private: - QList items(const QPointF &pos); - inline int firstChildIndex(int index) const { return index * 2 + 1; } diff --git a/src/gui/graphicsview/qgraphicsscene_linear_p.h b/src/gui/graphicsview/qgraphicsscene_linear_p.h index 1ef1902..1981b17 100644 --- a/src/gui/graphicsview/qgraphicsscene_linear_p.h +++ b/src/gui/graphicsview/qgraphicsscene_linear_p.h @@ -94,6 +94,14 @@ public: m_items.removeAll(item); } + virtual QList items(const QPointF &point) { + QList result; + foreach (QGraphicsItem *item, m_items) + if (item->sceneBoundingRect().contains(point)) + result << item; + return result; + } + virtual QList items(const QRectF &rect) { QList result; foreach (QGraphicsItem *item, m_items) diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index 6246753..f78672f 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -76,6 +76,7 @@ public: virtual void removeItems(const QList &items); virtual void updateItems(const QList &items); + virtual QList items(const QPointF &point) = 0; virtual QList items(const QRectF &rect) = 0; QGraphicsScene* scene(); -- cgit v0.12 From 875d5f41b1a796d91a4a8edac6c23a7965395470 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Wed, 18 Mar 2009 15:36:41 +0100 Subject: Fixes: Autotest the scene index using the new items(QPointF) function. --- tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 9a01cb8..955f2d3 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -143,6 +143,10 @@ void tst_QGraphicsSceneIndex::scatteredItems() for (int i = 0; i < 10; ++i) scene.addRect(i*50, i*50, 40, 35); + QCOMPARE(scene.items(QPointF(5, 5)).count(), 1); + QCOMPARE(scene.items(QPointF(55, 55)).count(), 1); + QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0); + QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1); QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 10); QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0); @@ -165,6 +169,11 @@ void tst_QGraphicsSceneIndex::overlappedItems() for (int j = 0; j < 10; ++j) scene.addRect(i*50, j*50, 200, 200); + QCOMPARE(scene.items(QPointF(5, 5)).count(), 1); + QCOMPARE(scene.items(QPointF(55, 55)).count(), 4); + QCOMPARE(scene.items(QPointF(105, 105)).count(), 9); + QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0); + QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 100); QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0); QCOMPARE(scene.items(QRectF(0, 0, 200, 200)).count(), 16); @@ -190,12 +199,17 @@ void tst_QGraphicsSceneIndex::movingItems() scene.addRect(i*50, i*50, 40, 35); QGraphicsRectItem *box = scene.addRect(0, 0, 10, 10); + QCOMPARE(scene.items(QPointF(5, 5)).count(), 2); + QCOMPARE(scene.items(QPointF(-1, -1)).count(), 0); QCOMPARE(scene.items(QRectF(0, 0, 5, 5)).count(), 2); box->setPos(10, 10); + QCOMPARE(scene.items(QPointF(9, 9)).count(), 1); + QCOMPARE(scene.items(QPointF(15, 15)).count(), 2); QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 1); box->setPos(-5, -5); + QCOMPARE(scene.items(QPointF(-1, -1)).count(), 1); QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 2); QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 11); -- cgit v0.12 From 76b8d22cee1d0a12de30f2c9d49ead5625b5122f Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Wed, 18 Mar 2009 16:33:03 +0100 Subject: Fixes: QGraphicsSceneIndex now inherits from QObject --- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 4 ++-- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 4 +++- src/gui/graphicsview/qgraphicsscene_linear_p.h | 4 +++- src/gui/graphicsview/qgraphicssceneindex.cpp | 4 ++-- src/gui/graphicsview/qgraphicssceneindex.h | 7 +++++-- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index b73cba2..29c54bb 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -83,8 +83,8 @@ public: } }; -QGraphicsSceneBspTree::QGraphicsSceneBspTree() - : leafCnt(0) +QGraphicsSceneBspTree::QGraphicsSceneBspTree(QObject *parent) + : QGraphicsSceneIndex(parent), leafCnt(0) { insertVisitor = new QGraphicsSceneInsertItemBspTreeVisitor; removeVisitor = new QGraphicsSceneRemoveItemBspTreeVisitor; diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index ed207ea..8b7d753 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -72,6 +72,8 @@ class QGraphicsSceneFindItemBspTreeVisitor; class Q_AUTOTEST_EXPORT QGraphicsSceneBspTree : public QGraphicsSceneIndex { + Q_OBJECT + public: struct Node { @@ -83,7 +85,7 @@ public: Type type; }; - QGraphicsSceneBspTree(); + QGraphicsSceneBspTree(QObject *parent = 0); ~QGraphicsSceneBspTree(); void initialize(const QRectF &rect, int depth); diff --git a/src/gui/graphicsview/qgraphicsscene_linear_p.h b/src/gui/graphicsview/qgraphicsscene_linear_p.h index 1981b17..4871b2c 100644 --- a/src/gui/graphicsview/qgraphicsscene_linear_p.h +++ b/src/gui/graphicsview/qgraphicsscene_linear_p.h @@ -66,12 +66,14 @@ QT_BEGIN_NAMESPACE class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex { + Q_OBJECT + private: QRectF m_sceneRect; QList m_items; public: - QGraphicsSceneLinearIndex(): QGraphicsSceneIndex() { + QGraphicsSceneLinearIndex(QObject *parent = 0): QGraphicsSceneIndex(parent) { } virtual void setRect(const QRectF &rect) { diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 99d1b3b..904e0af 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE /*! Constructs an abstract scene index. */ -QGraphicsSceneIndex::QGraphicsSceneIndex() +QGraphicsSceneIndex::QGraphicsSceneIndex(QObject *parent): QObject(parent) { } @@ -166,6 +166,6 @@ void QGraphicsSceneIndex::updateItems(const QList &items) QT_END_NAMESPACE -//#include "moc_qgraphicssceneindex.cpp" +#include "moc_qgraphicssceneindex.cpp" #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index f78672f..d3b6c9f 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -43,6 +43,7 @@ #define QGRAPHICSSCENEINDEX_H #include +#include QT_BEGIN_HEADER @@ -58,10 +59,12 @@ class QRectF; class QPointF; template class QList; -class Q_GUI_EXPORT QGraphicsSceneIndex +class Q_GUI_EXPORT QGraphicsSceneIndex: public QObject { + Q_OBJECT + public: - QGraphicsSceneIndex(); + QGraphicsSceneIndex(QObject *parent = 0); virtual ~QGraphicsSceneIndex(); virtual void setRect(const QRectF &rect) = 0; -- cgit v0.12 From dfd72ab3c8e519f2c08b9a85e1309f8e06a5dd45 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Wed, 18 Mar 2009 19:49:55 +0100 Subject: Fixes: 'delete' always works even with null pointer. --- src/gui/graphicsview/qgraphicsscene.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 4070f11..dd67067 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -363,8 +363,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() } QGraphicsScenePrivate::~QGraphicsScenePrivate() { - if (index) - delete index; + delete index; } /*! \internal -- cgit v0.12 From 31bba59443638a2f97f330a9b64ded261b060701 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Wed, 18 Mar 2009 20:16:55 +0100 Subject: Fixes: Own our internal scene index so we do not need to explicitly delete it. --- src/gui/graphicsview/qgraphicsscene.cpp | 7 +++---- src/gui/graphicsview/qgraphicsscene_p.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index dd67067..d4fcbd0 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -361,10 +361,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() style(0) { } -QGraphicsScenePrivate::~QGraphicsScenePrivate() -{ - delete index; -} + /*! \internal */ @@ -372,6 +369,8 @@ void QGraphicsScenePrivate::init() { Q_Q(QGraphicsScene); + index->setParent(q); + // Keep this index so we can check for connected slots later on. changedSignalMask = (1 << q->metaObject()->indexOfSignal("changed(QList)")); qApp->d_func()->scene_list.append(q); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index b06db38..7e311ee 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -81,7 +81,6 @@ class QGraphicsScenePrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QGraphicsScene) public: QGraphicsScenePrivate(); - ~QGraphicsScenePrivate(); void init(); quint32 changedSignalMask; -- cgit v0.12 From 980e01d69a29e2710a954e2bcd47d78039c76dbd Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Wed, 18 Mar 2009 20:21:36 +0100 Subject: Fixes: Recreate the BSP tree properly. --- src/gui/graphicsview/qgraphicsscene.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index d4fcbd0..4b40d3b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -2383,14 +2383,12 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) return; } d->resetIndex(); - if (d->indexMethod != NoIndex) { + if (method == BspTreeIndex) { delete d->index; + d->index = new QGraphicsSceneBspTree(this); + // ### FIXME: transfer the items } d->indexMethod = method; - if (method == BspTreeIndex) { - d->index = new QGraphicsSceneBspTree(); - } - } void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) -- cgit v0.12 From f4c03e0eec3b39145471f25d0a1cdcdba604790c Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Wed, 18 Mar 2009 20:41:27 +0100 Subject: Fixes: Recreate the index properly when switching the index method. --- src/gui/graphicsview/qgraphicsscene.cpp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 4b40d3b..f8f8e98 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -2372,6 +2372,17 @@ QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const Q_D(const QGraphicsScene); return d->indexMethod; } + +// Possibilities +// NoIndex -> CustomIndex : warning +// BspTreeIndex -> CustomIndex : warning +// CustomIndex -> CustomIndex : warning +// NoIndex -> BspTreeIndex : create an empty BSP if necessary +// BspTreeIndex -> BspTreeIndex : nothing +// CustomIndex -> BspTreeIndex : create BSP and transfer items +// NoIndex -> NoIndex : nothing +// BspTreeIndex -> NoIndex : nothing +// CustomIndex -> NoIndex : create BSP tree but do not populate void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) { Q_D(QGraphicsScene); @@ -2383,11 +2394,25 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) return; } d->resetIndex(); - if (method == BspTreeIndex) { - delete d->index; + + if (d->indexMethod == NoIndex && method == BspTreeIndex) { + QGraphicsSceneBspTree *tree = qobject_cast(d->index); + if (!tree) { + delete d->index; + d->index = new QGraphicsSceneBspTree(this); + } + } + + if (d->indexMethod == CustomIndex && method == BspTreeIndex) { + QGraphicsSceneIndex *oldIndex = d->index; d->index = new QGraphicsSceneBspTree(this); - // ### FIXME: transfer the items + d->index->insertItems(oldIndex->items(oldIndex->rect())); } + + if (d->indexMethod == CustomIndex && method == NoIndex) { + d->index = new QGraphicsSceneBspTree(this); + } + d->indexMethod = method; } -- cgit v0.12 From ce77e1d327653c2c0724d6d4a45564c25d98eda8 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Thu, 19 Mar 2009 11:26:24 +0100 Subject: Fixes: Move the bsp depth variable to the BSP tree class. --- src/gui/graphicsview/qgraphicsscene.cpp | 16 ++++++++++++---- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 2 +- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f8f8e98..6aab9df 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -329,7 +329,6 @@ static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraph QGraphicsScenePrivate::QGraphicsScenePrivate() : changedSignalMask(0), indexMethod(QGraphicsScene::BspTreeIndex), - bspTreeDepth(0), lastItemCount(0), index(new QGraphicsSceneBspTree()), hasSceneRect(false), @@ -540,7 +539,9 @@ void QGraphicsScenePrivate::_q_updateIndex() // Determine whether we should regenerate the BSP tree. if (indexMethod == QGraphicsScene::BspTreeIndex) { - int depth = bspTreeDepth; + QGraphicsSceneBspTree *bspTree = qobject_cast(index); + Q_ASSERT(bspTree); + int depth = bspTree->depth; if (depth == 0) { int oldDepth = intmaxlog(lastItemCount); depth = intmaxlog(indexedItems.size()); @@ -2472,7 +2473,8 @@ QGraphicsSceneIndex* QGraphicsScene::sceneIndex() const int QGraphicsScene::bspTreeDepth() const { Q_D(const QGraphicsScene); - return d->bspTreeDepth; + QGraphicsSceneBspTree *bspTree = qobject_cast(d->index); + return bspTree ? bspTree->depth : 0; } void QGraphicsScene::setBspTreeDepth(int depth) { @@ -2485,7 +2487,13 @@ void QGraphicsScene::setBspTreeDepth(int depth) return; } - d->bspTreeDepth = depth; + QGraphicsSceneBspTree *bspTree = qobject_cast(d->index); + if (!bspTree) { + qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP"); + return; + } + + bspTree->depth = depth; d->resetIndex(); } diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index 29c54bb..a81b14d 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -84,7 +84,7 @@ public: }; QGraphicsSceneBspTree::QGraphicsSceneBspTree(QObject *parent) - : QGraphicsSceneIndex(parent), leafCnt(0) + : QGraphicsSceneIndex(parent), depth(0), leafCnt(0) { insertVisitor = new QGraphicsSceneInsertItemBspTreeVisitor; removeVisitor = new QGraphicsSceneRemoveItemBspTreeVisitor; diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index 8b7d753..69d9eee 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -102,6 +102,8 @@ public: int leafCount() const; + int depth; + private: inline int firstChildIndex(int index) const -- cgit v0.12 From a779817905ae66de9333fbe3896b0ff1c3990581 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 19 Mar 2009 14:23:41 +0100 Subject: Fixes: First step to remove the indexing logic inside the scene. This commit basically remove the list of unindexingItems and use the linear index instead. Details: We now must be able to get rid of the timer which is the BSP role. --- src/gui/graphicsview/qgraphicsscene.cpp | 117 ++++++++++++------------- src/gui/graphicsview/qgraphicsscene_linear_p.h | 4 + src/gui/graphicsview/qgraphicsscene_p.h | 1 - 3 files changed, 60 insertions(+), 62 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 6aab9df..b559835 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -331,6 +331,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() indexMethod(QGraphicsScene::BspTreeIndex), lastItemCount(0), index(new QGraphicsSceneBspTree()), + linearIndex(new QGraphicsSceneLinearIndex()), hasSceneRect(false), updateAll(false), calledEmitUpdated(false), @@ -369,6 +370,7 @@ void QGraphicsScenePrivate::init() Q_Q(QGraphicsScene); index->setParent(q); + linearIndex->setParent(q); // Keep this index so we can check for connected slots later on. changedSignalMask = (1 << q->metaObject()->indexOfSignal("changed(QList)")); @@ -392,16 +394,13 @@ QList QGraphicsScenePrivate::estimateItemsInRect(const QRectF & // Get items from index items = that->index->items(rect); + //### Why there are items indexed and not at some point? + // Fill in with any unindexed items - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { - QRectF boundingRect = item->sceneBoundingRect(); - if (QRectF_intersects(boundingRect, rect)) { - item->d_ptr->itemDiscovered = 1; - items << item; - } - } + foreach (QGraphicsItem *item, linearIndex->items(rect)) { + if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { + item->d_ptr->itemDiscovered = 1; + items << item; } } @@ -412,14 +411,15 @@ QList QGraphicsScenePrivate::estimateItemsInRect(const QRectF & } QList itemsInRect; - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - if (item->d_ptr->visible && item->effectiveOpacity() > qreal(0.0)) - itemsInRect << item; - } + foreach (QGraphicsItem *item, linearIndex->items(rect)) { + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + continue; + if (item->d_ptr->visible && item->effectiveOpacity() > qreal(0.0)) + itemsInRect << item; } + + //### Why there are items indexed and not at some point? + for (int i = 0; i < indexedItems.size(); ++i) { if (QGraphicsItem *item = indexedItems.at(i)) { if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) @@ -469,7 +469,7 @@ void QGraphicsScenePrivate::removeFromIndex(QGraphicsItem *item) freeItemIndexes << index; indexedItems[index] = 0; item->d_func()->index = -1; - unindexedItems << item; + linearIndex->insertItem(item); foreach (QGraphicsItem *child, item->children()) child->removeFromIndex(); @@ -488,7 +488,7 @@ void QGraphicsScenePrivate::resetIndex() for (int i = 0; i < indexedItems.size(); ++i) { if (QGraphicsItem *item = indexedItems.at(i)) { item->d_ptr->index = -1; - unindexedItems << item; + linearIndex->insertItem(item); } } indexedItems.clear(); @@ -519,17 +519,15 @@ void QGraphicsScenePrivate::_q_updateIndex() // Add unindexedItems to indexedItems QRectF unindexedItemsBoundingRect; - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); - if (!freeItemIndexes.isEmpty()) { - int freeIndex = freeItemIndexes.takeFirst(); - item->d_func()->index = freeIndex; - indexedItems[freeIndex] = item; - } else { - item->d_func()->index = indexedItems.size(); - indexedItems << item; - } + foreach (QGraphicsItem *item, linearIndex->indexedItems()) { + unindexedItemsBoundingRect |= item->sceneBoundingRect(); + if (!freeItemIndexes.isEmpty()) { + int freeIndex = freeItemIndexes.takeFirst(); + item->d_func()->index = freeIndex; + indexedItems[freeIndex] = item; + } else { + item->d_func()->index = indexedItems.size(); + indexedItems << item; } } @@ -560,7 +558,8 @@ void QGraphicsScenePrivate::_q_updateIndex() //### do something better QGraphicsSceneBspTree *bsp = static_cast(index); bsp->initialize(q->sceneRect(), depth); - unindexedItems = indexedItems; + foreach (QGraphicsItem *item, indexedItems) + linearIndex->insertItem(item); lastItemCount = indexedItems.size(); q->update(); @@ -572,30 +571,28 @@ void QGraphicsScenePrivate::_q_updateIndex() } // Insert all unindexed items into the tree. - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - QRectF rect = item->sceneBoundingRect(); - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; + foreach (QGraphicsItem *item, linearIndex->indexedItems()) { + QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + continue; - if (indexMethod != QGraphicsScene::NoIndex) - index->insertItem(item); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); + if (indexMethod != QGraphicsScene::NoIndex) + index->insertItem(item); + + // If the item ignores view transformations, update our + // largest-item-counter to ensure that the view can accurately + // discover untransformable items when drawing. + if (item->d_ptr->itemIsUntransformable()) { + QGraphicsItem *topmostUntransformable = item; + while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags + & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { + topmostUntransformable = topmostUntransformable->parentItem(); } + // ### Verify that this is the correct largest untransformable rectangle. + largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); } } - unindexedItems.clear(); + linearIndex->clear(); // Notify scene rect changes. if (!hasSceneRect && growingItemsBoundingRect != oldGrowingItemsBoundingRect) @@ -756,7 +753,7 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) } else { // Recently added items are purged immediately. unindexedItems() never // contains stale items. - unindexedItems.removeAll(item); + linearIndex->removeItem(item); q->update(); } @@ -1982,8 +1979,7 @@ void QGraphicsScenePrivate::_q_updateSortCache() if (item && item->parentItem() == 0) topLevels << item; } - for (int i = 0; i < unindexedItems.size(); ++i) { - QGraphicsItem *item = unindexedItems.at(i); + foreach (QGraphicsItem *item, linearIndex->indexedItems()) { if (item->parentItem() == 0) topLevels << item; } @@ -2552,15 +2548,15 @@ QList QGraphicsScene::items() const // If freeItemIndexes is empty, we know there are no holes in indexedItems and // unindexedItems. if (d->freeItemIndexes.isEmpty()) { - if (d->unindexedItems.isEmpty()) + if (d->linearIndex->indexedItems().isEmpty()) return d->indexedItems; - return d->indexedItems + d->unindexedItems; + return d->indexedItems + d->linearIndex->indexedItems(); } // Rebuild the list of items to avoid holes. ### We could also just // compress the item lists at this point. QList itemList; - foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { + foreach (QGraphicsItem *item, d->indexedItems + d->linearIndex->indexedItems()) { if (item) itemList << item; } @@ -2841,12 +2837,11 @@ void QGraphicsScene::clear() } } QList unindexedParents; - for (int i = 0; i < d->unindexedItems.size(); ++i) { - QGraphicsItem *item = d->unindexedItems.at(i); + foreach (QGraphicsItem *item, d->linearIndex->indexedItems()) { if (!item->parentItem()) unindexedParents << item; } - d->unindexedItems.clear(); + d->linearIndex->clear(); qDeleteAll(unindexedParents); d->indexedItems.clear(); d->freeItemIndexes.clear(); @@ -2994,7 +2989,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Indexing requires sceneBoundingRect(), but because \a item might // not be completely constructed at this point, we need to store it in // a temporary list and schedule an indexing for later. - d->unindexedItems << item; + d->linearIndex->insertItem(item); item->d_func()->index = -1; d->startIndexTimer(); @@ -3382,7 +3377,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) d->freeItemIndexes << index; d->indexedItems[index] = 0; } else { - d->unindexedItems.removeAll(item); + d->linearIndex->removeItem(item); } // Remove from scene transform cache diff --git a/src/gui/graphicsview/qgraphicsscene_linear_p.h b/src/gui/graphicsview/qgraphicsscene_linear_p.h index 4871b2c..41e03e4 100644 --- a/src/gui/graphicsview/qgraphicsscene_linear_p.h +++ b/src/gui/graphicsview/qgraphicsscene_linear_p.h @@ -111,6 +111,10 @@ public: result << item; return result; } + + QList indexedItems() { + return m_items; + } }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 7e311ee..65c1a69 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -112,7 +112,6 @@ public: QPainterPath selectionArea; int selectionChanging; QSet selectedItems; - QList unindexedItems; QList indexedItems; QList dirtyItems; QList pendingUpdateItems; -- cgit v0.12 From 226baa99f53eeeff2489148c9187c19f5bc86f0e Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 7 Apr 2009 20:42:53 +0200 Subject: Remove the indexing (BSP) logic from the scene We basically add a new index that implement the old BSP logic but in a separate class instead of living into the QGraphicsScene. It will be much more easier to add a new index method or for people to use their own Conflicts: src/gui/graphicsview/qgraphicsitem.cpp src/gui/graphicsview/qgraphicssceneindex.h --- src/gui/graphicsview/graphicsview.pri | 4 +- src/gui/graphicsview/qgraphicsitem.cpp | 10 +- src/gui/graphicsview/qgraphicsitem.h | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 390 ++---------------- src/gui/graphicsview/qgraphicsscene.h | 2 +- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 40 +- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 27 +- src/gui/graphicsview/qgraphicsscene_linear_p.h | 124 ------ src/gui/graphicsview/qgraphicsscene_p.h | 20 +- .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 437 +++++++++++++++++++++ .../graphicsview/qgraphicsscenebsptreeindex_p.h | 118 ++++++ src/gui/graphicsview/qgraphicssceneindex.cpp | 14 +- src/gui/graphicsview/qgraphicssceneindex.h | 15 +- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 126 ++++++ .../tst_qgraphicssceneindex.cpp | 15 +- 15 files changed, 769 insertions(+), 574 deletions(-) delete mode 100644 src/gui/graphicsview/qgraphicsscene_linear_p.h create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h create mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index bc4d9dd..9097497 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -6,8 +6,9 @@ HEADERS += \ graphicsview/qgraphicsitemanimation.h \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_p.h \ + graphicsview/qgraphicsscenebsptreeindex_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ - graphicsview/qgraphicsscene_linear_p.h \ + graphicsview/qgraphicsscenelinearindex_p.h \ graphicsview/qgraphicssceneindex.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicsview_p.h \ @@ -18,6 +19,7 @@ SOURCES += \ graphicsview/qgraphicsitemanimation.cpp \ graphicsview/qgraphicsscene.cpp \ graphicsview/qgraphicsscene_bsp.cpp \ + graphicsview/qgraphicsscenebsptreeindex_p.cpp \ graphicsview/qgraphicssceneindex.cpp \ graphicsview/qgraphicssceneevent.cpp \ graphicsview/qgraphicsview.cpp diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b8ff5b4..4574334 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5789,7 +5789,7 @@ void QGraphicsItem::addToIndex() return; } if (d_ptr->scene) - d_ptr->scene->d_func()->addToIndex(this); + d_ptr->scene->d_func()->index->insertItem(this); d_ptr->updateHelper(); } @@ -5802,13 +5802,9 @@ void QGraphicsItem::addToIndex() */ void QGraphicsItem::removeFromIndex() { - if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - // ### remove from child index only if applicable - return; - } d_ptr->updateHelper(); if (d_ptr->scene) - d_ptr->scene->d_func()->removeFromIndex(this); + d_ptr->scene->d_func()->index->removeItem(this,false); } /*! @@ -5831,7 +5827,7 @@ void QGraphicsItem::prepareGeometryChange() d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); - scenePrivate->removeFromIndex(this); + scenePrivate->index->updateItem(this); if (d_ptr->inSetPosHelper) return; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index b98882d..1b41232 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -398,6 +398,7 @@ private: friend class QGraphicsWidget; friend class QGraphicsWidgetPrivate; friend class QGraphicsProxyWidgetPrivate; + friend class QGraphicsSceneBspTreeIndex; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index b559835..8140f79 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -39,8 +39,6 @@ ** ****************************************************************************/ -static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; - /*! \class QGraphicsScene \brief The QGraphicsScene class provides a surface for managing a large @@ -329,18 +327,14 @@ static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraph QGraphicsScenePrivate::QGraphicsScenePrivate() : changedSignalMask(0), indexMethod(QGraphicsScene::BspTreeIndex), + bspTreeDepth(0), lastItemCount(0), - index(new QGraphicsSceneBspTree()), - linearIndex(new QGraphicsSceneLinearIndex()), + index(0), hasSceneRect(false), updateAll(false), calledEmitUpdated(false), selectionChanging(0), dirtyItemResetPending(false), - regenerateIndex(true), - purgePending(false), - indexTimerId(0), - restartIndexTimer(false), stickyFocus(false), hasFocus(false), focusItem(0), @@ -369,8 +363,7 @@ void QGraphicsScenePrivate::init() { Q_Q(QGraphicsScene); - index->setParent(q); - linearIndex->setParent(q); + index = new QGraphicsSceneBspTreeIndex(q); // Keep this index so we can check for connected slots later on. changedSignalMask = (1 << q->metaObject()->indexOfSignal("changed(QList)")); @@ -383,220 +376,14 @@ void QGraphicsScenePrivate::init() */ QList QGraphicsScenePrivate::estimateItemsInRect(const QRectF &rect) const { - const_cast(this)->purgeRemovedItems(); const_cast(this)->_q_updateSortCache(); - if (indexMethod != QGraphicsScene::NoIndex) { - // ### Only do this once in a while. - QGraphicsScenePrivate *that = const_cast(this); - - QList items; - // Get items from index - items = that->index->items(rect); - - //### Why there are items indexed and not at some point? - - // Fill in with any unindexed items - foreach (QGraphicsItem *item, linearIndex->items(rect)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { - item->d_ptr->itemDiscovered = 1; - items << item; - } - } - - // Reset the discovered state of all discovered items - for (int i = 0; i < items.size(); ++i) - items.at(i)->d_func()->itemDiscovered = 0; - return items; - } - - QList itemsInRect; - foreach (QGraphicsItem *item, linearIndex->items(rect)) { - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - if (item->d_ptr->visible && item->effectiveOpacity() > qreal(0.0)) - itemsInRect << item; - } + // ### Only do this once in a while. + QGraphicsScenePrivate *that = const_cast(this); - //### Why there are items indexed and not at some point? - - for (int i = 0; i < indexedItems.size(); ++i) { - if (QGraphicsItem *item = indexedItems.at(i)) { - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - if (item->d_ptr->visible && item->effectiveOpacity() > qreal(0.0)) - itemsInRect << item; - } - } + // Get items from index + return that->index->items(rect); - return itemsInRect; -} - -/*! - \internal -*/ -void QGraphicsScenePrivate::addToIndex(QGraphicsItem *item) -{ - if (indexMethod == QGraphicsScene::BspTreeIndex) { - if (item->d_func()->index != -1) { - index->insertItem(item); - foreach (QGraphicsItem *child, item->children()) - child->addToIndex(); - } else { - // The BSP tree is regenerated if the number of items grows to a - // certain threshold, or if the bounding rect of the graph doubles in - // size. - startIndexTimer(); - } - } else if (indexMethod == QGraphicsScene::CustomIndex) { - if (item->d_func()->index != -1) { - index->insertItem(item); - foreach (QGraphicsItem *child, item->children()) - child->addToIndex(); - } - } -} - -/*! - \internal -*/ -void QGraphicsScenePrivate::removeFromIndex(QGraphicsItem *item) -{ - if (indexMethod != QGraphicsScene::NoIndex) { - int index = item->d_func()->index; - if (index != -1) { - this->index->removeItem(item); - freeItemIndexes << index; - indexedItems[index] = 0; - item->d_func()->index = -1; - linearIndex->insertItem(item); - - foreach (QGraphicsItem *child, item->children()) - child->removeFromIndex(); - } - startIndexTimer(); - } -} - -/*! - \internal -*/ -void QGraphicsScenePrivate::resetIndex() -{ - purgeRemovedItems(); - if (indexMethod != QGraphicsScene::NoIndex) { - for (int i = 0; i < indexedItems.size(); ++i) { - if (QGraphicsItem *item = indexedItems.at(i)) { - item->d_ptr->index = -1; - linearIndex->insertItem(item); - } - } - indexedItems.clear(); - freeItemIndexes.clear(); - regenerateIndex = true; - startIndexTimer(); - } -} - -static inline int intmaxlog(int n) -{ - return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); -} - -/*! - \internal -*/ -void QGraphicsScenePrivate::_q_updateIndex() -{ - if (!indexTimerId) - return; - - Q_Q(QGraphicsScene); - q->killTimer(indexTimerId); - indexTimerId = 0; - - purgeRemovedItems(); - - // Add unindexedItems to indexedItems - QRectF unindexedItemsBoundingRect; - foreach (QGraphicsItem *item, linearIndex->indexedItems()) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); - if (!freeItemIndexes.isEmpty()) { - int freeIndex = freeItemIndexes.takeFirst(); - item->d_func()->index = freeIndex; - indexedItems[freeIndex] = item; - } else { - item->d_func()->index = indexedItems.size(); - indexedItems << item; - } - } - - // Update growing scene rect. - QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; - growingItemsBoundingRect |= unindexedItemsBoundingRect; - - // Determine whether we should regenerate the BSP tree. - if (indexMethod == QGraphicsScene::BspTreeIndex) { - QGraphicsSceneBspTree *bspTree = qobject_cast(index); - Q_ASSERT(bspTree); - int depth = bspTree->depth; - if (depth == 0) { - int oldDepth = intmaxlog(lastItemCount); - depth = intmaxlog(indexedItems.size()); - static const int slack = 100; - //### do something better - QGraphicsSceneBspTree *bsp = static_cast(index); - if (bsp->leafCount() == 0 || (oldDepth != depth && qAbs(lastItemCount - indexedItems.size()) > slack)) { - // ### Crude algorithm. - regenerateIndex = true; - } - } - - // Regenerate the tree. - if (regenerateIndex) { - regenerateIndex = false; - //### do something better - QGraphicsSceneBspTree *bsp = static_cast(index); - bsp->initialize(q->sceneRect(), depth); - foreach (QGraphicsItem *item, indexedItems) - linearIndex->insertItem(item); - lastItemCount = indexedItems.size(); - q->update(); - - // Take this opportunity to reset our largest-item counter for - // untransformable items. When the items are inserted into the BSP - // tree, we'll get an accurate calculation. - largestUntransformableItem = QRectF(); - } - } - - // Insert all unindexed items into the tree. - foreach (QGraphicsItem *item, linearIndex->indexedItems()) { - QRectF rect = item->sceneBoundingRect(); - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - - if (indexMethod != QGraphicsScene::NoIndex) - index->insertItem(item); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); - } - } - linearIndex->clear(); - - // Notify scene rect changes. - if (!hasSceneRect && growingItemsBoundingRect != oldGrowingItemsBoundingRect) - emit q->sceneRectChanged(growingItemsBoundingRect); } /*! @@ -740,22 +527,8 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) // chain. item->clearFocus(); - int index = item->d_func()->index; - if (index != -1) { - // Important: The index is useless until purgeRemovedItems() is - // called. - indexedItems[index] = (QGraphicsItem *)0; - if (!purgePending) { - purgePending = true; - q->update(); - } - removedItems << item; - } else { - // Recently added items are purged immediately. unindexedItems() never - // contains stale items. - linearIndex->removeItem(item); - q->update(); - } + //We ask for a removing in the index + this->index->removeItem(item, true); // Reset the mouse grabber and focus item data. if (item == focusItem) @@ -806,51 +579,6 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) /*! \internal - - Removes stale pointers from all data structures. -*/ -void QGraphicsScenePrivate::purgeRemovedItems() -{ - Q_Q(QGraphicsScene); - - if (!purgePending && removedItems.isEmpty()) - return; - - // Remove stale items from the BSP tree. - if (indexMethod != QGraphicsScene::NoIndex) { - index->removeItems(removedItems); - } - - // Purge this list. - removedItems.clear(); - freeItemIndexes.clear(); - for (int i = 0; i < indexedItems.size(); ++i) { - if (!indexedItems.at(i)) - freeItemIndexes << i; - } - purgePending = false; - - // No locality info for the items; update the whole scene. - q->update(); -} - -/*! - \internal - - Starts or restarts the timer used for reindexing unindexed items. -*/ -void QGraphicsScenePrivate::startIndexTimer() -{ - Q_Q(QGraphicsScene); - if (indexTimerId) { - restartIndexTimer = true; - } else { - indexTimerId = q->startTimer(QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); - } -} - -/*! - \internal */ void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget) { @@ -1964,7 +1692,7 @@ void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder) void QGraphicsScenePrivate::_q_updateSortCache() { - _q_updateIndex(); + index->updateIndex(); if (!sortCacheEnabled || !updatingSortCache) return; @@ -1974,15 +1702,11 @@ void QGraphicsScenePrivate::_q_updateSortCache() QList topLevels; - for (int i = 0; i < indexedItems.size(); ++i) { - QGraphicsItem *item = indexedItems.at(i); + for (int i = 0; i < index->indexedItems().count(); ++i) { + QGraphicsItem *item = index->indexedItems().at(i); if (item && item->parentItem() == 0) topLevels << item; } - foreach (QGraphicsItem *item, linearIndex->indexedItems()) { - if (item->parentItem() == 0) - topLevels << item; - } qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); for (int i = 0; i < topLevels.size(); ++i) @@ -2139,8 +1863,8 @@ QGraphicsScene::QGraphicsScene(QObject *parent) QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent) : QObject(*new QGraphicsScenePrivate, parent) { - setSceneRect(sceneRect); d_func()->init(); + setSceneRect(sceneRect); } /*! @@ -2154,8 +1878,8 @@ QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent) QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent) : QObject(*new QGraphicsScenePrivate, parent) { - setSceneRect(x, y, width, height); d_func()->init(); + setSceneRect(x, y, width, height); } /*! @@ -2192,8 +1916,8 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - const_cast(d)->_q_updateIndex(); - return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; + d->index->updateIndex(); + return d->hasSceneRect ? d->index->rect() : d->growingItemsBoundingRect; } void QGraphicsScene::setSceneRect(const QRectF &rect) { @@ -2201,7 +1925,7 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) if (rect != d->sceneRect) { d->hasSceneRect = !rect.isNull(); d->sceneRect = rect; - d->resetIndex(); + d->index->setRect(rect); emit sceneRectChanged(rect); } } @@ -2390,24 +2114,23 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) if (d->indexMethod == method) { return; } - d->resetIndex(); if (d->indexMethod == NoIndex && method == BspTreeIndex) { - QGraphicsSceneBspTree *tree = qobject_cast(d->index); + QGraphicsSceneBspTreeIndex *tree = qobject_cast(d->index); if (!tree) { delete d->index; - d->index = new QGraphicsSceneBspTree(this); + d->index = new QGraphicsSceneBspTreeIndex(this); } } if (d->indexMethod == CustomIndex && method == BspTreeIndex) { QGraphicsSceneIndex *oldIndex = d->index; - d->index = new QGraphicsSceneBspTree(this); + d->index = new QGraphicsSceneBspTreeIndex(this); d->index->insertItems(oldIndex->items(oldIndex->rect())); } if (d->indexMethod == CustomIndex && method == NoIndex) { - d->index = new QGraphicsSceneBspTree(this); + d->index = new QGraphicsSceneLinearIndex(this); } d->indexMethod = method; @@ -2424,7 +2147,6 @@ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) } d->indexMethod = CustomIndex; d->index = index; - index->mscene = this; } } @@ -2469,8 +2191,8 @@ QGraphicsSceneIndex* QGraphicsScene::sceneIndex() const int QGraphicsScene::bspTreeDepth() const { Q_D(const QGraphicsScene); - QGraphicsSceneBspTree *bspTree = qobject_cast(d->index); - return bspTree ? bspTree->depth : 0; + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + return bspTree ? bspTree->bspDepth() : 0; } void QGraphicsScene::setBspTreeDepth(int depth) { @@ -2483,14 +2205,13 @@ void QGraphicsScene::setBspTreeDepth(int depth) return; } - QGraphicsSceneBspTree *bspTree = qobject_cast(d->index); + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); if (!bspTree) { qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP"); return; } - bspTree->depth = depth; - d->resetIndex(); + bspTree->setBspDepth(depth); } /*! @@ -2543,24 +2264,7 @@ QRectF QGraphicsScene::itemsBoundingRect() const QList QGraphicsScene::items() const { Q_D(const QGraphicsScene); - const_cast(d)->purgeRemovedItems(); - - // If freeItemIndexes is empty, we know there are no holes in indexedItems and - // unindexedItems. - if (d->freeItemIndexes.isEmpty()) { - if (d->linearIndex->indexedItems().isEmpty()) - return d->indexedItems; - return d->indexedItems + d->linearIndex->indexedItems(); - } - - // Rebuild the list of items to avoid holes. ### We could also just - // compress the item lists at this point. - QList itemList; - foreach (QGraphicsItem *item, d->indexedItems + d->linearIndex->indexedItems()) { - if (item) - itemList << item; - } - return itemList; + return d->index->indexedItems(); } /*! @@ -2830,21 +2534,12 @@ void QGraphicsScene::clear() { Q_D(QGraphicsScene); // Recursive descent delete - for (int i = 0; i < d->indexedItems.size(); ++i) { - if (QGraphicsItem *item = d->indexedItems.at(i)) { + for (int i = 0; i < d->index->indexedItems().size(); ++i) { + if (QGraphicsItem *item = d->index->indexedItems().at(i)) { if (!item->parentItem()) delete item; } } - QList unindexedParents; - foreach (QGraphicsItem *item, d->linearIndex->indexedItems()) { - if (!item->parentItem()) - unindexedParents << item; - } - d->linearIndex->clear(); - qDeleteAll(unindexedParents); - d->indexedItems.clear(); - d->freeItemIndexes.clear(); d->lastItemCount = 0; d->index->clear(); d->largestUntransformableItem = QRectF(); @@ -2968,10 +2663,6 @@ void QGraphicsScene::addItem(QGraphicsItem *item) return; } - // Prevent reusing a recently deleted pointer: purge all removed items - // from our lists. - d->purgeRemovedItems(); - // Invalidate any sort caching; arrival of a new item means we need to // resort. d->invalidateSortCache(); @@ -2989,9 +2680,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Indexing requires sceneBoundingRect(), but because \a item might // not be completely constructed at this point, we need to store it in // a temporary list and schedule an indexing for later. - d->linearIndex->insertItem(item); - item->d_func()->index = -1; - d->startIndexTimer(); + d->index->insertItem(item); // Add to list of toplevels if this item is a toplevel. if (!item->d_ptr->parent) @@ -3351,7 +3040,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - d->removeFromIndex(item); + d->index->removeItem(item, false); if (item == d->tabFocusFirst) { QGraphicsWidget *widget = static_cast(item); @@ -3371,15 +3060,6 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) d->unregisterTopLevelItem(item); } - // Remove from our item lists. - int index = item->d_func()->index; - if (index != -1) { - d->freeItemIndexes << index; - d->indexedItems[index] = 0; - } else { - d->linearIndex->removeItem(item); - } - // Remove from scene transform cache int transformIndex = item->d_func()->sceneTransformIndex; if (transformIndex != -1) { @@ -3998,16 +3678,6 @@ bool QGraphicsScene::event(QEvent *event) // geometries that do not have an explicit style set. update(); break; - case QEvent::Timer: - if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { - if (d->restartIndexTimer) { - d->restartIndexTimer = false; - } else { - // this call will kill the timer - d->_q_updateIndex(); - } - } - // Fallthrough intended - support timers in subclasses. default: return QObject::event(event); } diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index bb3cea7..6476b8c 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -279,7 +279,6 @@ private: Q_DECLARE_PRIVATE(QGraphicsScene) Q_DISABLE_COPY(QGraphicsScene) - Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated()) Q_PRIVATE_SLOT(d_func(), void _q_removeItemLater(QGraphicsItem *item)) Q_PRIVATE_SLOT(d_func(), void _q_updateLater()) @@ -292,6 +291,7 @@ private: friend class QGraphicsViewPrivate; friend class QGraphicsWidget; friend class QGraphicsWidgetPrivate; + friend class QGraphicsSceneBspTreeIndex; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index a81b14d..f8fa450 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -83,8 +83,8 @@ public: } }; -QGraphicsSceneBspTree::QGraphicsSceneBspTree(QObject *parent) - : QGraphicsSceneIndex(parent), depth(0), leafCnt(0) +QGraphicsSceneBspTree::QGraphicsSceneBspTree() + : leafCnt(0) { insertVisitor = new QGraphicsSceneInsertItemBspTreeVisitor; removeVisitor = new QGraphicsSceneRemoveItemBspTreeVisitor; @@ -100,7 +100,7 @@ QGraphicsSceneBspTree::~QGraphicsSceneBspTree() void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth) { - sceneRect = rect; + this->rect = rect; leafCnt = 0; nodes.resize((1 << (depth + 1)) - 1); nodes.fill(Node()); @@ -117,29 +117,19 @@ void QGraphicsSceneBspTree::clear() leaves.clear(); } -QRectF QGraphicsSceneBspTree::rect() const -{ - return sceneRect; -} - -void QGraphicsSceneBspTree::setRect(const QRectF &rect) -{ - sceneRect = rect; -} - -void QGraphicsSceneBspTree::insertItem(QGraphicsItem *item) +void QGraphicsSceneBspTree::insertItem(QGraphicsItem *item, const QRectF &rect) { insertVisitor->item = item; - climbTree(insertVisitor, item->sceneBoundingRect()); + climbTree(insertVisitor, rect); } -void QGraphicsSceneBspTree::removeItem(QGraphicsItem *item) +void QGraphicsSceneBspTree::removeItem(QGraphicsItem *item, const QRectF &rect) { removeVisitor->item = item; - climbTree(removeVisitor, item->sceneBoundingRect()); + climbTree(removeVisitor, rect); } -void QGraphicsSceneBspTree::removeItems(const QList &items) +void QGraphicsSceneBspTree::removeItems(const QSet &items) { for (int i = 0; i < leaves.size(); ++i) { QList newItemList; @@ -247,10 +237,8 @@ void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth, int index) void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) { - if (nodes.isEmpty()) { - // should never happen for bsp tree internal to QGraphicsScene - initialize(sceneRect, 0); - } + if (nodes.isEmpty()) + return; const Node &node = nodes.at(index); int childIndex = firstChildIndex(index); @@ -279,10 +267,8 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) { - if (nodes.isEmpty()) { - // should never happen for bsp tree internal to QGraphicsScene - initialize(sceneRect, 0); - } + if (nodes.isEmpty()) + return; const Node &node = nodes.at(index); int childIndex = firstChildIndex(index); @@ -316,7 +302,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con QRectF QGraphicsSceneBspTree::rectForIndex(int index) const { if (index <= 0) - return sceneRect; + return rect; int parentIdx = parentIndex(index); QRectF rect = rectForIndex(parentIdx); diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index 69d9eee..e6ceb78 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -60,7 +60,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -70,10 +69,8 @@ class QGraphicsSceneInsertItemBspTreeVisitor; class QGraphicsSceneRemoveItemBspTreeVisitor; class QGraphicsSceneFindItemBspTreeVisitor; -class Q_AUTOTEST_EXPORT QGraphicsSceneBspTree : public QGraphicsSceneIndex +class QGraphicsSceneBspTree { - Q_OBJECT - public: struct Node { @@ -85,27 +82,20 @@ public: Type type; }; - QGraphicsSceneBspTree(QObject *parent = 0); + QGraphicsSceneBspTree(); ~QGraphicsSceneBspTree(); void initialize(const QRectF &rect, int depth); void clear(); - QRectF rect() const; - void setRect(const QRectF &rect); - void insertItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item); - void removeItems(const QList &items); + void insertItem(QGraphicsItem *item, const QRectF &rect); + void removeItem(QGraphicsItem *item, const QRectF &rect); + void removeItems(const QSet &items); - QList items(const QPointF &point); QList items(const QRectF &rect); - + QList items(const QPointF &pos); int leafCount() const; - int depth; - -private: - inline int firstChildIndex(int index) const { return index * 2 + 1; } @@ -114,6 +104,7 @@ private: QString debug(int index) const; +private: void initialize(const QRectF &rect, int depth, int index); void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0); void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0); @@ -125,7 +116,7 @@ private: QVector nodes; QVector > leaves; int leafCnt; - QRectF sceneRect; + QRectF rect; QGraphicsSceneInsertItemBspTreeVisitor *insertVisitor; QGraphicsSceneRemoveItemBspTreeVisitor *removeVisitor; @@ -139,8 +130,6 @@ public: virtual void visit(QList *items) = 0; }; -Q_DECLARE_TYPEINFO(QGraphicsSceneBspTree::Node, Q_PRIMITIVE_TYPE); - QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscene_linear_p.h b/src/gui/graphicsview/qgraphicsscene_linear_p.h deleted file mode 100644 index 41e03e4..0000000 --- a/src/gui/graphicsview/qgraphicsscene_linear_p.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENELINEARINDEX_P_H -#define QGRAPHICSSCENELINEARINDEX_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex -{ - Q_OBJECT - -private: - QRectF m_sceneRect; - QList m_items; - -public: - QGraphicsSceneLinearIndex(QObject *parent = 0): QGraphicsSceneIndex(parent) { - } - - virtual void setRect(const QRectF &rect) { - m_sceneRect = rect; - } - - virtual QRectF rect() const { - return m_sceneRect; - } - - virtual void clear() { - m_items.clear(); - } - - virtual void insertItem(QGraphicsItem *item) { - m_items << item; - } - - virtual void removeItem(QGraphicsItem *item) { - m_items.removeAll(item); - } - - virtual QList items(const QPointF &point) { - QList result; - foreach (QGraphicsItem *item, m_items) - if (item->sceneBoundingRect().contains(point)) - result << item; - return result; - } - - virtual QList items(const QRectF &rect) { - QList result; - foreach (QGraphicsItem *item, m_items) - if (item->sceneBoundingRect().intersects(rect)) - result << item; - return result; - } - - QList indexedItems() { - return m_items; - } -}; - -QT_END_NAMESPACE - -#endif // QT_NO_GRAPHICSVIEW - -#endif // QGRAPHICSSCENELINEARINDEX_P_H diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 65c1a69..2c0d464 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -57,8 +57,8 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -#include "qgraphicsscene_bsp_p.h" -#include "qgraphicsscene_linear_p.h" +#include "qgraphicsscenebsptreeindex_p.h" +#include "qgraphicsscenelinearindex_p.h" #include "qgraphicssceneindex.h" #include "qgraphicsitem_p.h" @@ -89,15 +89,10 @@ public: int bspTreeDepth; QList estimateItemsInRect(const QRectF &rect) const; - void addToIndex(QGraphicsItem *item); - void removeFromIndex(QGraphicsItem *item); - void resetIndex(); - void _q_updateIndex(); int lastItemCount; QGraphicsSceneIndex *index; - QGraphicsSceneLinearIndex *linearIndex; QRectF sceneRect; bool hasSceneRect; @@ -112,7 +107,6 @@ public: QPainterPath selectionArea; int selectionChanging; QSet selectedItems; - QList indexedItems; QList dirtyItems; QList pendingUpdateItems; QList unpolishedItems; @@ -127,21 +121,11 @@ public: void resetDirtyItemsLater(); bool dirtyItemResetPending; - QList freeItemIndexes; - bool regenerateIndex; - - bool purgePending; void _q_removeItemLater(QGraphicsItem *item); - QList removedItems; - void purgeRemovedItems(); QBrush backgroundBrush; QBrush foregroundBrush; - int indexTimerId; - bool restartIndexTimer; - void startIndexTimer(); - bool stickyFocus; bool hasFocus; QGraphicsItem *focusItem; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp new file mode 100644 index 0000000..ebc167a --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -0,0 +1,437 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; + +#include "qgraphicsscenebsptreeindex_p.h" +#include "qgraphicsitem_p.h" +#include "qgraphicsscene_p.h" + +#include + +#include + +QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) + : QGraphicsSceneIndex(scene), + bspTreeDepth(0), + indexTimerId(0), + restartIndexTimer(false), + regenerateIndex(true), + lastItemCount(0), + purgePending(false) +{ + +} + +void QGraphicsSceneBspTreeIndex::setRect(const QRectF &rect) +{ + m_sceneRect = rect; + resetIndex(); +} + +QRectF QGraphicsSceneBspTreeIndex::rect() const +{ + const_cast(this)->updateIndex(); + return m_sceneRect; +} + +void QGraphicsSceneBspTreeIndex::clear() +{ + bsp.clear(); + lastItemCount = 0; + freeItemIndexes.clear(); + m_indexedItems.clear(); + unindexedItems.clear(); +} + +void QGraphicsSceneBspTreeIndex::insertItem(QGraphicsItem *item) +{ + // Prevent reusing a recently deleted pointer: purge all removed items + // from our lists. + purgeRemovedItems(); + + // Indexing requires sceneBoundingRect(), but because \a item might + // not be completely constructed at this point, we need to store it in + // a temporary list and schedule an indexing for later. + unindexedItems << item; + item->d_func()->index = -1; + startIndexTimer(); +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndex::addToIndex(QGraphicsItem *item) +{ + if (item->d_func()->index != -1) { + bsp.insertItem(item, item->sceneBoundingRect()); + foreach (QGraphicsItem *child, item->children()) + child->addToIndex(); + } else { + // The BSP tree is regenerated if the number of items grows to a + // certain threshold, or if the bounding rect of the graph doubles in + // size. + startIndexTimer(); + } +} + +void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item, bool itemIsAboutToDie) +{ + if (!itemIsAboutToDie) { + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + removeFromIndex(item); + + // Remove from our item lists. + int index = item->d_func()->index; + if (index != -1) { + freeItemIndexes << index; + m_indexedItems[index] = 0; + } else { + unindexedItems.removeAll(item); + } + + } else { + int index = item->d_func()->index; + if (index != -1) { + // Important: The index is useless until purgeRemovedItems() is + // called. + m_indexedItems[index] = (QGraphicsItem *)0; + if (!purgePending) { + purgePending = true; + scene()->update(); + } + removedItems << item; + } else { + // Recently added items are purged immediately. unindexedItems() never + // contains stale items. + unindexedItems.removeAll(item); + scene()->update(); + } + } +} +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) +{ + if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + // ### remove from child index only if applicable + return; + } + int index = item->d_func()->index; + if (index != -1) { + bsp.removeItem(item, item->sceneBoundingRect()); + freeItemIndexes << index; + m_indexedItems[index] = 0; + item->d_func()->index = -1; + unindexedItems << item; + + //prepareGeometryChange will call updateItem + foreach (QGraphicsItem *child, item->children()) + child->prepareGeometryChange(); + } + startIndexTimer(); +} + +void QGraphicsSceneBspTreeIndex::updateItem(QGraphicsItem *item) +{ + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + removeFromIndex(item); +} + +QList QGraphicsSceneBspTreeIndex::items(const QPointF &point) +{ + purgeRemovedItems(); + QList rectItems = bsp.items(QRectF(point, QSizeF(1, 1))); + // Fill in with any unindexed items + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { + QRectF boundingRect = item->sceneBoundingRect(); + if (boundingRect.intersects(QRectF(point, QSizeF(1, 1)))) { + item->d_ptr->itemDiscovered = 1; + rectItems << item; + } + } + } + } + + // Reset the discovered state of all discovered items + for (int i = 0; i < rectItems.size(); ++i) + rectItems.at(i)->d_func()->itemDiscovered = 0; + + return rectItems; +} + +QList QGraphicsSceneBspTreeIndex::items(const QRectF &rect) +{ + purgeRemovedItems(); + QList rectItems = bsp.items(rect); + // Fill in with any unindexed items + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { + QRectF boundingRect = item->sceneBoundingRect(); + if (boundingRect.intersects(rect)) { + item->d_ptr->itemDiscovered = 1; + rectItems << item; + } + } + } + } + + // Reset the discovered state of all discovered items + for (int i = 0; i < rectItems.size(); ++i) + rectItems.at(i)->d_func()->itemDiscovered = 0; + + return rectItems; +} + +QList QGraphicsSceneBspTreeIndex::indexedItems() +{ + purgeRemovedItems(); + // If freeItemIndexes is empty, we know there are no holes in indexedItems and + // unindexedItems. + if (freeItemIndexes.isEmpty()) { + if (unindexedItems.isEmpty()) + return m_indexedItems; + return m_indexedItems + unindexedItems; + } + + // Rebuild the list of items to avoid holes. ### We could also just + // compress the item lists at this point. + QList itemList; + foreach (QGraphicsItem *item, m_indexedItems + unindexedItems) { + if (item) + itemList << item; + } + return itemList; +} + +void QGraphicsSceneBspTreeIndex::updateIndex() +{ + _q_updateIndex(); +} + +int QGraphicsSceneBspTreeIndex::bspDepth() +{ + return bspTreeDepth; +} + +void QGraphicsSceneBspTreeIndex::setBspDepth(int depth) +{ + bspTreeDepth = depth; + resetIndex(); +} + +bool QGraphicsSceneBspTreeIndex::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::Timer: + if (indexTimerId && static_cast(event)->timerId() == indexTimerId) { + if (restartIndexTimer) { + restartIndexTimer = false; + } else { + // this call will kill the timer + _q_updateIndex(); + } + } + // Fallthrough intended - support timers in subclasses. + default: + return QObject::event(event); + } + return true; +} + +static inline int intmaxlog(int n) +{ + return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndex::_q_updateIndex() +{ + if (!indexTimerId) + return; + + killTimer(indexTimerId); + indexTimerId = 0; + + purgeRemovedItems(); + + // Add unindexedItems to indexedItems + QRectF unindexedItemsBoundingRect; + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + unindexedItemsBoundingRect |= item->sceneBoundingRect(); + if (!freeItemIndexes.isEmpty()) { + int freeIndex = freeItemIndexes.takeFirst(); + item->d_func()->index = freeIndex; + m_indexedItems[freeIndex] = item; + } else { + item->d_func()->index = m_indexedItems.size(); + m_indexedItems << item; + } + } + } + + // Update growing scene rect. + QRectF oldGrowingItemsBoundingRect = scene()->d_func()->growingItemsBoundingRect; + scene()->d_func()->growingItemsBoundingRect |= unindexedItemsBoundingRect; + + // Determine whether we should regenerate the BSP tree. + if (bspTreeDepth == 0) { + int oldDepth = intmaxlog(lastItemCount); + bspTreeDepth = intmaxlog(m_indexedItems.size()); + static const int slack = 100; + if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - m_indexedItems.size()) > slack)) { + // ### Crude algorithm. + regenerateIndex = true; + } + } + + // Regenerate the tree. + if (regenerateIndex) { + regenerateIndex = false; + bsp.initialize(scene()->sceneRect(), bspTreeDepth); + unindexedItems = m_indexedItems; + lastItemCount = m_indexedItems.size(); + scene()->update(); + + // Take this opportunity to reset our largest-item counter for + // untransformable items. When the items are inserted into the BSP + // tree, we'll get an accurate calculation. + scene()->d_func()->largestUntransformableItem = QRectF(); + } + + // Insert all unindexed items into the tree. + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + continue; + + bsp.insertItem(item,rect); + + // If the item ignores view transformations, update our + // largest-item-counter to ensure that the view can accurately + // discover untransformable items when drawing. + if (item->d_ptr->itemIsUntransformable()) { + QGraphicsItem *topmostUntransformable = item; + while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags + & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { + topmostUntransformable = topmostUntransformable->parentItem(); + } + // ### Verify that this is the correct largest untransformable rectangle. + scene()->d_func()->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); + } + } + } + unindexedItems.clear(); + + // Notify scene rect changes. + if (!scene()->d_func()->hasSceneRect && scene()->d_func()->growingItemsBoundingRect != oldGrowingItemsBoundingRect) + emit scene()->sceneRectChanged(scene()->d_func()->growingItemsBoundingRect); +} + + +/*! + \internal + + Removes stale pointers from all data structures. +*/ +void QGraphicsSceneBspTreeIndex::purgeRemovedItems() +{ + if (!purgePending && removedItems.isEmpty()) + return; + + // Remove stale items from the BSP tree. + bsp.removeItems(removedItems.toSet()); + // Purge this list. + removedItems.clear(); + freeItemIndexes.clear(); + for (int i = 0; i < m_indexedItems.size(); ++i) { + if (!m_indexedItems.at(i)) + freeItemIndexes << i; + } + purgePending = false; + + // No locality info for the items; update the whole scene. + scene()->update(); +} + +/*! + \internal + + Starts or restarts the timer used for reindexing unindexed items. +*/ +void QGraphicsSceneBspTreeIndex::startIndexTimer() +{ + if (indexTimerId) { + restartIndexTimer = true; + } else { + indexTimerId = startTimer(QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); + } +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndex::resetIndex() +{ + purgeRemovedItems(); + for (int i = 0; i < m_indexedItems.size(); ++i) { + if (QGraphicsItem *item = m_indexedItems.at(i)) { + item->d_ptr->index = -1; + unindexedItems << item; + } + } + m_indexedItems.clear(); + freeItemIndexes.clear(); + regenerateIndex = true; + startIndexTimer(); +} diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h new file mode 100644 index 0000000..74af910 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#ifndef QGRAPHICSBSPTREEINDEX_H +#define QGRAPHICSBSPTREEINDEX_H + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +QT_BEGIN_NAMESPACE + +#include +#include +#include +#include +#include + +#include "qgraphicsscene_bsp_p.h" + +class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex +{ + Q_OBJECT +public: + QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + + void setRect(const QRectF &rect); + virtual QRectF rect() const; + + void clear(); + + void insertItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item, bool itemIsAboutToDie); + void updateItem(QGraphicsItem *item); + + QList items(const QPointF &point); + QList items(const QRectF &rect); + + QList indexedItems(); + + void updateIndex(); + + int bspDepth(); + void setBspDepth(int depth); + +protected: + bool event(QEvent *event); + +public slots : + void _q_updateIndex(); + +private : + QGraphicsSceneBspTree bsp; + QRectF m_sceneRect; + int bspTreeDepth; + int indexTimerId; + bool restartIndexTimer; + bool regenerateIndex; + int lastItemCount; + + QList m_indexedItems; + QList unindexedItems; + QList freeItemIndexes; + + bool purgePending; + QList removedItems; + void purgeRemovedItems(); + + void startIndexTimer(); + void resetIndex(); + + void addToIndex(QGraphicsItem *item); + void removeFromIndex(QGraphicsItem *item); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_GRAPHICSVIEW + +#endif // QGRAPHICSBSPTREEINDEX_H diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 904e0af..7360bed 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE /*! Constructs an abstract scene index. */ -QGraphicsSceneIndex::QGraphicsSceneIndex(QObject *parent): QObject(parent) +QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene): QObject(scene), m_scene(scene) { } @@ -108,7 +108,7 @@ QGraphicsSceneIndex::~QGraphicsSceneIndex() */ QGraphicsScene* QGraphicsSceneIndex::scene() { - return mscene; + return m_scene; } /*! @@ -121,7 +121,7 @@ QGraphicsScene* QGraphicsSceneIndex::scene() */ void QGraphicsSceneIndex::updateItem(QGraphicsItem *item) { - removeItem(item); + removeItem(item,false); insertItem(item); } @@ -145,10 +145,10 @@ void QGraphicsSceneIndex::insertItems(const QList &items) \sa removeItem(), removeItems(), updateItems() */ -void QGraphicsSceneIndex::removeItems(const QList &items) +void QGraphicsSceneIndex::removeItems(const QList &items, bool itemsAreAboutToDie) { foreach (QGraphicsItem *item, items) - removeItem(item); + removeItem(item,itemsAreAboutToDie); } /*! @@ -164,6 +164,10 @@ void QGraphicsSceneIndex::updateItems(const QList &items) updateItem(item); } +void QGraphicsSceneIndex::updateIndex() +{ +} + QT_END_NAMESPACE #include "moc_qgraphicssceneindex.cpp" diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index d3b6c9f..3b034d4 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -64,27 +64,32 @@ class Q_GUI_EXPORT QGraphicsSceneIndex: public QObject Q_OBJECT public: - QGraphicsSceneIndex(QObject *parent = 0); + QGraphicsSceneIndex(QGraphicsScene *scene = 0); virtual ~QGraphicsSceneIndex(); + QGraphicsScene* scene(); + virtual void setRect(const QRectF &rect) = 0; virtual QRectF rect() const = 0; virtual void clear() = 0; virtual void insertItem(QGraphicsItem *item) = 0; - virtual void removeItem(QGraphicsItem *item) = 0; + virtual void removeItem(QGraphicsItem *items, bool itemIsAboutToDie) = 0; virtual void updateItem(QGraphicsItem *item); virtual void insertItems(const QList &items); - virtual void removeItems(const QList &items); + virtual void removeItems(const QList &items, bool itemsAreAboutToDie); virtual void updateItems(const QList &items); virtual QList items(const QPointF &point) = 0; virtual QList items(const QRectF &rect) = 0; - QGraphicsScene* scene(); + virtual QList indexedItems() = 0; + + virtual void updateIndex(); - QGraphicsScene* mscene; +private: + QGraphicsScene *m_scene; }; #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h new file mode 100644 index 0000000..30948d9 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENELINEARINDEX_P_H +#define QGRAPHICSSCENELINEARINDEX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + +private: + QRectF m_sceneRect; + QList m_items; + +public: + QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) + { + } + + virtual void setRect(const QRectF &rect) { + m_sceneRect = rect; + } + + virtual QRectF rect() const { + return m_sceneRect; + } + + virtual void clear() { + m_items.clear(); + } + + virtual void insertItem(QGraphicsItem *item) { + m_items << item; + } + + virtual void removeItem(QGraphicsItem *item, bool itemIsAboutToDie) { + Q_UNUSED(itemIsAboutToDie); + m_items.removeAll(item); + } + + virtual QList items(const QPointF &point) { + QList result; + foreach (QGraphicsItem *item, m_items) + if (item->sceneBoundingRect().contains(point)) + result << item; + return result; + } + + virtual QList items(const QRectF &rect) { + QList result; + foreach (QGraphicsItem *item, m_items) + if (item->sceneBoundingRect().intersects(rect)) + result << item; + return result; + } + + QList indexedItems() { + return m_items; + } +}; + +QT_END_NAMESPACE + +#endif // QT_NO_GRAPHICSVIEW + +#endif // QGRAPHICSSCENELINEARINDEX_P_H diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 955f2d3..3dca152 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -43,8 +43,8 @@ #include #include #include -#include -#include +#include +#include //TESTED_CLASS= @@ -88,12 +88,12 @@ void tst_QGraphicsSceneIndex::common_data() QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMethod) { QGraphicsSceneIndex *index = 0; - + QGraphicsScene *scene = new QGraphicsScene(); if (indexMethod == "bsp") - index = new QGraphicsSceneBspTree; + index = new QGraphicsSceneBspTreeIndex(scene); if (indexMethod == "linear") - index = new QGraphicsSceneLinearIndex; + index = new QGraphicsSceneLinearIndex(scene); return index; } @@ -104,8 +104,9 @@ void tst_QGraphicsSceneIndex::sceneRect_data() } void tst_QGraphicsSceneIndex::sceneRect() -{ - QGraphicsSceneIndex *index = new QGraphicsSceneBspTree; +{ + QGraphicsScene *scene = new QGraphicsScene(); + QGraphicsSceneIndex *index = new QGraphicsSceneBspTreeIndex(scene); index->setRect(QRectF(0, 0, 2000, 2000)); QCOMPARE(index->rect(), QRectF(0, 0, 2000, 2000)); } -- cgit v0.12 From 7d39e871e679be8afc10c7109a5cc396ead886f7 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 5 May 2009 17:56:43 +0200 Subject: Fix deletion of indexed items, and fix comments. It was not a good idea to delete all items in the middle of the loop when clearing the scene since we change the content of indexedItems by deleting one of them. We need to store first all top level items in a temporary list and then delete them in one shot (that will delete their children as well). --- src/gui/graphicsview/qgraphicsscene.cpp | 9 +++++---- tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e9fad68..f2e5f57 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -2549,13 +2549,16 @@ void QGraphicsScene::clearSelection() void QGraphicsScene::clear() { Q_D(QGraphicsScene); + QList items; // Recursive descent delete for (int i = 0; i < d->index->indexedItems().size(); ++i) { if (QGraphicsItem *item = d->index->indexedItems().at(i)) { if (!item->parentItem()) - delete item; + items << item; } } + //We delete all top level items + qDeleteAll(items); d->lastItemCount = 0; d->index->clear(); d->largestUntransformableItem = QRectF(); @@ -2693,9 +2696,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Add the item to this scene item->d_func()->scene = targetScene; - // Indexing requires sceneBoundingRect(), but because \a item might - // not be completely constructed at this point, we need to store it in - // a temporary list and schedule an indexing for later. + // Add the item in the index d->index->insertItem(item); // Add to list of toplevels if this item is a toplevel. diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp index f2a6bfd..617790c 100644 --- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp @@ -687,7 +687,6 @@ void tst_QGraphicsLayout::ownership() delete top; //don't crash after that. } - } QTEST_MAIN(tst_QGraphicsLayout) -- cgit v0.12 From 560ca373e4879f335a0ceeb3f8a769cc0e4297fe Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 6 May 2009 10:16:51 +0200 Subject: Make const when it needs to be. --- src/gui/graphicsview/qgraphicssceneindex.cpp | 4 ++-- src/gui/graphicsview/qgraphicssceneindex.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 7360bed..86a2fbb 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -104,9 +104,9 @@ QGraphicsSceneIndex::~QGraphicsSceneIndex() */ /*! - Returns the scene of this scene index. + Returns the scene of this index. */ -QGraphicsScene* QGraphicsSceneIndex::scene() +QGraphicsScene* QGraphicsSceneIndex::scene() const { return m_scene; } diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index 3b034d4..a782323 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -67,7 +67,7 @@ public: QGraphicsSceneIndex(QGraphicsScene *scene = 0); virtual ~QGraphicsSceneIndex(); - QGraphicsScene* scene(); + QGraphicsScene* scene() const; virtual void setRect(const QRectF &rect) = 0; virtual QRectF rect() const = 0; -- cgit v0.12 From 9281f4c219cec2e6a1e24b43e1edd0feb0fcfce5 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 29 May 2009 14:45:35 +0200 Subject: First bunch of changes after an very first API review This basically move some logic from the scene to the index base class. Lot of work need to be done in order to benefits from the device transform. The sorting needs to be move in the BSP tree. --- src/gui/graphicsview/graphicsview.pri | 1 + src/gui/graphicsview/qgraphicsitem.cpp | 17 +- src/gui/graphicsview/qgraphicsitem.h | 4 + src/gui/graphicsview/qgraphicsscene.cpp | 618 +++------------------ src/gui/graphicsview/qgraphicsscene.h | 9 + src/gui/graphicsview/qgraphicsscene_bsp.cpp | 12 +- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 8 +- src/gui/graphicsview/qgraphicsscene_p.h | 88 ++- .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 120 ++-- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 18 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 558 +++++++++++++++++-- src/gui/graphicsview/qgraphicssceneindex.h | 50 +- src/gui/graphicsview/qgraphicssceneindex_p.h | 96 ++++ src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 17 +- src/gui/graphicsview/qgraphicsview.cpp | 21 +- 15 files changed, 857 insertions(+), 780 deletions(-) create mode 100644 src/gui/graphicsview/qgraphicssceneindex_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 9097497..cc57892 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -10,6 +10,7 @@ HEADERS += \ graphicsview/qgraphicsscene_bsp_p.h \ graphicsview/qgraphicsscenelinearindex_p.h \ graphicsview/qgraphicssceneindex.h \ + graphicsview/qgraphicssceneindex_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicsview.h diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c1d44d3..fc5895c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -567,17 +567,6 @@ QT_BEGIN_NAMESPACE -// QRectF::intersects() returns false always if either the source or target -// rectangle's width or height are 0. This works around that problem. -static inline void _q_adjustRect(QRectF *rect) -{ - Q_ASSERT(rect); - if (!rect->width()) - rect->adjust(-0.00001, 0, 0.00001, 0); - if (!rect->height()) - rect->adjust(0, -0.00001, 0, 0.00001); -} - static inline void _q_adjustRect(QRect *rect) { Q_ASSERT(rect); @@ -6357,7 +6346,7 @@ void QGraphicsItem::addToIndex() return; } if (d_ptr->scene) - d_ptr->scene->d_func()->index->insertItem(this); + d_ptr->scene->d_func()->index->addItem(this); d_ptr->updateHelper(); } @@ -6372,7 +6361,7 @@ void QGraphicsItem::removeFromIndex() { d_ptr->updateHelper(); if (d_ptr->scene) - d_ptr->scene->d_func()->index->removeItem(this,false); + d_ptr->scene->d_func()->index->removeItem(this); } /*! @@ -6393,7 +6382,7 @@ void QGraphicsItem::prepareGeometryChange() if (d_ptr->scene) { d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); - scenePrivate->index->updateItem(this); + scenePrivate->index->prepareBoundingRectChange(this); } if (d_ptr->inSetPosHelper) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index cb86020..e244c13 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -409,6 +409,8 @@ protected: virtual void setExtension(Extension extension, const QVariant &variant); virtual QVariant extension(const QVariant &variant) const; + bool operator<(const QGraphicsItem *other) const; + protected: QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); @@ -430,6 +432,8 @@ private: friend class QGraphicsWidget; friend class QGraphicsWidgetPrivate; friend class QGraphicsProxyWidgetPrivate; + friend class QGraphicsSceneIndex; + friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 51c8294..9b6d40b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -249,65 +249,6 @@ QT_BEGIN_NAMESPACE -static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) -{ - qreal xp = s.left(); - qreal yp = s.top(); - qreal w = s.width(); - qreal h = s.height(); - qreal l1 = xp; - qreal r1 = xp; - if (w < 0) - l1 += w; - else - r1 += w; - - qreal l2 = r.left(); - qreal r2 = r.left(); - if (w < 0) - l2 += r.width(); - else - r2 += r.width(); - - if (l1 >= r2 || l2 >= r1) - return false; - - qreal t1 = yp; - qreal b1 = yp; - if (h < 0) - t1 += h; - else - b1 += h; - - qreal t2 = r.top(); - qreal b2 = r.top(); - if (r.height() < 0) - t2 += r.height(); - else - b2 += r.height(); - - return !(t1 >= b2 || t2 >= b1); -} - -// QRectF::intersects() returns false always if either the source or target -// rectangle's width or height are 0. This works around that problem. -static inline void _q_adjustRect(QRectF *rect) -{ - Q_ASSERT(rect); - if (!rect->width()) - rect->adjust(-0.00001, 0, 0.00001, 0); - if (!rect->height()) - rect->adjust(0, -0.00001, 0, 0.00001); -} - -static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) -{ - Q_ASSERT(item); - QRectF boundingRect(item->boundingRect()); - _q_adjustRect(&boundingRect); - return boundingRect; -} - static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent) { hover->setWidget(mouseEvent->widget()); @@ -374,21 +315,6 @@ void QGraphicsScenePrivate::init() /*! \internal */ -QList QGraphicsScenePrivate::estimateItemsInRect(const QRectF &rect) const -{ - const_cast(this)->_q_updateSortCache(); - - // ### Only do this once in a while. - QGraphicsScenePrivate *that = const_cast(this); - - // Get items from index - return that->index->items(rect); - -} - -/*! - \internal -*/ void QGraphicsScenePrivate::_q_emitUpdated() { Q_Q(QGraphicsScene); @@ -528,7 +454,7 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) item->clearFocus(); //We ask for a removing in the index - this->index->removeItem(item, true); + this->index->deleteItem(item); // Reset the mouse grabber and focus item data. if (item == focusItem) @@ -1145,444 +1071,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } - -QList QGraphicsScenePrivate::items_helper(const QPointF &pos) const -{ - QList items; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect = QRectF(pos, QSize(1,1)); - foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (item->contains(xinv.map(pos))) { - items << item; - keep = true; - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - childItems_helper(&items, item, xinv.map(pos)); - } - } - - sortItems(&items, Qt::AscendingOrder, sortCacheEnabled); - return items; -} - -QList QGraphicsScenePrivate::items_helper(const QRectF &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - QList items; - - QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - QRectF mbr = x.mapRect(br); - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(mbr))) { - items << item; - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path.isEmpty()) - path.addRect(rect); - if (itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (x.type() <= QTransform::TxScale) { - // Rect - childItems_helper(&items, item, xinv.mapRect(rect), mode); - } else { - // Polygon - childItems_helper(&items, item, xinv.map(rect), mode); - } - } - } - } - - if (order != Qt::SortOrder(-1)) - sortItems(&items, order, sortCacheEnabled); - return items; -} - -QList QGraphicsScenePrivate::items_helper(const QPolygonF &polygon, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - QList items; - - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItemsInRect(polyRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - childItems_helper(&items, item, xinv.map(polygon), mode); - } - } - - if (order != Qt::SortOrder(-1)) - sortItems(&items, order, sortCacheEnabled); - return items; -} - -QList QGraphicsScenePrivate::items_helper(const QPainterPath &path, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - QList items; - QRectF pathRect(path.controlPointRect()); - _q_adjustRect(&pathRect); - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItemsInRect(pathRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Path contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - childItems_helper(&items, item, xinv.map(path), mode); - } - } - - if (order != Qt::SortOrder(-1)) - sortItems(&items, order, sortCacheEnabled); - return items; -} - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - // ### is this needed? - if (parentClip && !parent->boundingRect().contains(pos)) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - if (item->contains(item->mapFromParent(pos))) { - items->append(item); - keep = true; - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) - // Recurse into children. - childItems_helper(items, item, item->mapFromParent(pos)); - } -} - - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QPainterPath path; - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - QRectF mbr = item->mapRectToParent(br); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { - items->append(item); - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(rect, mbr)) { - if (path == QPainterPath()) - path.addRect(rect); - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children. - if (!item->d_ptr->hasTransform || item->transform().type() <= QTransform::TxScale) { - // Rect - childItems_helper(items, item, item->mapRectFromParent(rect), mode); - } else { - // Polygon - childItems_helper(items, item, item->mapFromParent(rect), mode); - } - } - } -} - - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QPainterPath path; - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(polygon), mode); - } - } -} - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF pathRect(path.boundingRect()); - _q_adjustRect(&pathRect); - QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(path), mode); - } - } -} - void QGraphicsScenePrivate::invalidateSortCache() { Q_Q(QGraphicsScene); @@ -1709,7 +1197,8 @@ void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder) void QGraphicsScenePrivate::_q_updateSortCache() { - index->updateIndex(); + //### FIXME + //index->updateIndex(); if (!sortCacheEnabled || !updatingSortCache) return; @@ -1719,8 +1208,8 @@ void QGraphicsScenePrivate::_q_updateSortCache() QList topLevels; - for (int i = 0; i < index->indexedItems().count(); ++i) { - QGraphicsItem *item = index->indexedItems().at(i); + for (int i = 0; i < index->items().count(); ++i) { + QGraphicsItem *item = index->items().at(i); if (item && item->parentItem() == 0) topLevels << item; } @@ -1933,8 +1422,7 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - d->index->updateIndex(); - return d->hasSceneRect ? d->index->rect() : d->growingItemsBoundingRect; + return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; } void QGraphicsScene::setSceneRect(const QRectF &rect) { @@ -1942,7 +1430,7 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) if (rect != d->sceneRect) { d->hasSceneRect = !rect.isNull(); d->sceneRect = rect; - d->index->setRect(rect); + d->index->sceneRectChanged(rect); emit sceneRectChanged(rect); } } @@ -2106,9 +1594,11 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) } if (d->indexMethod == CustomIndex && method == BspTreeIndex) { + //We re-add in the new index all items from the old index QGraphicsSceneIndex *oldIndex = d->index; d->index = new QGraphicsSceneBspTreeIndex(this); - d->index->insertItems(oldIndex->items(oldIndex->rect())); + for (int i = 0 ; i < oldIndex->items().size() ; ++ i) + d->index->addItem(oldIndex->items().at(i)); } if (d->indexMethod == CustomIndex && method == NoIndex) { @@ -2246,7 +1736,7 @@ QRectF QGraphicsScene::itemsBoundingRect() const QList QGraphicsScene::items() const { Q_D(const QGraphicsScene); - return d->index->indexedItems(); + return d->index->items(); } /*! @@ -2259,7 +1749,7 @@ QList QGraphicsScene::items() const QList QGraphicsScene::items(const QPointF &pos) const { Q_D(const QGraphicsScene); - return d->items_helper(pos); + return d->index->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder); } @@ -2279,7 +1769,7 @@ QList QGraphicsScene::items(const QPointF &pos) const QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - return d->items_helper(rect, mode, Qt::AscendingOrder); + return d->index->items(rect, mode, Qt::AscendingOrder); } /*! @@ -2303,7 +1793,7 @@ QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - return d->items_helper(polygon, mode, Qt::AscendingOrder); + return d->index->items(polygon, mode, Qt::AscendingOrder); } /*! @@ -2320,7 +1810,74 @@ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - return d->items_helper(path, mode, Qt::AscendingOrder); + return d->index->items(path, mode, Qt::AscendingOrder); +} + +/*! + Returns all visible items at position \a pos in the scene. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a path are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(pos, mode, order, deviceTransform); +} + +/*! + \fn QList QGraphicsScene::items(const QRectF &rectangle, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a rectangle. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a rectangle are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(rect, mode, order, deviceTransform); +} + +/*! + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the polygon \a polygon. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a polygon are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(polygon, mode, order, deviceTransform); +} + +/*! + \overload + + Returns all visible items that, depending on \a path, are either inside or + intersect with the path \a path. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a path are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(path, mode, order, deviceTransform); } /*! @@ -2344,10 +1901,11 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, } QList tmp; - foreach (QGraphicsItem *itemInVicinity, d->estimateItemsInRect(item->sceneBoundingRect())) { + foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::AscendingOrder, QTransform())) { if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode)) tmp << itemInVicinity; } + //### remove me d->sortItems(&tmp, Qt::AscendingOrder, d->sortCacheEnabled); return tmp; } @@ -2517,8 +2075,8 @@ void QGraphicsScene::clear() Q_D(QGraphicsScene); QList items; // Recursive descent delete - for (int i = 0; i < d->index->indexedItems().size(); ++i) { - if (QGraphicsItem *item = d->index->indexedItems().at(i)) { + for (int i = 0; i < d->index->items().size(); ++i) { + if (QGraphicsItem *item = d->index->items().at(i)) { if (!item->parentItem()) items << item; } @@ -2663,7 +2221,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) item->d_func()->scene = targetScene; // Add the item in the index - d->index->insertItem(item); + d->index->addItem(item); // Add to list of toplevels if this item is a toplevel. if (!item->d_ptr->parent) @@ -3023,7 +2581,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - d->index->removeItem(item, false); + d->index->deleteItem(item); if (item == d->tabFocusFirst) { QGraphicsWidget *widget = static_cast(item); diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 6476b8c..5d70087 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -156,10 +156,17 @@ public: QRectF itemsBoundingRect() const; QList items() const; + + QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QPointF &pos) const; QList items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; + QList collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QGraphicsItem *itemAt(const QPointF &pos) const; @@ -291,6 +298,8 @@ private: friend class QGraphicsViewPrivate; friend class QGraphicsWidget; friend class QGraphicsWidgetPrivate; + friend class QGraphicsSceneIndex; + friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; }; diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index f8fa450..5c1820f 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -143,7 +143,7 @@ void QGraphicsSceneBspTree::removeItems(const QSet &items) } } -QList QGraphicsSceneBspTree::items(const QRectF &rect) +QList QGraphicsSceneBspTree::items(const QRectF &rect) const { QList tmp; findVisitor->foundItems = &tmp; @@ -151,7 +151,7 @@ QList QGraphicsSceneBspTree::items(const QRectF &rect) return tmp; } -QList QGraphicsSceneBspTree::items(const QPointF &pos) +QList QGraphicsSceneBspTree::items(const QPointF &pos) const { QList tmp; findVisitor->foundItems = &tmp; @@ -235,7 +235,7 @@ void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth, int index) } } -void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) +void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) const { if (nodes.isEmpty()) return; @@ -245,7 +245,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con switch (node.type) { case Node::Leaf: { - visitor->visit(&leaves[node.leafIndex]); + visitor->visit(const_cast*>(&leaves[node.leafIndex])); break; } case Node::Vertical: @@ -265,7 +265,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con } } -void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) +void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) const { if (nodes.isEmpty()) return; @@ -275,7 +275,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con switch (node.type) { case Node::Leaf: { - visitor->visit(&leaves[node.leafIndex]); + visitor->visit(const_cast*>(&leaves[node.leafIndex])); break; } case Node::Vertical: diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index e6ceb78..a13d862 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -92,8 +92,8 @@ public: void removeItem(QGraphicsItem *item, const QRectF &rect); void removeItems(const QSet &items); - QList items(const QRectF &rect); - QList items(const QPointF &pos); + QList items(const QRectF &rect) const; + QList items(const QPointF &pos) const; int leafCount() const; inline int firstChildIndex(int index) const @@ -106,8 +106,8 @@ public: private: void initialize(const QRectF &rect, int depth, int index); - void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0); - void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0); + void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0) const; + void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0) const; void findItems(QList *foundItems, const QRectF &rect, int index); void findItems(QList *foundItems, const QPointF &pos, int index); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 2c0d464..a035159 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -88,8 +88,6 @@ public: QGraphicsScene::ItemIndexMethod indexMethod; int bspTreeDepth; - QList estimateItemsInRect(const QRectF &rect) const; - int lastItemCount; QGraphicsSceneIndex *index; @@ -189,33 +187,6 @@ public: void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent); void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - - QList items_helper(const QPointF &pos) const; - QList items_helper(const QRectF &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const; - QList items_helper(const QPolygonF &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const; - QList items_helper(const QPainterPath &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const; - bool sortCacheEnabled; bool updatingSortCache; void invalidateSortCache(); @@ -255,6 +226,65 @@ public: mutable QVector freeSceneTransformSlots; }; +static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) +{ + qreal xp = s.left(); + qreal yp = s.top(); + qreal w = s.width(); + qreal h = s.height(); + qreal l1 = xp; + qreal r1 = xp; + if (w < 0) + l1 += w; + else + r1 += w; + + qreal l2 = r.left(); + qreal r2 = r.left(); + if (w < 0) + l2 += r.width(); + else + r2 += r.width(); + + if (l1 >= r2 || l2 >= r1) + return false; + + qreal t1 = yp; + qreal b1 = yp; + if (h < 0) + t1 += h; + else + b1 += h; + + qreal t2 = r.top(); + qreal b2 = r.top(); + if (r.height() < 0) + t2 += r.height(); + else + b2 += r.height(); + + return !(t1 >= b2 || t2 >= b1); +} + +// QRectF::intersects() returns false always if either the source or target +// rectangle's width or height are 0. This works around that problem. +static inline void _q_adjustRect(QRectF *rect) +{ + Q_ASSERT(rect); + if (!rect->width()) + rect->adjust(-0.00001, 0, 0.00001, 0); + if (!rect->height()) + rect->adjust(0, -0.00001, 0, 0.00001); +} + +static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) +{ + Q_ASSERT(item); + QRectF boundingRect(item->boundingRect()); + _q_adjustRect(&boundingRect); + return boundingRect; +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index ebc167a..1f2b81d 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -61,18 +61,6 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } -void QGraphicsSceneBspTreeIndex::setRect(const QRectF &rect) -{ - m_sceneRect = rect; - resetIndex(); -} - -QRectF QGraphicsSceneBspTreeIndex::rect() const -{ - const_cast(this)->updateIndex(); - return m_sceneRect; -} - void QGraphicsSceneBspTreeIndex::clear() { bsp.clear(); @@ -82,7 +70,7 @@ void QGraphicsSceneBspTreeIndex::clear() unindexedItems.clear(); } -void QGraphicsSceneBspTreeIndex::insertItem(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { // Prevent reusing a recently deleted pointer: purge all removed items // from our lists. @@ -113,42 +101,43 @@ void QGraphicsSceneBspTreeIndex::addToIndex(QGraphicsItem *item) } } -void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item, bool itemIsAboutToDie) +void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { - if (!itemIsAboutToDie) { - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - removeFromIndex(item); - - // Remove from our item lists. - int index = item->d_func()->index; - if (index != -1) { - freeItemIndexes << index; - m_indexedItems[index] = 0; - } else { - unindexedItems.removeAll(item); - } + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + removeFromIndex(item); + // Remove from our item lists. + int index = item->d_func()->index; + if (index != -1) { + freeItemIndexes << index; + m_indexedItems[index] = 0; } else { - int index = item->d_func()->index; - if (index != -1) { - // Important: The index is useless until purgeRemovedItems() is - // called. - m_indexedItems[index] = (QGraphicsItem *)0; - if (!purgePending) { - purgePending = true; - scene()->update(); - } - removedItems << item; - } else { - // Recently added items are purged immediately. unindexedItems() never - // contains stale items. - unindexedItems.removeAll(item); + unindexedItems.removeAll(item); + } +} + +void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) +{ + int index = item->d_func()->index; + if (index != -1) { + // Important: The index is useless until purgeRemovedItems() is + // called. + m_indexedItems[index] = (QGraphicsItem *)0; + if (!purgePending) { + purgePending = true; scene()->update(); } + removedItems << item; + } else { + // Recently added items are purged immediately. unindexedItems() never + // contains stale items. + unindexedItems.removeAll(item); + scene()->update(); } } + /*! \internal */ @@ -173,41 +162,17 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) startIndexTimer(); } -void QGraphicsSceneBspTreeIndex::updateItem(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - removeFromIndex(item); -} - -QList QGraphicsSceneBspTreeIndex::items(const QPointF &point) -{ - purgeRemovedItems(); - QList rectItems = bsp.items(QRectF(point, QSizeF(1, 1))); - // Fill in with any unindexed items - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { - QRectF boundingRect = item->sceneBoundingRect(); - if (boundingRect.intersects(QRectF(point, QSizeF(1, 1)))) { - item->d_ptr->itemDiscovered = 1; - rectItems << item; - } - } - } - } - - // Reset the discovered state of all discovered items - for (int i = 0; i < rectItems.size(); ++i) - rectItems.at(i)->d_func()->itemDiscovered = 0; - - return rectItems; + removeFromIndex(const_cast(item)); } -QList QGraphicsSceneBspTreeIndex::items(const QRectF &rect) +QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - purgeRemovedItems(); + const_cast(this)->purgeRemovedItems(); QList rectItems = bsp.items(rect); // Fill in with any unindexed items for (int i = 0; i < unindexedItems.size(); ++i) { @@ -229,9 +194,9 @@ QList QGraphicsSceneBspTreeIndex::items(const QRectF &rect) return rectItems; } -QList QGraphicsSceneBspTreeIndex::indexedItems() +QList QGraphicsSceneBspTreeIndex::items() const { - purgeRemovedItems(); + const_cast(this)->purgeRemovedItems(); // If freeItemIndexes is empty, we know there are no holes in indexedItems and // unindexedItems. if (freeItemIndexes.isEmpty()) { @@ -250,11 +215,6 @@ QList QGraphicsSceneBspTreeIndex::indexedItems() return itemList; } -void QGraphicsSceneBspTreeIndex::updateIndex() -{ - _q_updateIndex(); -} - int QGraphicsSceneBspTreeIndex::bspDepth() { return bspTreeDepth; @@ -266,6 +226,12 @@ void QGraphicsSceneBspTreeIndex::setBspDepth(int depth) resetIndex(); } +void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) +{ + m_sceneRect = rect; + resetIndex(); +} + bool QGraphicsSceneBspTreeIndex::event(QEvent *event) { switch (event->type()) { diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 74af910..63cd0e1 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -62,27 +62,23 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - void setRect(const QRectF &rect); - virtual QRectF rect() const; - void clear(); - void insertItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item, bool itemIsAboutToDie); - void updateItem(QGraphicsItem *item); - - QList items(const QPointF &point); - QList items(const QRectF &rect); + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); - QList indexedItems(); + QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - void updateIndex(); + QList items() const; int bspDepth(); void setBspDepth(int depth); protected: bool event(QEvent *event); + void sceneRectChanged(const QRectF &rect); public slots : void _q_updateIndex(); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 86a2fbb..870a62a 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -40,16 +40,244 @@ ****************************************************************************/ #include "qgraphicssceneindex.h" +#include "qgraphicssceneindex_p.h" #include "qgraphicsscene.h" +#include "qgraphicsitem_p.h" +#include "qgraphicsscene_p.h" #ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE /*! + Constructs a private scene index. +*/ +QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene) +{ +} + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPointF &pos) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + // ### is this needed? + if (parentClip && !parent->boundingRect().contains(pos)) + return; + + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items and all their children. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + if (item->contains(item->mapFromParent(pos))) { + items->append(item); + keep = true; + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) + // Recurse into children. + childItems_helper(items, item, item->mapFromParent(pos)); + } +} + + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QRectF &rect, + Qt::ItemSelectionMode mode) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + QRectF adjustedRect(rect); + _q_adjustRect(&adjustedRect); + QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent)); + if (r.isEmpty()) + return; + + QPainterPath path; + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items and all their children. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + QRectF mbr = item->mapRectToParent(br); + if (mode >= Qt::ContainsItemBoundingRect) { + // Rect intersects/contains item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) + || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { + items->append(item); + keep = true; + } + } else { + // Rect intersects/contains item's shape + if (QRectF_intersects(rect, mbr)) { + if (path == QPainterPath()) + path.addRect(rect); + if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + // Recurse into children. + if (!item->d_ptr->hasTransform || item->transform().type() <= QTransform::TxScale) { + // Rect + childItems_helper(items, item, item->mapRectFromParent(rect), mode); + } else { + // Polygon + childItems_helper(items, item, item->mapFromParent(rect), mode); + } + } + } +} + + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPolygonF &polygon, + Qt::ItemSelectionMode mode) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + QRectF polyRect(polygon.boundingRect()); + _q_adjustRect(&polyRect); + QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent)); + if (r.isEmpty()) + return; + + QPainterPath path; + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if (path == QPainterPath()) + path.addPolygon(polygon); + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { + items->append(item); + keep = true; + } + } else { + // Polygon contains/intersects item's shape + if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { + if (path == QPainterPath()) + path.addPolygon(polygon); + if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + // Recurse into children that clip children. + childItems_helper(items, item, item->mapFromParent(polygon), mode); + } + } +} + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPainterPath &path, + Qt::ItemSelectionMode mode) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + QRectF pathRect(path.boundingRect()); + _q_adjustRect(&pathRect); + QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent)); + if (r.isEmpty()) + return; + + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { + items->append(item); + keep = true; + } + } else { + // Path contains/intersects item's shape + if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { + if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + // Recurse into children that clip children. + childItems_helper(items, item, item->mapFromParent(path), mode); + } + } +} + +/*! Constructs an abstract scene index. */ -QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene): QObject(scene), m_scene(scene) +QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) +: QObject(*new QGraphicsSceneIndexPrivate(scene)) { } @@ -62,109 +290,325 @@ QGraphicsSceneIndex::~QGraphicsSceneIndex() } /*! - \fn virtual void setRect(const QRectF &rect) = 0 - - This pure virtual function is called when the scene changes its bounding - rectangle. - - \sa rect(), QGraphicsScene::setSceneRect + Returns the scene of this index. */ - +QGraphicsScene* QGraphicsSceneIndex::scene() const +{ + Q_D(const QGraphicsSceneIndex); + return d->scene; +} /*! - \fn virtual QRectF rect() const = 0 + \fn QList items() const = 0 - This pure virtual function returns the bounding rectangle of this - scene index. It could be as large as or larger than the scene - bounding rectangle, depending on the implementation of the - scene index. + This pure virtual function return the list of items that are actually in the index. - \sa setRect(), QGraphicsScene::sceneRect */ -/*! - \fn virtual void clear() = 0 +QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + QRectF adjustedRect = QRectF(pos, QSize(1,1)); + foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + // Rect intersects/contains item's shape + if (QRectF_intersects(adjustedRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (item->contains(xinv.map(pos))) { + items << item; + keep = true; + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + // Recurse into children that clip children. + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + d->childItems_helper(&items, item, xinv.map(pos)); + } + } + + d->scene->d_func()->sortItems(&items, Qt::AscendingOrder, d->scene->d_func()->sortCacheEnabled); + return items; +} - This pure virtual function removes all items in the scene index. -*/ +QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + + QPainterPath path; + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + QRectF adjustedRect(rect); + _q_adjustRect(&adjustedRect); + foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Rect intersects/contains item's bounding rect + QRectF mbr = x.mapRect(br); + if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) + || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(mbr))) { + items << item; + keep = true; + } + } else { + // Rect intersects/contains item's shape + if (QRectF_intersects(adjustedRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (path.isEmpty()) + path.addRect(rect); + if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { + items << item; + keep = true; + } + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + // Recurse into children that clip children. + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (x.type() <= QTransform::TxScale) { + // Rect + d->childItems_helper(&items, item, xinv.mapRect(rect), mode); + } else { + // Polygon + d->childItems_helper(&items, item, xinv.map(rect), mode); + } + } + } + } + + if (order != Qt::SortOrder(-1)) + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + return items; +} -/*! - \fn virtual void insertItem(QGraphicsItem *item) = 0 +QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + + QRectF polyRect(polygon.boundingRect()); + _q_adjustRect(&polyRect); + QPainterPath path; + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + foreach (QGraphicsItem *item, estimateItems(polyRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if (path == QPainterPath()) + path.addPolygon(polygon); + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { + items << item; + keep = true; + } + } else { + // Polygon contains/intersects item's shape + if (QRectF_intersects(polyRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (path == QPainterPath()) + path.addPolygon(polygon); + if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { + items << item; + keep = true; + } + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + // Recurse into children that clip children. + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + d->childItems_helper(&items, item, xinv.map(polygon), mode); + } + } + + if (order != Qt::SortOrder(-1)) + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + return items; +} +QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + QRectF pathRect(path.controlPointRect()); + _q_adjustRect(&pathRect); + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + foreach (QGraphicsItem *item, estimateItems(pathRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Path contains/intersects item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { + items << item; + keep = true; + } + } else { + // Path contains/intersects item's shape + if (QRectF_intersects(pathRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { + items << item; + keep = true; + } + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + d->childItems_helper(&items, item, xinv.map(path), mode); + } + } + + if (order != Qt::SortOrder(-1)) + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + return items; +} - This pure virtual function inserts an item to the scene index. +/*! + This pure virtual function return an estimation of items at position \a pos. - \sa removeItem(), updateItem(), insertItems() */ +QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + return estimateItems(QRectF(point, QSize(1,1)), order, deviceTransform); +} /*! - \fn virtual void removeItem(QGraphicsItem *item) = 0 + \fn virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 - This pure virtual function removes an item to the scene index. + This pure virtual function return an estimation of items in the \a rect. - \sa insertItem(), updateItem(), removeItems() */ + /*! - Returns the scene of this index. + This virtual function removes all items in the scene index. */ -QGraphicsScene* QGraphicsSceneIndex::scene() const +void QGraphicsSceneIndex::clear() { - return m_scene; + for (int i = 0 ; i < items().size(); ++i) + removeItem(items().at(i)); } /*! - Updates an item when its geometry has changed. + \fn virtual void addItem(QGraphicsItem *item) = 0 - The default implemention will remove the item from the index - and then insert it again. + This pure virtual function inserts an item to the scene index. - \sa insertItem(), removeItem(), updateItems() + \sa removeItem(), deleteItem() */ -void QGraphicsSceneIndex::updateItem(QGraphicsItem *item) -{ - removeItem(item,false); - insertItem(item); -} /*! - Inserts a list of items to the index. + \fn virtual void removeItem(QGraphicsItem *item) = 0 - The default implemention will insert the items one by one. + This pure virtual function removes an item to the scene index. - \sa insertItem(), removeItems(), updateItems() + \sa addItem(), deleteItem() */ -void QGraphicsSceneIndex::insertItems(const QList &items) + +/*! + This method is called when an item has been deleted. + The default implementation call removeItem. Be carefull, + if your implementation of removeItem use pure virtual method + of QGraphicsItem like boundingRect(), then you should reimplement + this method. + + \sa addItem(), removeItem() +*/ +void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) { - foreach (QGraphicsItem *item, items) - insertItem(item); + removeItem(item); } /*! - Removes a list of items from the index. + This virtual function is called by QGraphicsItem to notify the index + that some part of the item's state changes. By reimplementing this + function, your can react to a change, and in some cases, (depending on \a + change,) adjustments in the index can be made. - The default implemention will remove the items one by one. + \a change is the parameter of the item that is changing. \a value is the + value that changed; the type of the value depends on \a change. - \sa removeItem(), removeItems(), updateItems() + The default implementation does nothing. + + \sa GraphicsItemChange */ -void QGraphicsSceneIndex::removeItems(const QList &items, bool itemsAreAboutToDie) +void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value) { - foreach (QGraphicsItem *item, items) - removeItem(item,itemsAreAboutToDie); } /*! - Update a list of items which have changed the geometry. - - The default implemention will update the items one by one. + Notify the index for a geometry change of an item. - \sa updateItem(), insertItems(), removeItems() + \sa QGraphicsItem::prepareGeometryChange */ -void QGraphicsSceneIndex::updateItems(const QList &items) +void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { - foreach (QGraphicsItem *item, items) - updateItem(item); } -void QGraphicsSceneIndex::updateIndex() +/*! + This virtual function is called when the scene changes its bounding + rectangle. + \sa QGraphicsScene::sceneRect +*/ +void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) { } diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index a782323..da3096e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -44,6 +44,8 @@ #include #include +#include +#include QT_BEGIN_HEADER @@ -53,7 +55,7 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -class QGraphicsItem; +class QGraphicsSceneIndexPrivate; class QGraphicsScene; class QRectF; class QPointF; @@ -67,29 +69,31 @@ public: QGraphicsSceneIndex(QGraphicsScene *scene = 0); virtual ~QGraphicsSceneIndex(); - QGraphicsScene* scene() const; - - virtual void setRect(const QRectF &rect) = 0; - virtual QRectF rect() const = 0; - virtual void clear() = 0; - - virtual void insertItem(QGraphicsItem *item) = 0; - virtual void removeItem(QGraphicsItem *items, bool itemIsAboutToDie) = 0; - virtual void updateItem(QGraphicsItem *item); - - virtual void insertItems(const QList &items); - virtual void removeItems(const QList &items, bool itemsAreAboutToDie); - virtual void updateItems(const QList &items); - - virtual QList items(const QPointF &point) = 0; - virtual QList items(const QRectF &rect) = 0; - - virtual QList indexedItems() = 0; - - virtual void updateIndex(); - + QGraphicsScene *scene() const; + + virtual QList items() const = 0; + virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const; + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0; + +protected: + virtual void clear(); + virtual void addItem(QGraphicsItem *item) = 0; + virtual void removeItem(QGraphicsItem *item) = 0; + virtual void deleteItem(QGraphicsItem *item); + + virtual void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void prepareBoundingRectChange(const QGraphicsItem *item); + virtual void sceneRectChanged(const QRectF &rect); + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; + friend class QGraphicsItem; private: - QGraphicsScene *m_scene; + Q_DECLARE_PRIVATE(QGraphicsSceneIndex) }; #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h new file mode 100644 index 0000000..f2cdca3 --- /dev/null +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENEINDEX_P_H +#define QGRAPHICSSCENEINDEX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicssceneindex.h" + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include + +QT_BEGIN_NAMESPACE + +class QGraphicsScene; + +class QGraphicsSceneIndexPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsSceneIndex) +public: + QGraphicsSceneIndexPrivate(QGraphicsScene *scene); + + + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPointF &pos) const; + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QRectF &rect, + Qt::ItemSelectionMode mode) const; + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPolygonF &polygon, + Qt::ItemSelectionMode mode) const; + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPainterPath &path, + Qt::ItemSelectionMode mode) const; + + QGraphicsScene *scene; +}; + +QT_END_NAMESPACE + +#endif // QGRAPHICSSCENEINDEX_P_H + +#endif diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 30948d9..dc45a17 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -89,24 +89,15 @@ public: m_items.clear(); } - virtual void insertItem(QGraphicsItem *item) { + virtual void addItem(QGraphicsItem *item) { m_items << item; } - virtual void removeItem(QGraphicsItem *item, bool itemIsAboutToDie) { - Q_UNUSED(itemIsAboutToDie); + virtual void removeItem(QGraphicsItem *item) { m_items.removeAll(item); } - virtual QList items(const QPointF &point) { - QList result; - foreach (QGraphicsItem *item, m_items) - if (item->sceneBoundingRect().contains(point)) - result << item; - return result; - } - - virtual QList items(const QRectF &rect) { + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { QList result; foreach (QGraphicsItem *item, m_items) if (item->sceneBoundingRect().intersects(rect)) @@ -114,7 +105,7 @@ public: return result; } - QList indexedItems() { + QList items() const { return m_items; } }; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 10b837a..91f97a1 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -791,19 +791,6 @@ QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const Q return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect(); } -// QRectF::intersects() returns false always if either the source or target -// rectangle's width or height are 0. This works around that problem. -static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) -{ - Q_ASSERT(item); - QRectF boundingRect(item->boundingRect()); - if (!boundingRect.width()) - boundingRect.adjust(-0.00001, 0, 0.00001, 0); - if (!boundingRect.height()) - boundingRect.adjust(0, -0.00001, 0, 0.00001); - return boundingRect; -} - /*! \internal */ @@ -1094,7 +1081,7 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull() && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale); if (simpleRectLookup) { - return scene->d_func()->items_helper(exposedRegionSceneBounds, + return scene->d_func()->index->items(exposedRegionSceneBounds, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); } @@ -1109,7 +1096,7 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg const QPainterPath exposedPath(qt_regionToPath(adjustedRegion)); if (scene->d_func()->largestUntransformableItem.isNull()) { const QPainterPath exposedScenePath(q->mapToScene(exposedPath)); - return scene->d_func()->items_helper(exposedScenePath, + return scene->d_func()->index->items(exposedScenePath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); } @@ -2143,7 +2130,7 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat // First build a (potentially large) list of all items in the vicinity // that might be untransformable. - QList allCandidates = scene->d_func()->estimateItemsInRect(adjustedRect); + QList allCandidates = scene->d_func()->index->estimateItems(adjustedRect, order, q->transform()); // Then find the minimal list of items that are inside \a path, and // convert it to a set. @@ -2154,6 +2141,8 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat QList result; + //### this will disapear + // Run through all candidates and keep all items that are in candSet, or // are untransformable and collide with \a path. ### We can improve this // algorithm. -- cgit v0.12 From 32155ed07a6f8b8c831db6ba219395b4825fa9fd Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 29 May 2009 15:15:58 +0200 Subject: Fix a wrong parenting. --- src/gui/graphicsview/qgraphicssceneindex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 870a62a..36da295 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -277,7 +277,7 @@ void QGraphicsSceneIndexPrivate::childItems_helper(QList *items Constructs an abstract scene index. */ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) -: QObject(*new QGraphicsSceneIndexPrivate(scene)) +: QObject(*new QGraphicsSceneIndexPrivate(scene), scene) { } -- cgit v0.12 From 53187fabdbfb8a513e735fdd034e1a9fbbccc9cd Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 29 May 2009 17:18:38 +0200 Subject: Add an API to know the indexed rect of the index. Usefull for the POV of the scene and let the BSP update its internal structure before the next event loop reentrancy. --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp | 7 +++++++ src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h | 1 + src/gui/graphicsview/qgraphicssceneindex.cpp | 10 ++++++++++ src/gui/graphicsview/qgraphicssceneindex.h | 2 ++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9b6d40b..479a548 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1422,7 +1422,7 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; + return d->index->indexedRect(); } void QGraphicsScene::setSceneRect(const QRectF &rect) { diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index 1f2b81d..8a26447 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -61,6 +61,13 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } + +QRectF QGraphicsSceneBspTreeIndex::indexedRect() +{ + _q_updateIndex(); + return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; +} + void QGraphicsSceneBspTreeIndex::clear() { bsp.clear(); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 63cd0e1..7a6ea0b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -61,6 +61,7 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex Q_OBJECT public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + QRectF indexedRect(); void clear(); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 36da295..fe3a68a 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -297,6 +297,16 @@ QGraphicsScene* QGraphicsSceneIndex::scene() const Q_D(const QGraphicsSceneIndex); return d->scene; } + +/*! + Returns the indexed area for the index +*/ +QRectF QGraphicsSceneIndex::indexedRect() +{ + Q_D(const QGraphicsSceneIndex); + return d->scene->d_func()->sceneRect; +} + /*! \fn QList items() const = 0 diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index da3096e..11d9aae 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -71,6 +71,8 @@ public: QGraphicsScene *scene() const; + virtual QRectF indexedRect(); + virtual QList items() const = 0; virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; -- cgit v0.12 From 427c4d6b0a8b3004c86facd382de33c171c0458b Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 2 Jun 2009 17:45:27 +0200 Subject: Fix all auto-tests regressions. --- src/gui/graphicsview/qgraphicsscene.cpp | 15 +++++++++------ src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp | 11 ++++++----- src/gui/graphicsview/qgraphicssceneindex.cpp | 2 +- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 3 +++ .../auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 4 ++-- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 479a548..0172a23 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -453,7 +453,9 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) // chain. item->clearFocus(); - //We ask for a removing in the index + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. this->index->deleteItem(item); // Reset the mouse grabber and focus item data. @@ -1198,7 +1200,10 @@ void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder) void QGraphicsScenePrivate::_q_updateSortCache() { //### FIXME - //index->updateIndex(); + QGraphicsSceneBspTreeIndex *tree = qobject_cast(index); + if (tree) { + tree->_q_updateIndex(); + } if (!sortCacheEnabled || !updatingSortCache) return; @@ -2578,10 +2583,8 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Clear its background item->update(); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->index->deleteItem(item); + // Remove it from the index properly + d->index->removeItem(item); if (item == d->tabFocusFirst) { QGraphicsWidget *widget = static_cast(item); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index 8a26447..f8f1f56 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -61,11 +61,10 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } - QRectF QGraphicsSceneBspTreeIndex::indexedRect() { _q_updateIndex(); - return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; + return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; } void QGraphicsSceneBspTreeIndex::clear() @@ -162,7 +161,7 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) item->d_func()->index = -1; unindexedItems << item; - //prepareGeometryChange will call updateItem + //prepareGeometryChange will call prepareBoundingRectChange foreach (QGraphicsItem *child, item->children()) child->prepareGeometryChange(); } @@ -180,13 +179,15 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { const_cast(this)->purgeRemovedItems(); + scene()->d_func()->_q_updateSortCache(); + QList rectItems = bsp.items(rect); // Fill in with any unindexed items for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { QRectF boundingRect = item->sceneBoundingRect(); - if (boundingRect.intersects(rect)) { + if (QRectF_intersects(boundingRect, rect)) { item->d_ptr->itemDiscovered = 1; rectItems << item; } @@ -328,7 +329,7 @@ void QGraphicsSceneBspTreeIndex::_q_updateIndex() if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) continue; - bsp.insertItem(item,rect); + bsp.insertItem(item, rect); // If the item ignores view transformations, update our // largest-item-counter to ensure that the view can accurately diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index fe3a68a..d0d6081 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -352,7 +352,7 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe } } - d->scene->d_func()->sortItems(&items, Qt::AscendingOrder, d->scene->d_func()->sortCacheEnabled); + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); return items; } diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 0c5ebf6..eb117ab 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -395,6 +395,9 @@ void tst_QGraphicsScene::items() QGraphicsLineItem *l2 = scene.addLine(0, -5, 0, 5); QVERIFY(!l1->sceneBoundingRect().intersects(l2->sceneBoundingRect())); QVERIFY(!l2->sceneBoundingRect().intersects(l1->sceneBoundingRect())); + QList items; + items<setRect(QRectF(0, 0, 2000, 2000)); - QCOMPARE(index->rect(), QRectF(0, 0, 2000, 2000)); + scene->setSceneRect(QRectF(0, 0, 2000, 2000)); + QCOMPARE(index->indexedRect(), QRectF(0, 0, 2000, 2000)); } void tst_QGraphicsSceneIndex::customIndex_data() -- cgit v0.12 From ffd6bc0351c96c8a3828bd7376f2b6bda317cd71 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 3 Jun 2009 18:23:20 +0200 Subject: Remove the sorting cache from the QGraphicsScene and move it to the BSP. Now the QGraphicsScene has no idea how works the index. So we can improve it separatly, add new ones and benchmarks existing ones. --- src/gui/graphicsview/graphicsview.pri | 1 + src/gui/graphicsview/qgraphicsitem.cpp | 22 +- src/gui/graphicsview/qgraphicsitem.h | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 200 +------ src/gui/graphicsview/qgraphicsscene.h | 2 +- src/gui/graphicsview/qgraphicsscene_p.h | 19 - .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 614 ++++++++++++++------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 51 +- .../graphicsview/qgraphicsscenebsptreeindex_p_p.h | 140 +++++ src/gui/graphicsview/qgraphicssceneindex.cpp | 28 +- src/gui/graphicsview/qgraphicssceneindex.h | 9 +- src/gui/graphicsview/qgraphicssceneindex_p.h | 3 +- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 2 +- src/gui/graphicsview/qgraphicsview.cpp | 11 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 5 + tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 5 +- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 8 +- 17 files changed, 642 insertions(+), 479 deletions(-) create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index cc57892..a4a79e8 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -7,6 +7,7 @@ HEADERS += \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ + graphicsview/qgraphicsscenebsptreeindex_p_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ graphicsview/qgraphicsscenelinearindex_p.h \ graphicsview/qgraphicssceneindex.h \ diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index fc5895c..ee32724 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -537,6 +537,7 @@ #include "qgraphicsview.h" #include "qgraphicswidget.h" #include "qgraphicsproxywidget.h" +#include "qgraphicsscenebsptreeindex_p_p.h" #include #include #include @@ -888,12 +889,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de } } - if (scene) { - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - scene->d_func()->invalidateSortCache(); - } - // Resolve opacity. updateEffectiveOpacity(); @@ -905,6 +900,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de // Deliver post-change notification q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); + + if (scene) { + // Deliver the change to the index + scene->d_func()->index->itemChanged(q, QGraphicsItem::ItemParentHasChanged, newParentVariant); + } } /*! @@ -3528,11 +3528,9 @@ void QGraphicsItem::setZValue(qreal z) d_ptr->z = newZ; d_ptr->fullUpdateHelper(); - if (d_ptr->scene) { - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d_ptr->scene->d_func()->invalidateSortCache(); - } + //Z Value has changed, we have to notify the index. + if (d_ptr->scene) + d_ptr->scene->d_func()->index->itemChanged(this, ItemZValueChange, z); itemChange(ItemZValueHasChanged, newZVariant); } @@ -3991,7 +3989,7 @@ bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const { if (!item) return false; - return QGraphicsScenePrivate::closestItemFirst_withoutCache(item, this) + return QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(item, this) && qt_QGraphicsItem_isObscured(this, item, boundingRect()); } diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index e244c13..7874033 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -435,6 +435,7 @@ private: friend class QGraphicsSceneIndex; friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; + friend class QGraphicsSceneBspTreeIndexPrivate; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0172a23..4734e74 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -218,6 +218,7 @@ #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" #include "qgraphicssceneindex.h" +#include "qgraphicsscenebsptreeindex_p_p.h" #include #include @@ -291,8 +292,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() allItemsIgnoreHoverEvents(true), allItemsUseDefaultCursor(true), painterStateProtection(true), - sortCacheEnabled(false), - updatingSortCache(false), style(0) { } @@ -1073,175 +1072,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } -void QGraphicsScenePrivate::invalidateSortCache() -{ - Q_Q(QGraphicsScene); - if (!sortCacheEnabled || updatingSortCache) - return; - - updatingSortCache = true; - QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); -} - -/*! - \internal - - Should not be exported, but we can't change that now. - ### Qt 5: Remove symbol / make static -*/ -inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Return true if sibling item1 is on top of item2. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; - bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; - if (f1 != f2) return f2; - qreal z1 = d1->z; - qreal z2 = d2->z; - return z1 != z2 ? z1 > z2 : d1->siblingIndex > d2->siblingIndex; -} - -/*! - \internal - - Should not be exported, but we can't change that now. -*/ -inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return QGraphicsScenePrivate::closestItemFirst_withoutCache(item1, item2); -} - -/*! - Returns true if \a item1 is on top of \a item2. - - \internal -*/ -bool QGraphicsScenePrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Siblings? Just check their z-values. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - if (d1->parent == d2->parent) - return qt_closestLeaf(item1, item2); - - // Find common ancestor, and each item's ancestor closest to the common - // ancestor. - int item1Depth = d1->depth; - int item2Depth = d2->depth; - const QGraphicsItem *p = item1; - const QGraphicsItem *t1 = item1; - while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { - if (p == item2) { - // item2 is one of item1's ancestors; item1 is on top - return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t1 = p; - --item1Depth; - } - p = item2; - const QGraphicsItem *t2 = item2; - while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { - if (p == item1) { - // item1 is one of item2's ancestors; item1 is not on top - return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t2 = p; - --item2Depth; - } - - // item1Ancestor is now at the same level as item2Ancestor, but not the same. - const QGraphicsItem *a1 = t1; - const QGraphicsItem *a2 = t2; - while (a1) { - const QGraphicsItem *p1 = a1; - const QGraphicsItem *p2 = a2; - a1 = a1->parentItem(); - a2 = a2->parentItem(); - if (a1 && a1 == a2) - return qt_closestLeaf(p1, p2); - } - - // No common ancestor? Then just compare the items' toplevels directly. - return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); -} - -/*! - Returns true if \a item2 is on top of \a item1. - - \internal -*/ -bool QGraphicsScenePrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return closestItemFirst_withoutCache(item2, item1); -} - -void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder) -{ - if (!item->d_ptr->children.isEmpty()) { - QList childList = item->d_ptr->children; - qSort(childList.begin(), childList.end(), qt_closestLeaf); - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) - climbTree(childList.at(i), stackingOrder); - } - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (item->flags() & QGraphicsItem::ItemStacksBehindParent) - climbTree(childList.at(i), stackingOrder); - } - } else { - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - } -} - -void QGraphicsScenePrivate::_q_updateSortCache() -{ - //### FIXME - QGraphicsSceneBspTreeIndex *tree = qobject_cast(index); - if (tree) { - tree->_q_updateIndex(); - } - - if (!sortCacheEnabled || !updatingSortCache) - return; - - updatingSortCache = false; - int stackingOrder = 0; - - QList topLevels; - - for (int i = 0; i < index->items().count(); ++i) { - QGraphicsItem *item = index->items().at(i); - if (item && item->parentItem() == 0) - topLevels << item; - } - - qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); - for (int i = 0; i < topLevels.size(); ++i) - climbTree(topLevels.at(i), &stackingOrder); -} - -void QGraphicsScenePrivate::sortItems(QList *itemList, Qt::SortOrder order, - bool sortCacheEnabled) -{ - if (sortCacheEnabled) { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); - } - } else { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); - } - } -} - /*! \internal @@ -1707,15 +1537,25 @@ void QGraphicsScene::setBspTreeDepth(int depth) bool QGraphicsScene::isSortCacheEnabled() const { Q_D(const QGraphicsScene); - return d->sortCacheEnabled; + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + if (!bspTree) { + qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); + return false; + } + return bspTree->d_func()->sortCacheEnabled; } void QGraphicsScene::setSortCacheEnabled(bool enabled) { Q_D(QGraphicsScene); - if (enabled == d->sortCacheEnabled) + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + if (!bspTree) { + qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); return; - if ((d->sortCacheEnabled = enabled)) - d->invalidateSortCache(); + } + if (enabled == bspTree->d_func()->sortCacheEnabled) + return; + if ((bspTree->d_func()->sortCacheEnabled = enabled)) + bspTree->d_func()->invalidateSortCache(); } /*! @@ -1910,8 +1750,6 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode)) tmp << itemInVicinity; } - //### remove me - d->sortItems(&tmp, Qt::AscendingOrder, d->sortCacheEnabled); return tmp; } @@ -2211,10 +2049,6 @@ void QGraphicsScene::addItem(QGraphicsItem *item) return; } - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - // Detach this item from its parent if the parent's scene is different // from this scene. if (QGraphicsItem *itemParent = item->parentItem()) { @@ -2232,10 +2066,6 @@ void QGraphicsScene::addItem(QGraphicsItem *item) if (!item->d_ptr->parent) d->registerTopLevelItem(item); - // Update the scene's sort cache settings. - item->d_ptr->globalStackingOrder = -1; - d->invalidateSortCache(); - // Add to list of items that require an update. We cannot assume that the // item is fully constructed, so calling item->update() can lead to a pure // virtual function call to boundingRect(). diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 5d70087..702813c 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -290,7 +290,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_removeItemLater(QGraphicsItem *item)) Q_PRIVATE_SLOT(d_func(), void _q_updateLater()) Q_PRIVATE_SLOT(d_func(), void _q_polishItems()) - Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) Q_PRIVATE_SLOT(d_func(), void _q_resetDirtyItems()) friend class QGraphicsItem; friend class QGraphicsItemPrivate; @@ -301,6 +300,7 @@ private: friend class QGraphicsSceneIndex; friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; + friend class QGraphicsSceneBspTreeIndexPrivate; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers) diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index a035159..d2a5cdb 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -187,25 +187,6 @@ public: void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent); void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - bool sortCacheEnabled; - bool updatingSortCache; - void invalidateSortCache(); - static void climbTree(QGraphicsItem *item, int *stackingOrder); - void _q_updateSortCache(); - - static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - - static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; - } - static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; - } - - static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index f8f1f56..19aa9d5 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -39,9 +39,15 @@ ** ****************************************************************************/ + static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; #include "qgraphicsscenebsptreeindex_p.h" + +#ifndef QT_NO_GRAPHICSVIEW + +#include "qgraphicsscenebsptreeindex_p_p.h" +#include "qgraphicssceneindex_p.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" @@ -49,51 +55,365 @@ static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; #include -QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) - : QGraphicsSceneIndex(scene), +QT_BEGIN_NAMESPACE + +static inline int intmaxlog(int n) +{ + return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); +} + +/*! + Constructs a private scene index. +*/ +QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) + : scene(scene), bspTreeDepth(0), indexTimerId(0), restartIndexTimer(false), regenerateIndex(true), lastItemCount(0), - purgePending(false) + purgePending(false), + sortCacheEnabled(false), + updatingSortCache(false) +{ +} + + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() { + Q_Q(QGraphicsSceneBspTreeIndex); + if (!indexTimerId) + return; + QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); + q->killTimer(indexTimerId); + indexTimerId = 0; + + purgeRemovedItems(); + + // Add unindexedItems to indexedItems + QRectF unindexedItemsBoundingRect; + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + unindexedItemsBoundingRect |= item->sceneBoundingRect(); + if (!freeItemIndexes.isEmpty()) { + int freeIndex = freeItemIndexes.takeFirst(); + item->d_func()->index = freeIndex; + indexedItems[freeIndex] = item; + } else { + item->d_func()->index = indexedItems.size(); + indexedItems << item; + } + } + } + + // Update growing scene rect. + QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; + scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; + + // Determine whether we should regenerate the BSP tree. + if (bspTreeDepth == 0) { + int oldDepth = intmaxlog(lastItemCount); + bspTreeDepth = intmaxlog(indexedItems.size()); + static const int slack = 100; + if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) { + // ### Crude algorithm. + regenerateIndex = true; + } + } + + // Regenerate the tree. + if (regenerateIndex) { + regenerateIndex = false; + bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); + unindexedItems = indexedItems; + lastItemCount = indexedItems.size(); + q->scene()->update(); + + // Take this opportunity to reset our largest-item counter for + // untransformable items. When the items are inserted into the BSP + // tree, we'll get an accurate calculation. + scenePrivate->largestUntransformableItem = QRectF(); + } + + // Insert all unindexed items into the tree. + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + continue; + + bsp.insertItem(item, rect); + + // If the item ignores view transformations, update our + // largest-item-counter to ensure that the view can accurately + // discover untransformable items when drawing. + if (item->d_ptr->itemIsUntransformable()) { + QGraphicsItem *topmostUntransformable = item; + while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags + & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { + topmostUntransformable = topmostUntransformable->parentItem(); + } + // ### Verify that this is the correct largest untransformable rectangle. + scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); + } + } + } + unindexedItems.clear(); + + // Notify scene rect changes. + if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) + emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); } -QRectF QGraphicsSceneBspTreeIndex::indexedRect() + +/*! + \internal + + Removes stale pointers from all data structures. +*/ +void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!purgePending && removedItems.isEmpty()) + return; + + // Remove stale items from the BSP tree. + bsp.removeItems(removedItems.toSet()); + // Purge this list. + removedItems.clear(); + freeItemIndexes.clear(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (!indexedItems.at(i)) + freeItemIndexes << i; + } + purgePending = false; + + // No locality info for the items; update the whole scene. + q->scene()->update(); +} + +/*! + \internal + + Starts or restarts the timer used for reindexing unindexed items. +*/ +void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (indexTimerId) { + restartIndexTimer = true; + } else { + indexTimerId = q->startTimer(QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); + } +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::resetIndex() +{ + purgeRemovedItems(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (QGraphicsItem *item = indexedItems.at(i)) { + item->d_ptr->index = -1; + unindexedItems << item; + } + } + indexedItems.clear(); + freeItemIndexes.clear(); + regenerateIndex = true; + startIndexTimer(); +} + +void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) { + if (!item->d_ptr->children.isEmpty()) { + QList childList = item->d_ptr->children; + qSort(childList.begin(), childList.end(), qt_closestLeaf); + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) + climbTree(childList.at(i), stackingOrder); + } + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (item->flags() & QGraphicsItem::ItemStacksBehindParent) + climbTree(childList.at(i), stackingOrder); + } + } else { + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + } +} + +void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); _q_updateIndex(); + + if (!sortCacheEnabled || !updatingSortCache) + return; + + updatingSortCache = false; + int stackingOrder = 0; + + QList topLevels; + + for (int i = 0; i < q->items().count(); ++i) { + QGraphicsItem *item = q->items().at(i); + if (item && item->parentItem() == 0) + topLevels << item; + } + + qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); + for (int i = 0; i < topLevels.size(); ++i) + climbTree(topLevels.at(i), &stackingOrder); +} + +void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!sortCacheEnabled || updatingSortCache) + return; + + updatingSortCache = true; + QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); +} + +/*! + Returns true if \a item1 is on top of \a item2. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Siblings? Just check their z-values. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + if (d1->parent == d2->parent) + return qt_closestLeaf(item1, item2); + + // Find common ancestor, and each item's ancestor closest to the common + // ancestor. + int item1Depth = d1->depth; + int item2Depth = d2->depth; + const QGraphicsItem *p = item1; + const QGraphicsItem *t1 = item1; + while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { + if (p == item2) { + // item2 is one of item1's ancestors; item1 is on top + return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t1 = p; + --item1Depth; + } + p = item2; + const QGraphicsItem *t2 = item2; + while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { + if (p == item1) { + // item1 is one of item2's ancestors; item1 is not on top + return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t2 = p; + --item2Depth; + } + + // item1Ancestor is now at the same level as item2Ancestor, but not the same. + const QGraphicsItem *a1 = t1; + const QGraphicsItem *a2 = t2; + while (a1) { + const QGraphicsItem *p1 = a1; + const QGraphicsItem *p2 = a2; + a1 = a1->parentItem(); + a2 = a2->parentItem(); + if (a1 && a1 == a2) + return qt_closestLeaf(p1, p2); + } + + // No common ancestor? Then just compare the items' toplevels directly. + return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); +} + +/*! + Returns true if \a item2 is on top of \a item1. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + return closestItemFirst_withoutCache(item2, item1); +} + +void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, + bool sortCacheEnabled) +{ + if (sortCacheEnabled) { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); + } + } else { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); + } + } +} + +QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) + : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) +{ + +} + +QRectF QGraphicsSceneBspTreeIndex::indexedRect() const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->_q_updateIndex(); return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; } void QGraphicsSceneBspTreeIndex::clear() { - bsp.clear(); - lastItemCount = 0; - freeItemIndexes.clear(); - m_indexedItems.clear(); - unindexedItems.clear(); + Q_D(QGraphicsSceneBspTreeIndex); + d->bsp.clear(); + d->lastItemCount = 0; + d->freeItemIndexes.clear(); + d->indexedItems.clear(); + d->unindexedItems.clear(); } void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); // Prevent reusing a recently deleted pointer: purge all removed items // from our lists. - purgeRemovedItems(); + d->purgeRemovedItems(); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + // Update the scene's sort cache settings. + item->d_ptr->globalStackingOrder = -1; + d->invalidateSortCache(); // Indexing requires sceneBoundingRect(), but because \a item might // not be completely constructed at this point, we need to store it in // a temporary list and schedule an indexing for later. - unindexedItems << item; + d->unindexedItems << item; item->d_func()->index = -1; - startIndexTimer(); + d->startIndexTimer(); } /*! \internal */ -void QGraphicsSceneBspTreeIndex::addToIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) { if (item->d_func()->index != -1) { bsp.insertItem(item, item->sceneBoundingRect()); @@ -109,37 +429,47 @@ void QGraphicsSceneBspTreeIndex::addToIndex(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - removeFromIndex(item); + d->removeFromIndex(item); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); // Remove from our item lists. int index = item->d_func()->index; if (index != -1) { - freeItemIndexes << index; - m_indexedItems[index] = 0; + d->freeItemIndexes << index; + d->indexedItems[index] = 0; } else { - unindexedItems.removeAll(item); + d->unindexedItems.removeAll(item); } } void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); + int index = item->d_func()->index; if (index != -1) { // Important: The index is useless until purgeRemovedItems() is // called. - m_indexedItems[index] = (QGraphicsItem *)0; - if (!purgePending) { - purgePending = true; + d->indexedItems[index] = (QGraphicsItem *)0; + if (!d->purgePending) { + d->purgePending = true; scene()->update(); } - removedItems << item; + d->removedItems << item; } else { // Recently added items are purged immediately. unindexedItems() never // contains stale items. - unindexedItems.removeAll(item); + d->unindexedItems.removeAll(item); scene()->update(); } } @@ -147,7 +477,7 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) /*! \internal */ -void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) { if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { // ### remove from child index only if applicable @@ -157,7 +487,7 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) if (index != -1) { bsp.removeItem(item, item->sceneBoundingRect()); freeItemIndexes << index; - m_indexedItems[index] = 0; + indexedItems[index] = 0; item->d_func()->index = -1; unindexedItems << item; @@ -170,21 +500,23 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - removeFromIndex(const_cast(item)); + d->removeFromIndex(const_cast(item)); } QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - const_cast(this)->purgeRemovedItems(); - scene()->d_func()->_q_updateSortCache(); + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + const_cast(d)->_q_updateSortCache(); - QList rectItems = bsp.items(rect); + QList rectItems = d->bsp.items(rect); // Fill in with any unindexed items - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { + for (int i = 0; i < d->unindexedItems.size(); ++i) { + if (QGraphicsItem *item = d->unindexedItems.at(i)) { if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { QRectF boundingRect = item->sceneBoundingRect(); if (QRectF_intersects(boundingRect, rect)) { @@ -199,57 +531,83 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r for (int i = 0; i < rectItems.size(); ++i) rectItems.at(i)->d_func()->itemDiscovered = 0; + d->sortItems(&rectItems, order, d->sortCacheEnabled); + return rectItems; } -QList QGraphicsSceneBspTreeIndex::items() const +QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const { - const_cast(this)->purgeRemovedItems(); + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + QList itemList; // If freeItemIndexes is empty, we know there are no holes in indexedItems and // unindexedItems. - if (freeItemIndexes.isEmpty()) { - if (unindexedItems.isEmpty()) - return m_indexedItems; - return m_indexedItems + unindexedItems; - } - - // Rebuild the list of items to avoid holes. ### We could also just - // compress the item lists at this point. - QList itemList; - foreach (QGraphicsItem *item, m_indexedItems + unindexedItems) { - if (item) - itemList << item; + if (d->freeItemIndexes.isEmpty()) { + if (d->unindexedItems.isEmpty()) { + itemList = d->indexedItems; + } else { + itemList = d->indexedItems + d->unindexedItems; + } + } else { + // Rebuild the list of items to avoid holes. ### We could also just + // compress the item lists at this point. + foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { + if (item) + itemList << item; + } } + //We sort descending order + d->sortItems(&itemList, order, d->sortCacheEnabled); return itemList; } int QGraphicsSceneBspTreeIndex::bspDepth() { - return bspTreeDepth; + Q_D(const QGraphicsSceneBspTreeIndex); + return d->bspTreeDepth; } void QGraphicsSceneBspTreeIndex::setBspDepth(int depth) { - bspTreeDepth = depth; - resetIndex(); + Q_D(QGraphicsSceneBspTreeIndex); + d->bspTreeDepth = depth; + d->resetIndex(); } void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - resetIndex(); + Q_D(QGraphicsSceneBspTreeIndex); + d->sceneRect = rect; + d->resetIndex(); +} + +void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + Q_D(QGraphicsSceneBspTreeIndex); + switch (change) { + case QGraphicsItem::ItemZValueChange: + case QGraphicsItem::ItemParentChange: { + d->invalidateSortCache(); + break; + } + default: + break; + } + return QGraphicsSceneIndex::itemChanged(item, change, value); } bool QGraphicsSceneBspTreeIndex::event(QEvent *event) { + Q_D(QGraphicsSceneBspTreeIndex); switch (event->type()) { case QEvent::Timer: - if (indexTimerId && static_cast(event)->timerId() == indexTimerId) { - if (restartIndexTimer) { - restartIndexTimer = false; + if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { + if (d->restartIndexTimer) { + d->restartIndexTimer = false; } else { // this call will kill the timer - _q_updateIndex(); + d->_q_updateIndex(); } } // Fallthrough intended - support timers in subclasses. @@ -259,153 +617,9 @@ bool QGraphicsSceneBspTreeIndex::event(QEvent *event) return true; } -static inline int intmaxlog(int n) -{ - return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); -} +QT_END_NAMESPACE -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndex::_q_updateIndex() -{ - if (!indexTimerId) - return; +#include "moc_qgraphicsscenebsptreeindex_p.cpp" - killTimer(indexTimerId); - indexTimerId = 0; +#endif // QT_NO_GRAPHICSVIEW - purgeRemovedItems(); - - // Add unindexedItems to indexedItems - QRectF unindexedItemsBoundingRect; - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); - if (!freeItemIndexes.isEmpty()) { - int freeIndex = freeItemIndexes.takeFirst(); - item->d_func()->index = freeIndex; - m_indexedItems[freeIndex] = item; - } else { - item->d_func()->index = m_indexedItems.size(); - m_indexedItems << item; - } - } - } - - // Update growing scene rect. - QRectF oldGrowingItemsBoundingRect = scene()->d_func()->growingItemsBoundingRect; - scene()->d_func()->growingItemsBoundingRect |= unindexedItemsBoundingRect; - - // Determine whether we should regenerate the BSP tree. - if (bspTreeDepth == 0) { - int oldDepth = intmaxlog(lastItemCount); - bspTreeDepth = intmaxlog(m_indexedItems.size()); - static const int slack = 100; - if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - m_indexedItems.size()) > slack)) { - // ### Crude algorithm. - regenerateIndex = true; - } - } - - // Regenerate the tree. - if (regenerateIndex) { - regenerateIndex = false; - bsp.initialize(scene()->sceneRect(), bspTreeDepth); - unindexedItems = m_indexedItems; - lastItemCount = m_indexedItems.size(); - scene()->update(); - - // Take this opportunity to reset our largest-item counter for - // untransformable items. When the items are inserted into the BSP - // tree, we'll get an accurate calculation. - scene()->d_func()->largestUntransformableItem = QRectF(); - } - - // Insert all unindexed items into the tree. - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - QRectF rect = item->sceneBoundingRect(); - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - - bsp.insertItem(item, rect); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - scene()->d_func()->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); - } - } - } - unindexedItems.clear(); - - // Notify scene rect changes. - if (!scene()->d_func()->hasSceneRect && scene()->d_func()->growingItemsBoundingRect != oldGrowingItemsBoundingRect) - emit scene()->sceneRectChanged(scene()->d_func()->growingItemsBoundingRect); -} - - -/*! - \internal - - Removes stale pointers from all data structures. -*/ -void QGraphicsSceneBspTreeIndex::purgeRemovedItems() -{ - if (!purgePending && removedItems.isEmpty()) - return; - - // Remove stale items from the BSP tree. - bsp.removeItems(removedItems.toSet()); - // Purge this list. - removedItems.clear(); - freeItemIndexes.clear(); - for (int i = 0; i < m_indexedItems.size(); ++i) { - if (!m_indexedItems.at(i)) - freeItemIndexes << i; - } - purgePending = false; - - // No locality info for the items; update the whole scene. - scene()->update(); -} - -/*! - \internal - - Starts or restarts the timer used for reindexing unindexed items. -*/ -void QGraphicsSceneBspTreeIndex::startIndexTimer() -{ - if (indexTimerId) { - restartIndexTimer = true; - } else { - indexTimerId = startTimer(QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); - } -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndex::resetIndex() -{ - purgeRemovedItems(); - for (int i = 0; i < m_indexedItems.size(); ++i) { - if (QGraphicsItem *item = m_indexedItems.at(i)) { - item->d_ptr->index = -1; - unindexedItems << item; - } - } - m_indexedItems.clear(); - freeItemIndexes.clear(); - regenerateIndex = true; - startIndexTimer(); -} diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 7a6ea0b..b1ea977 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -56,56 +56,41 @@ QT_BEGIN_NAMESPACE #include "qgraphicsscene_bsp_p.h" +class QGraphicsSceneBspTreeIndexPrivate; class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex { Q_OBJECT public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect(); - - void clear(); - - void addItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); - void prepareBoundingRectChange(const QGraphicsItem *item); + QRectF indexedRect() const; QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - QList items() const; + QList items(Qt::SortOrder order = Qt::AscendingOrder) const; int bspDepth(); void setBspDepth(int depth); protected: bool event(QEvent *event); - void sceneRectChanged(const QRectF &rect); + void clear(); + + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); -public slots : - void _q_updateIndex(); + void sceneRectChanged(const QRectF &rect); + void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : - QGraphicsSceneBspTree bsp; - QRectF m_sceneRect; - int bspTreeDepth; - int indexTimerId; - bool restartIndexTimer; - bool regenerateIndex; - int lastItemCount; - - QList m_indexedItems; - QList unindexedItems; - QList freeItemIndexes; - - bool purgePending; - QList removedItems; - void purgeRemovedItems(); - - void startIndexTimer(); - void resetIndex(); - - void addToIndex(QGraphicsItem *item); - void removeFromIndex(QGraphicsItem *item); + Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) + Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) + Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h new file mode 100644 index 0000000..2df5fbc --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_P_H +#define QGRAPHICSSCENEBSPTREEINDEX_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicsscenebsptreeindex_p.h" + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGraphicsScene; + +class QGraphicsSceneBspTreeIndexPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) +public: + QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); + + QGraphicsScene *scene; + QGraphicsSceneBspTree bsp; + QRectF sceneRect; + int bspTreeDepth; + int indexTimerId; + bool restartIndexTimer; + bool regenerateIndex; + int lastItemCount; + + QList indexedItems; + QList unindexedItems; + QList freeItemIndexes; + + bool purgePending; + QList removedItems; + void purgeRemovedItems(); + + void _q_updateIndex(); + void startIndexTimer(); + void resetIndex(); + + void addToIndex(QGraphicsItem *item); + void removeFromIndex(QGraphicsItem *item); + + void _q_updateSortCache(); + bool sortCacheEnabled; + bool updatingSortCache; + void invalidateSortCache(); + + static void climbTree(QGraphicsItem *item, int *stackingOrder); + static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + + static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; + } + static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; + } + + static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); +}; + + +/*! + \internal +*/ +inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Return true if sibling item1 is on top of item2. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; + bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; + if (f1 != f2) return f2; + qreal z1 = d1->z; + qreal z2 = d2->z; + return z1 != z2 ? z1 > z2 : d1->siblingIndex > d2->siblingIndex; +} + +QT_END_NAMESPACE + +#endif // QGRAPHICSSCENEBSPTREEINDEX_P_P_H + +#endif + diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index d0d6081..eeee74e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -41,6 +41,7 @@ #include "qgraphicssceneindex.h" #include "qgraphicssceneindex_p.h" +#include "qgraphicsscenebsptreeindex_p_p.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" @@ -282,6 +283,14 @@ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) } /*! + \internal +*/ +QGraphicsSceneIndex::QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene) + : QObject(dd, scene) +{ +} + +/*! Destroys the scene index. */ QGraphicsSceneIndex::~QGraphicsSceneIndex() @@ -301,7 +310,7 @@ QGraphicsScene* QGraphicsSceneIndex::scene() const /*! Returns the indexed area for the index */ -QRectF QGraphicsSceneIndex::indexedRect() +QRectF QGraphicsSceneIndex::indexedRect() const { Q_D(const QGraphicsSceneIndex); return d->scene->d_func()->sceneRect; @@ -351,8 +360,9 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe d->childItems_helper(&items, item, xinv.map(pos)); } } - - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + //### Needed but it should be handle differently + if (order != Qt::SortOrder(-1)) + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } @@ -415,9 +425,9 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe } } } - + //### Needed but it should be handle differently if (order != Qt::SortOrder(-1)) - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } @@ -474,9 +484,9 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: d->childItems_helper(&items, item, xinv.map(polygon), mode); } } - + //### Needed but it should be handle differently if (order != Qt::SortOrder(-1)) - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const @@ -525,9 +535,9 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: d->childItems_helper(&items, item, xinv.map(path), mode); } } - + //### Needed but it should be handle differently if (order != Qt::SortOrder(-1)) - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index 11d9aae..084a623 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -71,9 +71,9 @@ public: QGraphicsScene *scene() const; - virtual QRectF indexedRect(); + virtual QRectF indexedRect() const; - virtual QList items() const = 0; + virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; @@ -91,10 +91,15 @@ protected: virtual void prepareBoundingRectChange(const QGraphicsItem *item); virtual void sceneRectChanged(const QRectF &rect); + QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); + friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QGraphicsItem; + friend class QGraphicsItemPrivate; + friend class QGraphicsSceneBspTreeIndex; private: + Q_DISABLE_COPY(QGraphicsSceneIndex) Q_DECLARE_PRIVATE(QGraphicsSceneIndex) }; diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index f2cdca3..2014693 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -58,6 +58,7 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include +#include QT_BEGIN_NAMESPACE @@ -86,7 +87,7 @@ public: const QPainterPath &path, Qt::ItemSelectionMode mode) const; - QGraphicsScene *scene; + QGraphicsScene *scene; }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index dc45a17..3057b4a 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -105,7 +105,7 @@ public: return result; } - QList items() const { + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { return m_items; } }; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 91f97a1..e8330a9 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1056,7 +1056,7 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg *allItems = true; // All items are guaranteed within the exposed region, don't bother using the index. - QList itemList(scene->items()); + QList itemList(scene->d_func()->index->items(Qt::DescendingOrder)); int i = 0; while (i < itemList.size()) { const QGraphicsItem *item = itemList.at(i); @@ -1069,9 +1069,6 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg else ++i; } - - // Sort the items. - QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder, scene->d_func()->sortCacheEnabled); return itemList; } @@ -2134,7 +2131,7 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat // Then find the minimal list of items that are inside \a path, and // convert it to a set. - QList regularCandidates = scene->items(q->mapToScene(path), mode); + QList regularCandidates = scene->items(q->mapToScene(path), mode, order, q->transform()); QSet candSet = QSet::fromList(regularCandidates); QTransform viewMatrix = q->viewportTransform(); @@ -2161,10 +2158,6 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat } ++it; } - - // ### Insertion sort would be faster. - if (order != Qt::SortOrder(-1)) - QGraphicsScenePrivate::sortItems(&result, order, scene->d_func()->sortCacheEnabled); return result; } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 8afdeb4..c83134f 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4685,6 +4685,11 @@ void tst_QGraphicsItem::itemClipsChildrenToShape() scene.render(&painter); painter.end(); + QGraphicsView view(&scene); + view.show(); + + QTest::qWait(5000); + QCOMPARE(image.pixel(16, 16), QColor(255, 0, 0).rgba()); QCOMPARE(image.pixel(32, 32), QColor(0, 0, 255).rgba()); QCOMPARE(image.pixel(50, 50), QColor(0, 255, 0).rgba()); diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index eb117ab..dd997c7 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -379,8 +379,7 @@ void tst_QGraphicsScene::items() for (int x = minX; x < maxX; x += 100) items << scene.addRect(QRectF(0, 0, 10, 10)); } - - QCOMPARE(scene.items(), items); + QCOMPARE(scene.items().size(), items.size()); scene.itemAt(0, 0); // trigger indexing scene.removeItem(items.at(5)); @@ -397,7 +396,7 @@ void tst_QGraphicsScene::items() QVERIFY(!l2->sceneBoundingRect().intersects(l1->sceneBoundingRect())); QList items; items<rect().center()); - QTest::qWait(100); + QTest::qWait(250); for (int size = 200; size <= 400; size += 25) { view.resize(size, size); @@ -2122,7 +2122,7 @@ void tst_QGraphicsView::resizeAnchor() QVERIFY(qAbs(newCenter.x() - center.x()) < slack); QVERIFY(qAbs(newCenter.y() - center.y()) < slack); } - QTest::qWait(100); + QTest::qWait(250); } } } @@ -2925,7 +2925,7 @@ void tst_QGraphicsView::task245469_itemsAtPointWithClip() QTest::qWait(100); QList itemsAtCenter = view.items(view.viewport()->rect().center()); - QCOMPARE(itemsAtCenter, (QList() << child << parent)); + QCOMPARE(itemsAtCenter, (QList() << parent << child)); QPolygonF p = view.mapToScene(QRect(view.viewport()->rect().center(), QSize(1, 1))); QList itemsAtCenter2 = scene.items(p); -- cgit v0.12 From cea8678e5fca8b33bbd5da057282888bc260a5c9 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 4 Jun 2009 16:46:36 +0200 Subject: Fix doc and auto-test regression. --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 4734e74..d811ade 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1586,7 +1586,7 @@ QList QGraphicsScene::items() const /*! Returns all visible items at position \a pos in the scene. The items are - listed in descending Z order (i.e., the first item in the list is the + listed in descending stacking order (i.e., the first item in the list is the top-most item, and the last item is the bottom-most item). \sa itemAt() diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 447de34..696a42d 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -2925,7 +2925,7 @@ void tst_QGraphicsView::task245469_itemsAtPointWithClip() QTest::qWait(100); QList itemsAtCenter = view.items(view.viewport()->rect().center()); - QCOMPARE(itemsAtCenter, (QList() << parent << child)); + QCOMPARE(itemsAtCenter, (QList() << child << parent)); QPolygonF p = view.mapToScene(QRect(view.viewport()->rect().center(), QSize(1, 1))); QList itemsAtCenter2 = scene.items(p); -- cgit v0.12 From 3d9d7d10c2c6a4aed4650572bc9f3c8bd5b899b5 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 11 Jun 2009 17:05:32 +0200 Subject: Kill one items_helper + one childItem helper and use the new recursive approach. --- src/gui/graphicsview/qgraphicsscene.cpp | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 232 ++++++++++++--------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 7 +- 3 files changed, 110 insertions(+), 134 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 33232af..0a1cd2b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1734,10 +1734,7 @@ QList QGraphicsScene::items(const QPointF &pos) const QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - QList itemList; - //###d->index->items(rect, mode, Qt::AscendingOrder); - d->recursive_items_helper(0, rect, &itemList, QTransform(), QTransform(), mode, Qt::AscendingOrder); - return itemList; + return d->index->items(rect, mode, Qt::AscendingOrder); } /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 6895911..954cef3 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -57,57 +57,121 @@ QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : { } -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const +void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, + QList *items, + const QTransform &parentTransform, + const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, + qreal parentOpacity) const { - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - // ### is this needed? - if (parentClip && !parent->boundingRect().contains(pos)) - return; + // Calculate opacity. + qreal opacity; + if (item) { + if (!item->d_ptr->visible) + return; + QGraphicsItem *p = item->d_ptr->parent; + bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; + bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); + if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) { + opacity = parentOpacity * item->opacity(); + } else { + opacity = item->d_ptr->opacity; + } + if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) + return; + } else { + opacity = parentOpacity; + } - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; + // Calculate the full transform for this item. + QTransform transform = parentTransform; + bool keep = false; + if (item) { + item->d_ptr->combineTransformFromParent(&transform, &viewTransform); + + // ### This does not take the clip into account. + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + keep = true; + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = rect.contains(transform.mapRect(brect)) && rect != brect; + else + keep = rect.intersects(transform.mapRect(brect)); + + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(rect); + keep = scene->d_func()->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } + } - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; + bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); + bool dontProcessItem = !item || !keep; + bool dontProcessChildren = item && dontProcessItem && childClip; + + // Find and sort children. + QList &children = item ? item->d_ptr->children : const_cast(scene->d_func())->topLevelItems; + if (!dontProcessChildren) { + if (item && item->d_ptr->needSortChildren) { + item->d_ptr->needSortChildren = 0; + qStableSort(children.begin(), children.end(), qt_notclosestLeaf); + } else if (!item && scene->d_func()->needSortTopLevelItems) { + const_cast(scene->d_func())->needSortTopLevelItems = false; + qStableSort(children.begin(), children.end(), qt_notclosestLeaf); + } + } - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - if (item->contains(item->mapFromParent(pos))) { - items->append(item); - keep = true; - } + childClip &= !dontProcessChildren & !children.isEmpty(); + + // Clip. + if (childClip) + rect &= transform.map(item->shape()).controlPointRect(); + + // Process children behind + int i = 0; + if (!dontProcessChildren) { + for (i = 0; i < children.size(); ++i) { + QGraphicsItem *child = children.at(i); + if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) + break; + recursive_items_helper(child, rect, items, transform, viewTransform, + mode, order, opacity); } + } - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) - // Recurse into children. - childItems_helper(items, item, item->mapFromParent(pos)); + // Process item + if (!dontProcessItem) + items->append(item); + + // Process children in front + if (!dontProcessChildren) { + for (; i < children.size(); ++i) + recursive_items_helper(children.at(i), rect, items, transform, viewTransform, + mode, order, opacity); } -} + if (!item && order == Qt::AscendingOrder) { + int n = items->size(); + for (int i = 0; i < n / 2; ++i) { + QGraphicsItem *tmp = (*items)[n - i - 1]; + (*items)[n - i - 1] = (*items)[i]; + (*items)[i] = tmp; + } + } +} void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const + const QPointF &pos) const { bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); if (parentClip && parent->d_ptr->isClippedAway()) return; - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) + // ### is this needed? + if (parentClip && !parent->boundingRect().contains(pos)) return; - QPainterPath path; QList &children = parent->d_ptr->children; for (int i = 0; i < children.size(); ++i) { QGraphicsItem *item = children.at(i); @@ -120,45 +184,18 @@ void QGraphicsSceneIndexPrivate::childItems_helper(QList *items bool keep = false; if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - QRectF mbr = item->mapRectToParent(br); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { - items->append(item); - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(rect, mbr)) { - if (path == QPainterPath()) - path.addRect(rect); - if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } + if (item->contains(item->mapFromParent(pos))) { + items->append(item); + keep = true; } } - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) // Recurse into children. - if (!item->d_ptr->transformData || item->d_ptr->transformData->computedFullTransform().type() <= QTransform::TxScale) { - // Rect - childItems_helper(items, item, item->mapRectFromParent(rect), mode); - } else { - // Polygon - childItems_helper(items, item, item->mapFromParent(rect), mode); - } - } + childItems_helper(items, item, item->mapFromParent(pos)); } } - void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, const QGraphicsItem *parent, const QPolygonF &polygon, @@ -369,66 +406,9 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; - - QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - QRectF mbr = x.mapRect(br); - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(mbr))) { - items << item; - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path.isEmpty()) - path.addRect(rect); - if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (x.type() <= QTransform::TxScale) { - // Rect - d->childItems_helper(&items, item, xinv.mapRect(rect), mode); - } else { - // Polygon - d->childItems_helper(&items, item, xinv.map(rect), mode); - } - } - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + QList itemList; + d->recursive_items_helper(0, rect, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 2014693..3a2cb27 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -70,16 +70,15 @@ class QGraphicsSceneIndexPrivate : public QObjectPrivate public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); + void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList *items, + const QTransform &parentTransform, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; void childItems_helper(QList *items, const QGraphicsItem *parent, const QPointF &pos) const; void childItems_helper(QList *items, const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, const QPolygonF &polygon, Qt::ItemSelectionMode mode) const; void childItems_helper(QList *items, -- cgit v0.12 From da70cf2876cee57299dbeebb86c4c3881e3df721 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 15 Jun 2009 20:50:26 +0200 Subject: Kill items_helper and child_items_helper for ever. We have now on function recusrsive_item_helper that doing the job. To resolve different use cases we use concept of interceptors for QRectF, QPointF QPolygonF and QPainterPath. --- src/gui/graphicsview/qgraphicsscene.cpp | 5 + src/gui/graphicsview/qgraphicsscene_p.h | 2 + .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 3 +- .../graphicsview/qgraphicsscenebsptreeindex_p_p.h | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 408 ++++++--------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 36 +- 6 files changed, 140 insertions(+), 319 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0a1cd2b..eb06186 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -312,6 +312,11 @@ void QGraphicsScenePrivate::init() q->update(); } +QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q) +{ + return q->d_func(); +} + void QGraphicsScenePrivate::_q_emitUpdated() { Q_Q(QGraphicsScene); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index afdba7e..c63e121 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -85,6 +85,8 @@ public: QGraphicsScenePrivate(); void init(); + static QGraphicsScenePrivate *get(QGraphicsScene *q); + quint32 changedSignalMask; QGraphicsScene::ItemIndexMethod indexMethod; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index 97d0500..acadcbd 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -64,7 +64,7 @@ static inline int intmaxlog(int n) Constructs a private scene index. */ QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) - : scene(scene), + : QGraphicsSceneIndexPrivate(scene), bspTreeDepth(0), indexTimerId(0), restartIndexTimer(false), @@ -175,7 +175,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() */ void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() { - Q_Q(QGraphicsSceneBspTreeIndex); if (!purgePending && removedItems.isEmpty()) return; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h index 098b278..30f6e26 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h @@ -57,7 +57,7 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -#include +#include #include QT_BEGIN_NAMESPACE @@ -66,13 +66,12 @@ static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; class QGraphicsScene; -class QGraphicsSceneBspTreeIndexPrivate : public QObjectPrivate +class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate { Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) public: QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); - QGraphicsScene *scene; QGraphicsSceneBspTree bsp; QRectF sceneRect; int bspTreeDepth; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 954cef3..8d18806 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -50,14 +50,88 @@ QT_BEGIN_NAMESPACE +class QGraphicsSceneIndexRectIntersector : public QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexRectIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} + bool intersect(const QRectF &brect) const + { + bool keep = true; + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = rect.contains(transform.mapRect(brect)) && rect != brect; + else + keep = rect.intersects(transform.mapRect(brect)); + + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(rect); + keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } + return keep; + } +}; + +class QGraphicsSceneIndexPointIntersector : public QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexPointIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} + bool intersect(const QRectF &brect) const + { + bool keep = false; + if (rect.intersects(transform.mapRect(brect))) + if (item->contains(transform.inverted().map(pos))) + keep = true; + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(rect); + keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } + return keep; + } + QPointF pos; +}; + +class QGraphicsSceneIndexPathIntersector : public QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexPathIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} + bool intersect(const QRectF &brect) const + { + bool keep = true; + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = rect.contains(transform.mapRect(brect)) && rect != brect; + else + keep = rect.intersects(transform.mapRect(brect)); + + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(path), mode); + } + return keep; + } + QPainterPath path; +}; + /*! Constructs a private scene index. */ QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene) { + pointIntersector = new QGraphicsSceneIndexPointIntersector(scene); + rectIntersector = new QGraphicsSceneIndexRectIntersector(scene); + pathIntersector = new QGraphicsSceneIndexPathIntersector(scene); +} + +/*! + Destructor of private scene index. +*/ +QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate() +{ + delete pointIntersector; + delete rectIntersector; + delete pathIntersector; } -void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, +void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, const QTransform &viewTransform, @@ -93,17 +167,10 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe QRectF brect = item->boundingRect(); _q_adjustRect(&brect); - keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); - - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = scene->d_func()->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); - } + //We fill the intersector with needed informations + intersector->transform = transform; + intersector->item = item; + keep = intersector->intersect(brect); } bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); @@ -126,7 +193,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe // Clip. if (childClip) - rect &= transform.map(item->shape()).controlPointRect(); + intersector->rect &= transform.map(item->shape()).controlPointRect(); // Process children behind int i = 0; @@ -135,7 +202,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe QGraphicsItem *child = children.at(i); if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; - recursive_items_helper(child, rect, items, transform, viewTransform, + recursive_items_helper(child, intersector, items, transform, viewTransform, mode, order, opacity); } } @@ -147,7 +214,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe // Process children in front if (!dontProcessChildren) { for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), rect, items, transform, viewTransform, + recursive_items_helper(children.at(i), intersector, items, transform, viewTransform, mode, order, opacity); } @@ -161,156 +228,6 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe } } -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - // ### is this needed? - if (parentClip && !parent->boundingRect().contains(pos)) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; - - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - if (item->contains(item->mapFromParent(pos))) { - items->append(item); - keep = true; - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) - // Recurse into children. - childItems_helper(items, item, item->mapFromParent(pos)); - } -} - -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QPainterPath path; - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(polygon), mode); - } - } -} - -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF pathRect(path.boundingRect()); - _q_adjustRect(&pathRect); - QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { - if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(path), mode); - } - } -} - /*! Constructs an abstract scene index. */ @@ -363,162 +280,50 @@ QRectF QGraphicsSceneIndex::indexedRect() const QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect = QRectF(pos, QSize(1,1)); - foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (item->contains(xinv.map(pos))) { - items << item; - keep = true; - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - d->childItems_helper(&items, item, xinv.map(pos)); - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + QList itemList; + d->pointIntersector->mode = mode; + d->pointIntersector->rect = QRectF(pos, QSize(1,1)); + d->pointIntersector->pos = pos; + d->recursive_items_helper(0, d->pointIntersector, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; - d->recursive_items_helper(0, rect, &itemList, QTransform(), deviceTransform, mode, order); + d->rectIntersector->mode = mode; + d->rectIntersector->rect = rect; + d->recursive_items_helper(0, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; - + QList itemList; QRectF polyRect(polygon.boundingRect()); _q_adjustRect(&polyRect); + d->pathIntersector->mode = mode; + d->pathIntersector->rect = polyRect; QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItems(polyRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - d->childItems_helper(&items, item, xinv.map(polygon), mode); - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + path.addPolygon(polygon); + d->pathIntersector->path = path; + d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } + QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; + QList itemList; QRectF pathRect(path.controlPointRect()); _q_adjustRect(&pathRect); - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItems(pathRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Path contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - d->childItems_helper(&items, item, xinv.map(path), mode); - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + d->pathIntersector->mode = mode; + d->pathIntersector->rect = pathRect; + d->pathIntersector->path = path; + d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } /*! @@ -592,6 +397,8 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) */ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value) { + //Q_UNUSED(item); + //Q_UNUSED(value); } /*! @@ -601,6 +408,7 @@ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem:: */ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { + //Q_UNUSED(item); } /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 3a2cb27..d0d181b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -63,30 +63,38 @@ QT_BEGIN_NAMESPACE class QGraphicsScene; +class QGraphicsSceneIndexIntersector; +class QGraphicsSceneIndexRectIntersector; +class QGraphicsSceneIndexPointIntersector; +class QGraphicsSceneIndexPathIntersector; class QGraphicsSceneIndexPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGraphicsSceneIndex) public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); + ~QGraphicsSceneIndexPrivate(); - void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList *items, + void recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; - - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const; - QGraphicsScene *scene; + QGraphicsSceneIndexPointIntersector *pointIntersector; + QGraphicsSceneIndexRectIntersector *rectIntersector; + QGraphicsSceneIndexPathIntersector *pathIntersector; +}; + +class QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexIntersector(QGraphicsScene *scene) : scene(scene) { } + virtual ~QGraphicsSceneIndexIntersector() { } + virtual bool intersect(const QRectF &rect) const = 0; + Qt::ItemSelectionMode mode; + QGraphicsItem *item; + QGraphicsScene *scene; + QRectF rect; + QTransform transform; }; QT_END_NAMESPACE -- cgit v0.12 From 3dce31e5eb0fac43d445fb9664f1b68f4cd4c11f Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 10:26:34 +0200 Subject: Warnings -- --- src/gui/graphicsview/qgraphicssceneindex.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 8d18806..3c4efe7 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -395,10 +395,11 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) \sa GraphicsItemChange */ -void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value) +void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { - //Q_UNUSED(item); - //Q_UNUSED(value); + Q_UNUSED(item); + Q_UNUSED(change); + Q_UNUSED(value); } /*! @@ -408,7 +409,7 @@ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem:: */ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { - //Q_UNUSED(item); + Q_UNUSED(item); } /*! @@ -418,6 +419,7 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) */ void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) { + Q_UNUSED(rect); } QT_END_NAMESPACE -- cgit v0.12 From 2ceb72068fbb9157a058a1788863b68a12d25646 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 11:41:35 +0200 Subject: Fix all documentation warnings. --- src/gui/graphicsview/qgraphicsitem.h | 2 - src/gui/graphicsview/qgraphicsscene.cpp | 50 +++++++++---- src/gui/graphicsview/qgraphicssceneindex.cpp | 106 ++++++++++++++++++++++----- 3 files changed, 125 insertions(+), 33 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 6194249..56a4a3b 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -418,8 +418,6 @@ protected: virtual void setExtension(Extension extension, const QVariant &variant); virtual QVariant extension(const QVariant &variant) const; - bool operator<(const QGraphicsItem *other) const; - protected: QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 6e08a76..0729a9d 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -201,6 +201,8 @@ however, is done in constant time. This approach is ideal for dynamic scenes, where many items are added, moved or removed continuously. + \omitvalue CustomIndex + \sa setItemIndexMethod(), bspTreeDepth */ @@ -312,6 +314,9 @@ void QGraphicsScenePrivate::init() q->update(); } +/*! + \internal +*/ QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q) { return q->d_func(); @@ -454,11 +459,11 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) markDirty(item, QRectF(), false, false, false, false, /*removingItemFromScene=*/true); if (item->d_ptr->inDestructor) { - // Can potentially call item->boundingRect() (virtual function), that's why - // we only can call this function if the item is not in its destructor. + // The item is actually in its destructor, we call the special method in the index. index->deleteItem(item); } else { - // Remove it from the index properly + // Can potentially call item->boundingRect() (virtual function), that's why + // we only can call this function if the item is not in its destructor. index->removeItem(item); } @@ -1569,6 +1574,13 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->indexMethod = method; } +/*! + \brief the item indexing method. + This method allow to apply an indexing algorithm \a index to the scene, to speed up + item discovery functions like items() and itemAt(). + + \sa sceneIndex(), QGraphicsSceneIndex +*/ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) { Q_D(QGraphicsScene); @@ -1583,6 +1595,11 @@ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) } } +/*! + This method return the current indexing algorithm of the scene. + + \sa setSceneIndex(), QGraphicsSceneIndex +*/ QGraphicsSceneIndex* QGraphicsScene::sceneIndex() const { Q_D(const QGraphicsScene); @@ -1784,10 +1801,13 @@ QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemS } /*! - Returns all visible items at position \a pos in the scene. + Returns all visible items that, depending on \a mode, are at the specified \a pos + and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose - exact shape intersects with or is contained by \a path are returned. + exact shape intersects with \a pos are returned. + + \a deviceTransform is the transformation apply to the view. \sa itemAt() */ @@ -1798,15 +1818,15 @@ QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelecti } /*! - \fn QList QGraphicsScene::items(const QRectF &rectangle, Qt::SortOrder order, const QTransform &deviceTransform) const - \overload Returns all visible items that, depending on \a mode, are either inside or - intersect with the specified \a rectangle. + intersect with the specified \a rect and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose - exact shape intersects with or is contained by \a rectangle are returned. + exact shape intersects with or is contained by \a rect are returned. + + \a deviceTransform is the transformation apply to the view. \sa itemAt() */ @@ -1820,11 +1840,13 @@ QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti \overload Returns all visible items that, depending on \a mode, are either inside or - intersect with the polygon \a polygon. + intersect with the specified \a polygon and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose exact shape intersects with or is contained by \a polygon are returned. + \a deviceTransform is the transformation apply to the view. + \sa itemAt() */ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const @@ -1834,14 +1856,16 @@ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS } /*! - \overload + \overload - Returns all visible items that, depending on \a path, are either inside or - intersect with the path \a path. + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a path and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose exact shape intersects with or is contained by \a path are returned. + \a deviceTransform is the transformation apply to the view. + \sa itemAt() */ QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 3c4efe7..b713452 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -38,6 +38,22 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +/*! + \class QGraphicsSceneIndex + \brief The QGraphicsSceneIndex class provides a base class to implement + a custom indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + + The QGraphicsSceneIndex class provides a base class to implement + a custom indexing algorithm for discovering items in QGraphicsScene. You + need to subclass it and reimplement addItem, removeItem, estimateItems + and items in order to have an functional indexing. + + \sa QGraphicsScene, QGraphicsView +*/ #include "qgraphicssceneindex.h" #include "qgraphicssceneindex_p.h" @@ -229,7 +245,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr } /*! - Constructs an abstract scene index. + Constructs an abstract scene index for a given \a scene. */ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) : QObject(*new QGraphicsSceneIndexPrivate(scene), scene) @@ -271,12 +287,17 @@ QRectF QGraphicsSceneIndex::indexedRect() const } /*! - \fn QList items() const = 0 + \fn QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const - This pure virtual function return the list of items that are actually in the index. + Returns all visible items that, depending on \a mode, are at the specified \a pos + and return a list sorted using \a order. -*/ + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with \a pos are returned. + + \a deviceTransform is the transformation apply to the view. +*/ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -288,6 +309,20 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe return itemList; } +/*! + \fn QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a rect are returned. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -298,6 +333,20 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe return itemList; } +/*! + \fn QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a polygon and return a list sorted using \a order. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a polygon are returned. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -313,6 +362,20 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: return itemList; } +/*! + \fn QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a path and return a list sorted using \a order. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a path are returned. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -327,8 +390,9 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: } /*! - This pure virtual function return an estimation of items at position \a pos. - + This virtual function return an estimation of items at position \a point. + This method return a list sorted using \a order. + \a deviceTransform is the transformation apply to the view. */ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -336,12 +400,18 @@ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, } /*! - \fn virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 + \fn virtual QList QGraphicsSceneIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 This pure virtual function return an estimation of items in the \a rect. + This method return a list sorted using \a order. + \a deviceTransform is the transformation apply to the view. */ +/*! + \fn virtual QList QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; + This pure virtual function all items in the index and sort them using \a order. +*/ /*! This virtual function removes all items in the scene index. @@ -353,23 +423,23 @@ void QGraphicsSceneIndex::clear() } /*! - \fn virtual void addItem(QGraphicsItem *item) = 0 + \fn virtual void QGraphicsSceneIndex::addItem(QGraphicsItem *item) = 0 - This pure virtual function inserts an item to the scene index. + This pure virtual function inserts an \a item to the scene index. \sa removeItem(), deleteItem() */ /*! - \fn virtual void removeItem(QGraphicsItem *item) = 0 + \fn virtual void QGraphicsSceneIndex::removeItem(QGraphicsItem *item) = 0 - This pure virtual function removes an item to the scene index. + This pure virtual function removes an \a item to the scene index. \sa addItem(), deleteItem() */ /*! - This method is called when an item has been deleted. + This method is called when an \a item has been deleted. The default implementation call removeItem. Be carefull, if your implementation of removeItem use pure virtual method of QGraphicsItem like boundingRect(), then you should reimplement @@ -384,7 +454,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) /*! This virtual function is called by QGraphicsItem to notify the index - that some part of the item's state changes. By reimplementing this + that some part of the \a item 's state changes. By reimplementing this function, your can react to a change, and in some cases, (depending on \a change,) adjustments in the index can be made. @@ -393,7 +463,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) The default implementation does nothing. - \sa GraphicsItemChange + \sa QGraphicsItem::GraphicsItemChange */ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { @@ -403,9 +473,9 @@ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem:: } /*! - Notify the index for a geometry change of an item. + Notify the index for a geometry change of an \a item. - \sa QGraphicsItem::prepareGeometryChange + \sa QGraphicsItem::prepareGeometryChange() */ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { @@ -414,8 +484,8 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) /*! This virtual function is called when the scene changes its bounding - rectangle. - \sa QGraphicsScene::sceneRect + rectangle. \a rect is the new value of the scene rectangle. + \sa QGraphicsScene::sceneRect() */ void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) { -- cgit v0.12 From 0fa15d71015adfd8895ef41a082fb9479bf4bb3d Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 13:45:36 +0200 Subject: Remove old legacy and fix documentation. --- src/gui/graphicsview/graphicsview.pri | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 12 +- src/gui/graphicsview/qgraphicsscene_p.h | 4 +- .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 145 ++++++++++++++++++++- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 27 ++++ src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 37 +++--- 7 files changed, 198 insertions(+), 33 deletions(-) diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 9dc4112..a4d142a 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -18,6 +18,7 @@ SOURCES += graphicsview/qgraphicsitem.cpp \ graphicsview/qgraphicsscene.cpp \ graphicsview/qgraphicsscene_bsp.cpp \ graphicsview/qgraphicsscenebsptreeindex_p.cpp \ + graphicsview/qgraphicsscenelinearindex.cpp \ graphicsview/qgraphicssceneindex.cpp \ graphicsview/qgraphicssceneevent.cpp \ graphicsview/qgraphicsview.cpp diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0729a9d..328ab4c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -271,9 +271,8 @@ static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraph QGraphicsScenePrivate::QGraphicsScenePrivate() : changedSignalMask(0), indexMethod(QGraphicsScene::BspTreeIndex), - bspTreeDepth(0), - lastItemCount(0), index(0), + lastItemCount(0), hasSceneRect(false), updateAll(false), calledEmitUpdated(false), @@ -1642,14 +1641,11 @@ int QGraphicsScene::bspTreeDepth() const { Q_D(const QGraphicsScene); QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); - return bspTree ? bspTree->bspDepth() : 0; + return bspTree ? bspTree->bspTreeDepth() : 0; } void QGraphicsScene::setBspTreeDepth(int depth) { Q_D(QGraphicsScene); - if (d->bspTreeDepth == depth) - return; - if (depth < 0) { qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth); return; @@ -1660,8 +1656,10 @@ void QGraphicsScene::setBspTreeDepth(int depth) qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP"); return; } + if (bspTree->bspTreeDepth() == depth) + return; - bspTree->setBspDepth(depth); + bspTree->setBspTreeDepth(depth); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index c63e121..db401ef 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -90,12 +90,10 @@ public: quint32 changedSignalMask; QGraphicsScene::ItemIndexMethod indexMethod; - int bspTreeDepth; + QGraphicsSceneIndex *index; int lastItemCount; - QGraphicsSceneIndex *index; - QRectF sceneRect; bool hasSceneRect; QRectF growingItemsBoundingRect; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index acadcbd..b19248a 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -39,6 +39,40 @@ ** ****************************************************************************/ +/*! + \class QGraphicsSceneBspTreeIndex + \brief The QGraphicsSceneBspTreeIndex class provides an implementation of + a BSP indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + + QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) + implementation to discover items quickly. This implementation is + very efficient for static scene. It has a depth that you can set. + The depth directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + + \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex +*/ #include "qgraphicsscenebsptreeindex_p.h" @@ -61,7 +95,7 @@ static inline int intmaxlog(int n) } /*! - Constructs a private scene index. + Constructs a private scene bsp index. */ QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) : QGraphicsSceneIndexPrivate(scene), @@ -78,6 +112,11 @@ QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsSc /*! + This method will update the BSP index by removing the items from the temporary + unindexed list and add them in the indexedItems list. This will also + update the growingItemsBoundingRect if needed. This will update the BSP + implementation as well. + \internal */ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() @@ -223,6 +262,9 @@ void QGraphicsSceneBspTreeIndexPrivate::resetIndex() startIndexTimer(); } +/*! + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) { if (!item->d_ptr->children.isEmpty()) { @@ -244,6 +286,9 @@ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stac } } +/*! + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() { Q_Q(QGraphicsSceneBspTreeIndex); @@ -268,6 +313,9 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() climbTree(topLevels.at(i), &stackingOrder); } +/*! + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() { Q_Q(QGraphicsSceneBspTreeIndex); @@ -342,6 +390,11 @@ bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGrap return closestItemFirst_withoutCache(item2, item1); } +/*! + Sort a list of \a itemList in a specific \a order and use the cache if requested. + + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, bool sortCacheEnabled) { @@ -360,12 +413,19 @@ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemLi } } +/*! + Constructs a BSP scene index for the given \a scene. +*/ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) { } +/*! + \reimp + Return the rect indexed by the BSP index. +*/ QRectF QGraphicsSceneBspTreeIndex::indexedRect() const { Q_D(const QGraphicsSceneBspTreeIndex); @@ -373,6 +433,10 @@ QRectF QGraphicsSceneBspTreeIndex::indexedRect() const return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; } +/*! + \reimp + Clear the all the BSP index. +*/ void QGraphicsSceneBspTreeIndex::clear() { Q_D(QGraphicsSceneBspTreeIndex); @@ -383,6 +447,9 @@ void QGraphicsSceneBspTreeIndex::clear() d->unindexedItems.clear(); } +/*! + Add the \a item into the BSP index. +*/ void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -405,6 +472,7 @@ void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) } /*! + This really add the item in the BSP. \internal */ void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) @@ -421,6 +489,9 @@ void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) } } +/*! + Remove the \a item from the BSP index. +*/ void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -443,6 +514,10 @@ void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) } } +/*! + \reimp + Delete the \a item from the BSP index (without accessing its boundingRect). +*/ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -469,6 +544,7 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) } /*! + Really remove the item from the BSP \internal */ void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) @@ -492,6 +568,10 @@ void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) startIndexTimer(); } +/*! + \reimp + Update the BSP when the \a item 's bounding rect has changed. +*/ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -501,6 +581,13 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * d->removeFromIndex(const_cast(item)); } +/*! + Returns an estimation visible items that are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneBspTreeIndex); @@ -530,6 +617,12 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r return rectItems; } + +/*! + \fn QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; + + Return all items in the BSP index and sort them using \a order. +*/ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const { Q_D(const QGraphicsSceneBspTreeIndex); @@ -558,19 +651,52 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co return itemList; } -int QGraphicsSceneBspTreeIndex::bspDepth() +/*! + \property QGraphicsSceneBspTreeIndex::bspTreeDepth + \brief the depth of the BSP index tree + \since 4.6 + + This value determines the depth of BSP tree. The depth + directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + +*/ +int QGraphicsSceneBspTreeIndex::bspTreeDepth() { Q_D(const QGraphicsSceneBspTreeIndex); return d->bspTreeDepth; } -void QGraphicsSceneBspTreeIndex::setBspDepth(int depth) +void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) { Q_D(QGraphicsSceneBspTreeIndex); d->bspTreeDepth = depth; d->resetIndex(); } +/*! + \reimp + + This method react to the \a rect change of the scene and + reset the BSP tree index. +*/ void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) { Q_D(QGraphicsSceneBspTreeIndex); @@ -578,6 +704,13 @@ void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) d->resetIndex(); } +/*! + \reimp + + This method react to the \a change of the \a item and use the \a value to + update the BSP tree if necessary. + +*/ void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { Q_D(QGraphicsSceneBspTreeIndex); @@ -592,7 +725,13 @@ void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphic } return QGraphicsSceneIndex::itemChanged(item, change, value); } +/*! + \reimp + Used to catch the timer event. + + \internal +*/ bool QGraphicsSceneBspTreeIndex::event(QEvent *event) { Q_D(QGraphicsSceneBspTreeIndex); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index b1ea977..40b8f0b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -60,6 +60,7 @@ class QGraphicsSceneBspTreeIndexPrivate; class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex { Q_OBJECT + Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); QRectF indexedRect() const; @@ -68,8 +69,8 @@ public: QList items(Qt::SortOrder order = Qt::AscendingOrder) const; - int bspDepth(); - void setBspDepth(int depth); + int bspTreeDepth(); + void setBspTreeDepth(int depth); protected: bool event(QEvent *event); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index b713452..05ec28b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -147,6 +147,9 @@ QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate() delete pathIntersector; } +/*! + \internal +*/ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, @@ -297,6 +300,12 @@ QRectF QGraphicsSceneIndex::indexedRect() const \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -322,6 +331,12 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -346,6 +361,12 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -375,6 +396,12 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 3057b4a..d21475c 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -68,23 +68,32 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex { Q_OBJECT -private: - QRectF m_sceneRect; - QList m_items; - public: QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) { } - virtual void setRect(const QRectF &rect) { - m_sceneRect = rect; + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { + Q_UNUSED(order); + return m_items; + } + + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_UNUSED(rect); + Q_UNUSED(order); + Q_UNUSED(deviceTransform); + return m_items; } - virtual QRectF rect() const { + virtual QRectF indexedRect() const { return m_sceneRect; } +protected : + void sceneRectChanged(const QRectF &rect) { + m_sceneRect = rect; + } + virtual void clear() { m_items.clear(); } @@ -97,17 +106,9 @@ public: m_items.removeAll(item); } - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - QList result; - foreach (QGraphicsItem *item, m_items) - if (item->sceneBoundingRect().intersects(rect)) - result << item; - return result; - } - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - return m_items; - } +private: + QRectF m_sceneRect; + QList m_items; }; QT_END_NAMESPACE -- cgit v0.12 From 8dee7b0c5be293f4b8ebafcae6baa052ca92f1d0 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 13:46:43 +0200 Subject: Add missing file. --- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex.cpp diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp new file mode 100644 index 0000000..1c898bc --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -0,0 +1,70 @@ +#include "qgraphicsscenelinearindex_p.h" + +/*! + \class QGraphicsSceneLinearIndex + \brief The QGraphicsSceneLinearIndex class provides an implementation of + a linear indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + + QGraphicsSceneLinearIndex index is default linear implementation to discover items. + It basically store all items in a list and return them to the scene. + + \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex, QGraphicsSceneBspTreeIndex +*/ + +/*! + \fn QGraphicsSceneLinearIndex::QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): + + Construct a linear index for the given \a scene. +*/ + +/*! + \fn QList QGraphicsSceneLinearIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; + + Return all items in the index and sort them using \a order. +*/ + + +/*! + \fn virtual QList QGraphicsSceneLinearIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; + + Returns an estimation visible items that are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + \a deviceTransform is the transformation apply to the view. + +*/ + +/*! + \fn QRectF QGraphicsSceneLinearIndex::indexedRect() const; + \reimp + Return the rect indexed by the the index. +*/ + +/*! + \fn void QGraphicsSceneLinearIndex::sceneRectChanged(const QRectF &rect); + \reimp + This method react to the \a rect change of the scene. +*/ + +/*! + \fn void QGraphicsSceneLinearIndex::clear(); + \reimp + Clear the all the BSP index. +*/ + +/*! + \fn virtual void QGraphicsSceneLinearIndex::addItem(QGraphicsItem *item); + + Add the \a item into the index. +*/ + +/*! + \fn virtual void QGraphicsSceneLinearIndex::removeItem(QGraphicsItem *item); + + Add the \a item from the index. +*/ + -- cgit v0.12 From d72727cb7530da54b59c51effa97263512e9238c Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 17 Jun 2009 11:25:36 +0200 Subject: Fix broken auto-test for the index. Since now items() doesn't use the index then the growingboundingrect is not updated if you call right after a delete. It's because the timer is not yet fired (even the processEvent) so you call add, move, remove which will trigger only one update index so the growingboundingrect will never change. --- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 4d786c7..17d290b 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -2726,8 +2726,8 @@ void tst_QGraphicsScene::update() qRegisterMetaType >("QList"); QSignalSpy spy(&scene, SIGNAL(changed(QList))); - // When deleted, the item will lazy-remove itself - delete rect; + // We update the scene. + scene.update(); // This function forces a purge, which will post an update signal scene.itemAt(0, 0); -- cgit v0.12 From 8a0e002ccc762ef3edbc3c9ad91b4d6017cb91bb Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 17 Jun 2009 14:15:14 +0200 Subject: Make eveything internal for now but ready to see the light. --- src/gui/graphicsview/graphicsview.pri | 6 +- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 7 +- src/gui/graphicsview/qgraphicsscene_p.h | 1 - .../graphicsview/qgraphicsscenebsptreeindex.cpp | 761 +++++++++++++++++++++ src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 119 ++++ .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 760 -------------------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 137 ++-- .../graphicsview/qgraphicsscenebsptreeindex_p_p.h | 150 ---- src/gui/graphicsview/qgraphicssceneindex.cpp | 2 +- src/gui/graphicsview/qgraphicssceneindex.h | 13 +- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 3 +- src/gui/graphicsview/qgraphicsscenelinearindex.h | 124 ++++ src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 118 ---- 14 files changed, 1122 insertions(+), 1081 deletions(-) create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex.h delete mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp delete mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h create mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex.h delete mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index a4d142a..5ac1c54 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -5,11 +5,11 @@ HEADERS += graphicsview/qgraphicsitem.h \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ - graphicsview/qgraphicsscenelinearindex_p.h \ + graphicsview/qgraphicsscenelinearindex.h \ graphicsview/qgraphicssceneindex.h \ graphicsview/qgraphicssceneindex_p.h \ + graphicsview/qgraphicsscenebsptreeindex.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ - graphicsview/qgraphicsscenebsptreeindex_p_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicsview.h @@ -17,7 +17,7 @@ SOURCES += graphicsview/qgraphicsitem.cpp \ graphicsview/qgraphicsitemanimation.cpp \ graphicsview/qgraphicsscene.cpp \ graphicsview/qgraphicsscene_bsp.cpp \ - graphicsview/qgraphicsscenebsptreeindex_p.cpp \ + graphicsview/qgraphicsscenebsptreeindex.cpp \ graphicsview/qgraphicsscenelinearindex.cpp \ graphicsview/qgraphicssceneindex.cpp \ graphicsview/qgraphicssceneevent.cpp \ diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 39ad447..593d7be 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -554,7 +554,7 @@ #include "qgraphicsview.h" #include "qgraphicswidget.h" #include "qgraphicsproxywidget.h" -#include "qgraphicsscenebsptreeindex_p_p.h" +#include "qgraphicsscenebsptreeindex_p.h" #include #include #include diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 5a3028c..a33cb3e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -220,7 +220,8 @@ #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" #include "qgraphicssceneindex.h" -#include "qgraphicsscenebsptreeindex_p_p.h" +#include "qgraphicsscenebsptreeindex.h" +#include "qgraphicsscenelinearindex.h" #include #include @@ -1574,6 +1575,8 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) } /*! + \internal + \brief the item indexing method. This method allow to apply an indexing algorithm \a index to the scene, to speed up item discovery functions like items() and itemAt(). @@ -1595,6 +1598,8 @@ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) } /*! + \internal + This method return the current indexing algorithm of the scene. \sa setSceneIndex(), QGraphicsSceneIndex diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 72ae158..563e016 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -58,7 +58,6 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicsscenelinearindex_p.h" #include "qgraphicssceneindex.h" #include "qgraphicsview.h" #include "qgraphicsitem_p.h" diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp new file mode 100644 index 0000000..76fd218 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -0,0 +1,761 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QGraphicsSceneBspTreeIndex + \brief The QGraphicsSceneBspTreeIndex class provides an implementation of + a BSP indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + \internal + + QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) + implementation to discover items quickly. This implementation is + very efficient for static scene. It has a depth that you can set. + The depth directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + + \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex +*/ + +#include "qgraphicsscenebsptreeindex.h" + +#ifndef QT_NO_GRAPHICSVIEW + +#include "qgraphicsscenebsptreeindex_p.h" +#include "qgraphicssceneindex_p.h" +#include "qgraphicsitem_p.h" +#include "qgraphicsscene_p.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +static inline int intmaxlog(int n) +{ + return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); +} + +/*! + Constructs a private scene bsp index. +*/ +QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) + : QGraphicsSceneIndexPrivate(scene), + bspTreeDepth(0), + indexTimerId(0), + restartIndexTimer(false), + regenerateIndex(true), + lastItemCount(0), + purgePending(false), + sortCacheEnabled(false), + updatingSortCache(false) +{ +} + + +/*! + This method will update the BSP index by removing the items from the temporary + unindexed list and add them in the indexedItems list. This will also + update the growingItemsBoundingRect if needed. This will update the BSP + implementation as well. + + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!indexTimerId) + return; + + QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); + q->killTimer(indexTimerId); + indexTimerId = 0; + + purgeRemovedItems(); + + // Add unindexedItems to indexedItems + QRectF unindexedItemsBoundingRect; + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + unindexedItemsBoundingRect |= item->sceneBoundingRect(); + if (!freeItemIndexes.isEmpty()) { + int freeIndex = freeItemIndexes.takeFirst(); + item->d_func()->index = freeIndex; + indexedItems[freeIndex] = item; + } else { + item->d_func()->index = indexedItems.size(); + indexedItems << item; + } + } + } + + // Update growing scene rect. + QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; + scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; + + // Determine whether we should regenerate the BSP tree. + if (bspTreeDepth == 0) { + int oldDepth = intmaxlog(lastItemCount); + bspTreeDepth = intmaxlog(indexedItems.size()); + static const int slack = 100; + if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) { + // ### Crude algorithm. + regenerateIndex = true; + } + } + + // Regenerate the tree. + if (regenerateIndex) { + regenerateIndex = false; + bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); + unindexedItems = indexedItems; + lastItemCount = indexedItems.size(); + q->scene()->update(); + + // Take this opportunity to reset our largest-item counter for + // untransformable items. When the items are inserted into the BSP + // tree, we'll get an accurate calculation. + scenePrivate->largestUntransformableItem = QRectF(); + } + + // Insert all unindexed items into the tree. + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + continue; + + bsp.insertItem(item, rect); + + // If the item ignores view transformations, update our + // largest-item-counter to ensure that the view can accurately + // discover untransformable items when drawing. + if (item->d_ptr->itemIsUntransformable()) { + QGraphicsItem *topmostUntransformable = item; + while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags + & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { + topmostUntransformable = topmostUntransformable->parentItem(); + } + // ### Verify that this is the correct largest untransformable rectangle. + scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); + } + } + } + unindexedItems.clear(); + + // Notify scene rect changes. + if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) + emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); +} + + +/*! + \internal + + Removes stale pointers from all data structures. +*/ +void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() +{ + if (!purgePending && removedItems.isEmpty()) + return; + + // Remove stale items from the BSP tree. + bsp.removeItems(removedItems); + // Purge this list. + removedItems.clear(); + freeItemIndexes.clear(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (!indexedItems.at(i)) + freeItemIndexes << i; + } + purgePending = false; +} + +/*! + \internal + + Starts or restarts the timer used for reindexing unindexed items. +*/ +void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer(int interval) +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (indexTimerId) { + restartIndexTimer = true; + } else { + indexTimerId = q->startTimer(interval); + } +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::resetIndex() +{ + purgeRemovedItems(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (QGraphicsItem *item = indexedItems.at(i)) { + item->d_ptr->index = -1; + unindexedItems << item; + } + } + indexedItems.clear(); + freeItemIndexes.clear(); + regenerateIndex = true; + startIndexTimer(); +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) +{ + if (!item->d_ptr->children.isEmpty()) { + QList childList = item->d_ptr->children; + qSort(childList.begin(), childList.end(), qt_closestLeaf); + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) + climbTree(childList.at(i), stackingOrder); + } + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (item->flags() & QGraphicsItem::ItemStacksBehindParent) + climbTree(childList.at(i), stackingOrder); + } + } else { + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + } +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + _q_updateIndex(); + + if (!sortCacheEnabled || !updatingSortCache) + return; + + updatingSortCache = false; + int stackingOrder = 0; + + QList topLevels; + + for (int i = 0; i < q->items().count(); ++i) { + QGraphicsItem *item = q->items().at(i); + if (item && item->parentItem() == 0) + topLevels << item; + } + + qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); + for (int i = 0; i < topLevels.size(); ++i) + climbTree(topLevels.at(i), &stackingOrder); +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!sortCacheEnabled || updatingSortCache) + return; + + updatingSortCache = true; + QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); +} + +/*! + Returns true if \a item1 is on top of \a item2. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Siblings? Just check their z-values. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + if (d1->parent == d2->parent) + return qt_closestLeaf(item1, item2); + + // Find common ancestor, and each item's ancestor closest to the common + // ancestor. + int item1Depth = d1->depth; + int item2Depth = d2->depth; + const QGraphicsItem *p = item1; + const QGraphicsItem *t1 = item1; + while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { + if (p == item2) { + // item2 is one of item1's ancestors; item1 is on top + return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t1 = p; + --item1Depth; + } + p = item2; + const QGraphicsItem *t2 = item2; + while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { + if (p == item1) { + // item1 is one of item2's ancestors; item1 is not on top + return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t2 = p; + --item2Depth; + } + + // item1Ancestor is now at the same level as item2Ancestor, but not the same. + const QGraphicsItem *a1 = t1; + const QGraphicsItem *a2 = t2; + while (a1) { + const QGraphicsItem *p1 = a1; + const QGraphicsItem *p2 = a2; + a1 = a1->parentItem(); + a2 = a2->parentItem(); + if (a1 && a1 == a2) + return qt_closestLeaf(p1, p2); + } + + // No common ancestor? Then just compare the items' toplevels directly. + return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); +} + +/*! + Returns true if \a item2 is on top of \a item1. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + return closestItemFirst_withoutCache(item2, item1); +} + +/*! + Sort a list of \a itemList in a specific \a order and use the cache if requested. + + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, + bool sortCacheEnabled) +{ + if (sortCacheEnabled) { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); + } + } else { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); + } + } +} + +/*! + Constructs a BSP scene index for the given \a scene. +*/ +QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) + : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) +{ + +} + +/*! + \reimp + Return the rect indexed by the BSP index. +*/ +QRectF QGraphicsSceneBspTreeIndex::indexedRect() const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->_q_updateIndex(); + return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; +} + +/*! + \reimp + Clear the all the BSP index. +*/ +void QGraphicsSceneBspTreeIndex::clear() +{ + Q_D(QGraphicsSceneBspTreeIndex); + d->bsp.clear(); + d->lastItemCount = 0; + d->freeItemIndexes.clear(); + d->indexedItems.clear(); + d->unindexedItems.clear(); +} + +/*! + Add the \a item into the BSP index. +*/ +void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Prevent reusing a recently deleted pointer: purge all removed items + // from our lists. + d->purgeRemovedItems(); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + // Update the scene's sort cache settings. + item->d_ptr->globalStackingOrder = -1; + d->invalidateSortCache(); + + // Indexing requires sceneBoundingRect(), but because \a item might + // not be completely constructed at this point, we need to store it in + // a temporary list and schedule an indexing for later. + d->unindexedItems << item; + item->d_func()->index = -1; + d->startIndexTimer(0); +} + +/*! + This really add the item in the BSP. + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) +{ + if (item->d_func()->index != -1) { + bsp.insertItem(item, item->sceneBoundingRect()); + foreach (QGraphicsItem *child, item->children()) + child->addToIndex(); + } else { + // The BSP tree is regenerated if the number of items grows to a + // certain threshold, or if the bounding rect of the graph doubles in + // size. + startIndexTimer(); + } +} + +/*! + Remove the \a item from the BSP index. +*/ +void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + d->removeFromIndex(item); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); + + // Remove from our item lists. + int index = item->d_func()->index; + if (index != -1) { + d->freeItemIndexes << index; + d->indexedItems[index] = 0; + } else { + d->unindexedItems.removeAll(item); + } +} + +/*! + \reimp + Delete the \a item from the BSP index (without accessing its boundingRect). +*/ +void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); + + int index = item->d_func()->index; + if (index != -1) { + // Important: The index is useless until purgeRemovedItems() is + // called. + d->indexedItems[index] = (QGraphicsItem *)0; + if (!d->purgePending) { + d->purgePending = true; + scene()->update(); + } + d->removedItems << item; + } else { + // Recently added items are purged immediately. unindexedItems() never + // contains stale items. + d->unindexedItems.removeAll(item); + scene()->update(); + } +} + +/*! + Really remove the item from the BSP + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) +{ + if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + // ### remove from child index only if applicable + return; + } + int index = item->d_func()->index; + if (index != -1) { + bsp.removeItem(item, item->sceneBoundingRect()); + freeItemIndexes << index; + indexedItems[index] = 0; + item->d_func()->index = -1; + unindexedItems << item; + + //prepareGeometryChange will call prepareBoundingRectChange + foreach (QGraphicsItem *child, item->children()) + child->prepareGeometryChange(); + } + startIndexTimer(); +} + +/*! + \reimp + Update the BSP when the \a item 's bounding rect has changed. +*/ +void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + d->removeFromIndex(const_cast(item)); +} + +/*! + Returns an estimation visible items that are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + \a deviceTransform is the transformation apply to the view. + +*/ +QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + const_cast(d)->_q_updateSortCache(); + + QList rectItems = d->bsp.items(rect); + // Fill in with any unindexed items + for (int i = 0; i < d->unindexedItems.size(); ++i) { + if (QGraphicsItem *item = d->unindexedItems.at(i)) { + if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { + QRectF boundingRect = item->sceneBoundingRect(); + if (QRectF_intersects(boundingRect, rect)) { + item->d_ptr->itemDiscovered = 1; + rectItems << item; + } + } + } + } + + // Reset the discovered state of all discovered items + for (int i = 0; i < rectItems.size(); ++i) + rectItems.at(i)->d_func()->itemDiscovered = 0; + + d->sortItems(&rectItems, order, d->sortCacheEnabled); + + return rectItems; +} + + +/*! + \fn QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; + + Return all items in the BSP index and sort them using \a order. +*/ +QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + QList itemList; + // If freeItemIndexes is empty, we know there are no holes in indexedItems and + // unindexedItems. + if (d->freeItemIndexes.isEmpty()) { + if (d->unindexedItems.isEmpty()) { + itemList = d->indexedItems; + } else { + itemList = d->indexedItems + d->unindexedItems; + } + } else { + // Rebuild the list of items to avoid holes. ### We could also just + // compress the item lists at this point. + foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { + if (item) + itemList << item; + } + } + if (order != -1) { + //We sort descending order + d->sortItems(&itemList, order, d->sortCacheEnabled); + } + return itemList; +} + +/*! + \property QGraphicsSceneBspTreeIndex::bspTreeDepth + \brief the depth of the BSP index tree + \since 4.6 + + This value determines the depth of BSP tree. The depth + directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + +*/ +int QGraphicsSceneBspTreeIndex::bspTreeDepth() +{ + Q_D(const QGraphicsSceneBspTreeIndex); + return d->bspTreeDepth; +} + +void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) +{ + Q_D(QGraphicsSceneBspTreeIndex); + d->bspTreeDepth = depth; + d->resetIndex(); +} + +/*! + \reimp + + This method react to the \a rect change of the scene and + reset the BSP tree index. +*/ +void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) +{ + Q_D(QGraphicsSceneBspTreeIndex); + d->sceneRect = rect; + d->resetIndex(); +} + +/*! + \reimp + + This method react to the \a change of the \a item and use the \a value to + update the BSP tree if necessary. + +*/ +void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + Q_D(QGraphicsSceneBspTreeIndex); + switch (change) { + case QGraphicsItem::ItemZValueChange: + case QGraphicsItem::ItemParentChange: { + d->invalidateSortCache(); + break; + } + default: + break; + } + return QGraphicsSceneIndex::itemChanged(item, change, value); +} +/*! + \reimp + + Used to catch the timer event. + + \internal +*/ +bool QGraphicsSceneBspTreeIndex::event(QEvent *event) +{ + Q_D(QGraphicsSceneBspTreeIndex); + switch (event->type()) { + case QEvent::Timer: + if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { + if (d->restartIndexTimer) { + d->restartIndexTimer = false; + } else { + // this call will kill the timer + d->_q_updateIndex(); + } + } + // Fallthrough intended - support timers in subclasses. + default: + return QObject::event(event); + } + return true; +} + +QT_END_NAMESPACE + +#include "moc_qgraphicsscenebsptreeindex.cpp" + +#endif // QT_NO_GRAPHICSVIEW + diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h new file mode 100644 index 0000000..0444a30 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QGRAPHICSBSPTREEINDEX_H +#define QGRAPHICSBSPTREEINDEX_H + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include +#include + +#include "qgraphicsscene_bsp_p.h" + +class QGraphicsSceneBspTreeIndexPrivate; + +class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) +public: + QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + QRectF indexedRect() const; + + QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const; + + int bspTreeDepth(); + void setBspTreeDepth(int depth); + +protected: + bool event(QEvent *event); + void clear(); + + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); + + void sceneRectChanged(const QRectF &rect); + void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + +private : + Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) + Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) + Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; +}; + +#endif // QT_NO_GRAPHICSVIEW + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGRAPHICSBSPTREEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp deleted file mode 100644 index b19248a..0000000 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ /dev/null @@ -1,760 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QGraphicsSceneBspTreeIndex - \brief The QGraphicsSceneBspTreeIndex class provides an implementation of - a BSP indexing algorithm for discovering items in QGraphicsScene. - \since 4.6 - \ingroup multimedia - \ingroup graphicsview-api - \mainclass - - QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) - implementation to discover items quickly. This implementation is - very efficient for static scene. It has a depth that you can set. - The depth directly affects performance and memory usage; the latter - growing exponentially with the depth of the tree. With an optimal tree - depth, the index can instantly determine the locality of items, even - for scenes with thousands or millions of items. This also greatly improves - rendering performance. - - By default, the value is 0, in which case Qt will guess a reasonable - default depth based on the size, location and number of items in the - scene. If these parameters change frequently, however, you may experience - slowdowns as the index retunes the depth internally. You can avoid - potential slowdowns by fixating the tree depth through setting this - property. - - The depth of the tree and the size of the scene rectangle decide the - granularity of the scene's partitioning. The size of each scene segment is - determined by the following algorithm: - - The BSP tree has an optimal size when each segment contains between 0 and - 10 items. - - \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex -*/ - -#include "qgraphicsscenebsptreeindex_p.h" - -#ifndef QT_NO_GRAPHICSVIEW - -#include "qgraphicsscenebsptreeindex_p_p.h" -#include "qgraphicssceneindex_p.h" -#include "qgraphicsitem_p.h" -#include "qgraphicsscene_p.h" - -#include - -#include - -QT_BEGIN_NAMESPACE - -static inline int intmaxlog(int n) -{ - return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); -} - -/*! - Constructs a private scene bsp index. -*/ -QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) - : QGraphicsSceneIndexPrivate(scene), - bspTreeDepth(0), - indexTimerId(0), - restartIndexTimer(false), - regenerateIndex(true), - lastItemCount(0), - purgePending(false), - sortCacheEnabled(false), - updatingSortCache(false) -{ -} - - -/*! - This method will update the BSP index by removing the items from the temporary - unindexed list and add them in the indexedItems list. This will also - update the growingItemsBoundingRect if needed. This will update the BSP - implementation as well. - - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() -{ - Q_Q(QGraphicsSceneBspTreeIndex); - if (!indexTimerId) - return; - - QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); - q->killTimer(indexTimerId); - indexTimerId = 0; - - purgeRemovedItems(); - - // Add unindexedItems to indexedItems - QRectF unindexedItemsBoundingRect; - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); - if (!freeItemIndexes.isEmpty()) { - int freeIndex = freeItemIndexes.takeFirst(); - item->d_func()->index = freeIndex; - indexedItems[freeIndex] = item; - } else { - item->d_func()->index = indexedItems.size(); - indexedItems << item; - } - } - } - - // Update growing scene rect. - QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; - scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; - - // Determine whether we should regenerate the BSP tree. - if (bspTreeDepth == 0) { - int oldDepth = intmaxlog(lastItemCount); - bspTreeDepth = intmaxlog(indexedItems.size()); - static const int slack = 100; - if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) { - // ### Crude algorithm. - regenerateIndex = true; - } - } - - // Regenerate the tree. - if (regenerateIndex) { - regenerateIndex = false; - bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); - unindexedItems = indexedItems; - lastItemCount = indexedItems.size(); - q->scene()->update(); - - // Take this opportunity to reset our largest-item counter for - // untransformable items. When the items are inserted into the BSP - // tree, we'll get an accurate calculation. - scenePrivate->largestUntransformableItem = QRectF(); - } - - // Insert all unindexed items into the tree. - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - QRectF rect = item->sceneBoundingRect(); - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - - bsp.insertItem(item, rect); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); - } - } - } - unindexedItems.clear(); - - // Notify scene rect changes. - if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) - emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); -} - - -/*! - \internal - - Removes stale pointers from all data structures. -*/ -void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() -{ - if (!purgePending && removedItems.isEmpty()) - return; - - // Remove stale items from the BSP tree. - bsp.removeItems(removedItems); - // Purge this list. - removedItems.clear(); - freeItemIndexes.clear(); - for (int i = 0; i < indexedItems.size(); ++i) { - if (!indexedItems.at(i)) - freeItemIndexes << i; - } - purgePending = false; -} - -/*! - \internal - - Starts or restarts the timer used for reindexing unindexed items. -*/ -void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer(int interval) -{ - Q_Q(QGraphicsSceneBspTreeIndex); - if (indexTimerId) { - restartIndexTimer = true; - } else { - indexTimerId = q->startTimer(interval); - } -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::resetIndex() -{ - purgeRemovedItems(); - for (int i = 0; i < indexedItems.size(); ++i) { - if (QGraphicsItem *item = indexedItems.at(i)) { - item->d_ptr->index = -1; - unindexedItems << item; - } - } - indexedItems.clear(); - freeItemIndexes.clear(); - regenerateIndex = true; - startIndexTimer(); -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) -{ - if (!item->d_ptr->children.isEmpty()) { - QList childList = item->d_ptr->children; - qSort(childList.begin(), childList.end(), qt_closestLeaf); - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) - climbTree(childList.at(i), stackingOrder); - } - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (item->flags() & QGraphicsItem::ItemStacksBehindParent) - climbTree(childList.at(i), stackingOrder); - } - } else { - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - } -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() -{ - Q_Q(QGraphicsSceneBspTreeIndex); - _q_updateIndex(); - - if (!sortCacheEnabled || !updatingSortCache) - return; - - updatingSortCache = false; - int stackingOrder = 0; - - QList topLevels; - - for (int i = 0; i < q->items().count(); ++i) { - QGraphicsItem *item = q->items().at(i); - if (item && item->parentItem() == 0) - topLevels << item; - } - - qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); - for (int i = 0; i < topLevels.size(); ++i) - climbTree(topLevels.at(i), &stackingOrder); -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() -{ - Q_Q(QGraphicsSceneBspTreeIndex); - if (!sortCacheEnabled || updatingSortCache) - return; - - updatingSortCache = true; - QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); -} - -/*! - Returns true if \a item1 is on top of \a item2. - - \internal -*/ -bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Siblings? Just check their z-values. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - if (d1->parent == d2->parent) - return qt_closestLeaf(item1, item2); - - // Find common ancestor, and each item's ancestor closest to the common - // ancestor. - int item1Depth = d1->depth; - int item2Depth = d2->depth; - const QGraphicsItem *p = item1; - const QGraphicsItem *t1 = item1; - while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { - if (p == item2) { - // item2 is one of item1's ancestors; item1 is on top - return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t1 = p; - --item1Depth; - } - p = item2; - const QGraphicsItem *t2 = item2; - while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { - if (p == item1) { - // item1 is one of item2's ancestors; item1 is not on top - return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t2 = p; - --item2Depth; - } - - // item1Ancestor is now at the same level as item2Ancestor, but not the same. - const QGraphicsItem *a1 = t1; - const QGraphicsItem *a2 = t2; - while (a1) { - const QGraphicsItem *p1 = a1; - const QGraphicsItem *p2 = a2; - a1 = a1->parentItem(); - a2 = a2->parentItem(); - if (a1 && a1 == a2) - return qt_closestLeaf(p1, p2); - } - - // No common ancestor? Then just compare the items' toplevels directly. - return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); -} - -/*! - Returns true if \a item2 is on top of \a item1. - - \internal -*/ -bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return closestItemFirst_withoutCache(item2, item1); -} - -/*! - Sort a list of \a itemList in a specific \a order and use the cache if requested. - - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, - bool sortCacheEnabled) -{ - if (sortCacheEnabled) { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); - } - } else { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); - } - } -} - -/*! - Constructs a BSP scene index for the given \a scene. -*/ -QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) - : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) -{ - -} - -/*! - \reimp - Return the rect indexed by the BSP index. -*/ -QRectF QGraphicsSceneBspTreeIndex::indexedRect() const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->_q_updateIndex(); - return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; -} - -/*! - \reimp - Clear the all the BSP index. -*/ -void QGraphicsSceneBspTreeIndex::clear() -{ - Q_D(QGraphicsSceneBspTreeIndex); - d->bsp.clear(); - d->lastItemCount = 0; - d->freeItemIndexes.clear(); - d->indexedItems.clear(); - d->unindexedItems.clear(); -} - -/*! - Add the \a item into the BSP index. -*/ -void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Prevent reusing a recently deleted pointer: purge all removed items - // from our lists. - d->purgeRemovedItems(); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - // Update the scene's sort cache settings. - item->d_ptr->globalStackingOrder = -1; - d->invalidateSortCache(); - - // Indexing requires sceneBoundingRect(), but because \a item might - // not be completely constructed at this point, we need to store it in - // a temporary list and schedule an indexing for later. - d->unindexedItems << item; - item->d_func()->index = -1; - d->startIndexTimer(0); -} - -/*! - This really add the item in the BSP. - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) -{ - if (item->d_func()->index != -1) { - bsp.insertItem(item, item->sceneBoundingRect()); - foreach (QGraphicsItem *child, item->children()) - child->addToIndex(); - } else { - // The BSP tree is regenerated if the number of items grows to a - // certain threshold, or if the bounding rect of the graph doubles in - // size. - startIndexTimer(); - } -} - -/*! - Remove the \a item from the BSP index. -*/ -void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromIndex(item); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - // Remove from our item lists. - int index = item->d_func()->index; - if (index != -1) { - d->freeItemIndexes << index; - d->indexedItems[index] = 0; - } else { - d->unindexedItems.removeAll(item); - } -} - -/*! - \reimp - Delete the \a item from the BSP index (without accessing its boundingRect). -*/ -void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - int index = item->d_func()->index; - if (index != -1) { - // Important: The index is useless until purgeRemovedItems() is - // called. - d->indexedItems[index] = (QGraphicsItem *)0; - if (!d->purgePending) { - d->purgePending = true; - scene()->update(); - } - d->removedItems << item; - } else { - // Recently added items are purged immediately. unindexedItems() never - // contains stale items. - d->unindexedItems.removeAll(item); - scene()->update(); - } -} - -/*! - Really remove the item from the BSP - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) -{ - if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - // ### remove from child index only if applicable - return; - } - int index = item->d_func()->index; - if (index != -1) { - bsp.removeItem(item, item->sceneBoundingRect()); - freeItemIndexes << index; - indexedItems[index] = 0; - item->d_func()->index = -1; - unindexedItems << item; - - //prepareGeometryChange will call prepareBoundingRectChange - foreach (QGraphicsItem *child, item->children()) - child->prepareGeometryChange(); - } - startIndexTimer(); -} - -/*! - \reimp - Update the BSP when the \a item 's bounding rect has changed. -*/ -void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromIndex(const_cast(item)); -} - -/*! - Returns an estimation visible items that are either inside or - intersect with the specified \a rect and return a list sorted using \a order. - - \a deviceTransform is the transformation apply to the view. - -*/ -QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->purgeRemovedItems(); - const_cast(d)->_q_updateSortCache(); - - QList rectItems = d->bsp.items(rect); - // Fill in with any unindexed items - for (int i = 0; i < d->unindexedItems.size(); ++i) { - if (QGraphicsItem *item = d->unindexedItems.at(i)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { - QRectF boundingRect = item->sceneBoundingRect(); - if (QRectF_intersects(boundingRect, rect)) { - item->d_ptr->itemDiscovered = 1; - rectItems << item; - } - } - } - } - - // Reset the discovered state of all discovered items - for (int i = 0; i < rectItems.size(); ++i) - rectItems.at(i)->d_func()->itemDiscovered = 0; - - d->sortItems(&rectItems, order, d->sortCacheEnabled); - - return rectItems; -} - - -/*! - \fn QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; - - Return all items in the BSP index and sort them using \a order. -*/ -QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->purgeRemovedItems(); - QList itemList; - // If freeItemIndexes is empty, we know there are no holes in indexedItems and - // unindexedItems. - if (d->freeItemIndexes.isEmpty()) { - if (d->unindexedItems.isEmpty()) { - itemList = d->indexedItems; - } else { - itemList = d->indexedItems + d->unindexedItems; - } - } else { - // Rebuild the list of items to avoid holes. ### We could also just - // compress the item lists at this point. - foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { - if (item) - itemList << item; - } - } - if (order != -1) { - //We sort descending order - d->sortItems(&itemList, order, d->sortCacheEnabled); - } - return itemList; -} - -/*! - \property QGraphicsSceneBspTreeIndex::bspTreeDepth - \brief the depth of the BSP index tree - \since 4.6 - - This value determines the depth of BSP tree. The depth - directly affects performance and memory usage; the latter - growing exponentially with the depth of the tree. With an optimal tree - depth, the index can instantly determine the locality of items, even - for scenes with thousands or millions of items. This also greatly improves - rendering performance. - - By default, the value is 0, in which case Qt will guess a reasonable - default depth based on the size, location and number of items in the - scene. If these parameters change frequently, however, you may experience - slowdowns as the index retunes the depth internally. You can avoid - potential slowdowns by fixating the tree depth through setting this - property. - - The depth of the tree and the size of the scene rectangle decide the - granularity of the scene's partitioning. The size of each scene segment is - determined by the following algorithm: - - The BSP tree has an optimal size when each segment contains between 0 and - 10 items. - -*/ -int QGraphicsSceneBspTreeIndex::bspTreeDepth() -{ - Q_D(const QGraphicsSceneBspTreeIndex); - return d->bspTreeDepth; -} - -void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) -{ - Q_D(QGraphicsSceneBspTreeIndex); - d->bspTreeDepth = depth; - d->resetIndex(); -} - -/*! - \reimp - - This method react to the \a rect change of the scene and - reset the BSP tree index. -*/ -void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) -{ - Q_D(QGraphicsSceneBspTreeIndex); - d->sceneRect = rect; - d->resetIndex(); -} - -/*! - \reimp - - This method react to the \a change of the \a item and use the \a value to - update the BSP tree if necessary. - -*/ -void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) -{ - Q_D(QGraphicsSceneBspTreeIndex); - switch (change) { - case QGraphicsItem::ItemZValueChange: - case QGraphicsItem::ItemParentChange: { - d->invalidateSortCache(); - break; - } - default: - break; - } - return QGraphicsSceneIndex::itemChanged(item, change, value); -} -/*! - \reimp - - Used to catch the timer event. - - \internal -*/ -bool QGraphicsSceneBspTreeIndex::event(QEvent *event) -{ - Q_D(QGraphicsSceneBspTreeIndex); - switch (event->type()) { - case QEvent::Timer: - if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { - if (d->restartIndexTimer) { - d->restartIndexTimer = false; - } else { - // this call will kill the timer - d->_q_updateIndex(); - } - } - // Fallthrough intended - support timers in subclasses. - default: - return QObject::event(event); - } - return true; -} - -QT_END_NAMESPACE - -#include "moc_qgraphicsscenebsptreeindex_p.cpp" - -#endif // QT_NO_GRAPHICSVIEW - diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 40b8f0b..6bafbc8 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -39,63 +39,112 @@ ** ****************************************************************************/ -#include - -#ifndef QGRAPHICSBSPTREEINDEX_H -#define QGRAPHICSBSPTREEINDEX_H +#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_H +#define QGRAPHICSSCENEBSPTREEINDEX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicsscenebsptreeindex.h" #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW +#include +#include + QT_BEGIN_NAMESPACE -#include -#include -#include -#include -#include +static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; -#include "qgraphicsscene_bsp_p.h" +class QGraphicsScene; -class QGraphicsSceneBspTreeIndexPrivate; -class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex +class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate { - Q_OBJECT - Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) + Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) public: - QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect() const; - - QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const; - - int bspTreeDepth(); - void setBspTreeDepth(int depth); - -protected: - bool event(QEvent *event); - void clear(); - - void addItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); - void prepareBoundingRectChange(const QGraphicsItem *item); + QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); + + QGraphicsSceneBspTree bsp; + QRectF sceneRect; + int bspTreeDepth; + int indexTimerId; + bool restartIndexTimer; + bool regenerateIndex; + int lastItemCount; + + QList indexedItems; + QList unindexedItems; + QList freeItemIndexes; + + bool purgePending; + QSet removedItems; + void purgeRemovedItems(); + + void _q_updateIndex(); + void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); + void resetIndex(); + + void addToIndex(QGraphicsItem *item); + void removeFromIndex(QGraphicsItem *item); + + void _q_updateSortCache(); + bool sortCacheEnabled; + bool updatingSortCache; + void invalidateSortCache(); + + static void climbTree(QGraphicsItem *item, int *stackingOrder); + static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + + static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; + } + static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; + } + + static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); +}; - void sceneRectChanged(const QRectF &rect); - void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); -private : - Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) - Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) - Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) - Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) +/*! + \internal +*/ +inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Return true if sibling item1 is on top of item2. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; + bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; + if (f1 != f2) return f2; + qreal z1 = d1->z; + qreal z2 = d2->z; + return z1 > z2; +} + +/*! + \internal +*/ +static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + return qt_closestLeaf(item2, item1); +} - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; -}; QT_END_NAMESPACE -#endif // QT_NO_GRAPHICSVIEW +#endif // QGRAPHICSSCENEBSPTREEINDEX_P_H + +#endif -#endif // QGRAPHICSBSPTREEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h deleted file mode 100644 index 30f6e26..0000000 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_P_H -#define QGRAPHICSSCENEBSPTREEINDEX_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include "qgraphicsscenebsptreeindex_p.h" - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include - -QT_BEGIN_NAMESPACE - -static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; - -class QGraphicsScene; - -class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) -public: - QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); - - QGraphicsSceneBspTree bsp; - QRectF sceneRect; - int bspTreeDepth; - int indexTimerId; - bool restartIndexTimer; - bool regenerateIndex; - int lastItemCount; - - QList indexedItems; - QList unindexedItems; - QList freeItemIndexes; - - bool purgePending; - QSet removedItems; - void purgeRemovedItems(); - - void _q_updateIndex(); - void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); - void resetIndex(); - - void addToIndex(QGraphicsItem *item); - void removeFromIndex(QGraphicsItem *item); - - void _q_updateSortCache(); - bool sortCacheEnabled; - bool updatingSortCache; - void invalidateSortCache(); - - static void climbTree(QGraphicsItem *item, int *stackingOrder); - static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - - static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; - } - static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; - } - - static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); -}; - - -/*! - \internal -*/ -inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Return true if sibling item1 is on top of item2. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; - bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; - if (f1 != f2) return f2; - qreal z1 = d1->z; - qreal z2 = d2->z; - return z1 > z2; -} - -/*! - \internal -*/ -static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return qt_closestLeaf(item2, item1); -} - - -QT_END_NAMESPACE - -#endif // QGRAPHICSSCENEBSPTREEINDEX_P_P_H - -#endif - diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 05ec28b..966d8fe 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -46,6 +46,7 @@ \ingroup multimedia \ingroup graphicsview-api \mainclass + \internal The QGraphicsSceneIndex class provides a base class to implement a custom indexing algorithm for discovering items in QGraphicsScene. You @@ -57,7 +58,6 @@ #include "qgraphicssceneindex.h" #include "qgraphicssceneindex_p.h" -#include "qgraphicsscenebsptreeindex_p_p.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index 084a623..c0e415c 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -42,6 +42,17 @@ #ifndef QGRAPHICSSCENEINDEX_H #define QGRAPHICSSCENEINDEX_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + #include #include #include @@ -61,7 +72,7 @@ class QRectF; class QPointF; template class QList; -class Q_GUI_EXPORT QGraphicsSceneIndex: public QObject +class Q_AUTOTEST_EXPORT QGraphicsSceneIndex: public QObject { Q_OBJECT diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp index 1c898bc..5504493 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -1,4 +1,4 @@ -#include "qgraphicsscenelinearindex_p.h" +#include "qgraphicsscenelinearindex.h" /*! \class QGraphicsSceneLinearIndex @@ -8,6 +8,7 @@ \ingroup multimedia \ingroup graphicsview-api \mainclass + \internal QGraphicsSceneLinearIndex index is default linear implementation to discover items. It basically store all items in a list and return them to the scene. diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.h b/src/gui/graphicsview/qgraphicsscenelinearindex.h new file mode 100644 index 0000000..b793d98 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENELINEARINDEX_H +#define QGRAPHICSSCENELINEARINDEX_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include + +class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + +public: + QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) + { + } + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { + Q_UNUSED(order); + return m_items; + } + + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_UNUSED(rect); + Q_UNUSED(order); + Q_UNUSED(deviceTransform); + return m_items; + } + + virtual QRectF indexedRect() const { + return m_sceneRect; + } + +protected : + void sceneRectChanged(const QRectF &rect) { + m_sceneRect = rect; + } + + virtual void clear() { + m_items.clear(); + } + + virtual void addItem(QGraphicsItem *item) { + m_items << item; + } + + virtual void removeItem(QGraphicsItem *item) { + m_items.removeAll(item); + } + +private: + QRectF m_sceneRect; + QList m_items; +}; + +#endif // QT_NO_GRAPHICSVIEW + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGRAPHICSSCENELINEARINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h deleted file mode 100644 index d21475c..0000000 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENELINEARINDEX_P_H -#define QGRAPHICSSCENELINEARINDEX_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex -{ - Q_OBJECT - -public: - QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) - { - } - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - Q_UNUSED(order); - return m_items; - } - - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - Q_UNUSED(rect); - Q_UNUSED(order); - Q_UNUSED(deviceTransform); - return m_items; - } - - virtual QRectF indexedRect() const { - return m_sceneRect; - } - -protected : - void sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - } - - virtual void clear() { - m_items.clear(); - } - - virtual void addItem(QGraphicsItem *item) { - m_items << item; - } - - virtual void removeItem(QGraphicsItem *item) { - m_items.removeAll(item); - } - -private: - QRectF m_sceneRect; - QList m_items; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_GRAPHICSVIEW - -#endif // QGRAPHICSSCENELINEARINDEX_P_H -- cgit v0.12 From 5d682567d1acb79b2fa55ae8f005c5dcdc9aacb7 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 17 Jun 2009 14:27:46 +0200 Subject: API / code review for QGraphicsSceneIndex (internal API). A few minor modifications only, marked some things as ### obsolete, removed the public get/set for the index (it's internal anyway). --- src/gui/graphicsview/qgraphicsitem.h | 48 ++++++------ src/gui/graphicsview/qgraphicsscene.cpp | 90 ++++------------------ src/gui/graphicsview/qgraphicsscene.h | 11 +-- src/gui/graphicsview/qgraphicsscene_p.h | 40 ---------- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 6 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 40 ++++++++++ 6 files changed, 86 insertions(+), 149 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index ec16d26..12dcad2 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -141,7 +141,7 @@ public: QGraphicsItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -208,8 +208,8 @@ public: Qt::MouseButtons acceptedMouseButtons() const; void setAcceptedMouseButtons(Qt::MouseButtons buttons); - bool acceptsHoverEvents() const; // obsolete - void setAcceptsHoverEvents(bool enabled); // obsolete + bool acceptsHoverEvents() const; // ### obsolete + void setAcceptsHoverEvents(bool enabled); // ### obsolete bool acceptHoverEvents() const; void setAcceptHoverEvents(bool enabled); @@ -534,7 +534,7 @@ class Q_GUI_EXPORT QAbstractGraphicsShapeItem : public QGraphicsItem public: QAbstractGraphicsShapeItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -564,13 +564,13 @@ class Q_GUI_EXPORT QGraphicsPathItem : public QAbstractGraphicsShapeItem public: QGraphicsPathItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsPathItem(const QPainterPath &path, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -607,19 +607,19 @@ class Q_GUI_EXPORT QGraphicsRectItem : public QAbstractGraphicsShapeItem public: QGraphicsRectItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -660,19 +660,19 @@ class Q_GUI_EXPORT QGraphicsEllipseItem : public QAbstractGraphicsShapeItem public: QGraphicsEllipseItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -719,14 +719,14 @@ class Q_GUI_EXPORT QGraphicsPolygonItem : public QAbstractGraphicsShapeItem public: QGraphicsPolygonItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsPolygonItem(const QPolygonF &polygon, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -766,19 +766,19 @@ class Q_GUI_EXPORT QGraphicsLineItem : public QGraphicsItem public: QGraphicsLineItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -826,13 +826,13 @@ public: QGraphicsPixmapItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -888,13 +888,13 @@ class Q_GUI_EXPORT QGraphicsTextItem : public QGraphicsObject public: QGraphicsTextItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsTextItem(const QString &text, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -989,13 +989,13 @@ class Q_GUI_EXPORT QGraphicsSimpleTextItem : public QAbstractGraphicsShapeItem public: QGraphicsSimpleTextItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -1035,7 +1035,7 @@ class Q_GUI_EXPORT QGraphicsItemGroup : public QGraphicsItem public: QGraphicsItemGroup(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a33cb3e..dacfc87 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -201,8 +201,6 @@ however, is done in constant time. This approach is ideal for dynamic scenes, where many items are added, moved or removed continuously. - \omitvalue CustomIndex - \sa setItemIndexMethod(), bspTreeDepth */ @@ -1529,85 +1527,19 @@ QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const Q_D(const QGraphicsScene); return d->indexMethod; } - -// Possibilities -// NoIndex -> CustomIndex : warning -// BspTreeIndex -> CustomIndex : warning -// CustomIndex -> CustomIndex : warning -// NoIndex -> BspTreeIndex : create an empty BSP if necessary -// BspTreeIndex -> BspTreeIndex : nothing -// CustomIndex -> BspTreeIndex : create BSP and transfer items -// NoIndex -> NoIndex : nothing -// BspTreeIndex -> NoIndex : nothing -// CustomIndex -> NoIndex : create BSP tree but do not populate void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) { Q_D(QGraphicsScene); - if (method == CustomIndex) { - qWarning("QGraphicsScene: Invalid index type %d", CustomIndex); + if (d->indexMethod == method) return; - } - if (d->indexMethod == method) { - return; - } - if (d->indexMethod == NoIndex && method == BspTreeIndex) { - QGraphicsSceneBspTreeIndex *tree = qobject_cast(d->index); - if (!tree) { - delete d->index; - d->index = new QGraphicsSceneBspTreeIndex(this); - } - } + d->indexMethod = method; - if (d->indexMethod == CustomIndex && method == BspTreeIndex) { - //We re-add in the new index all items from the old index - QGraphicsSceneIndex *oldIndex = d->index; + delete d->index; + if (method == BspTreeIndex) d->index = new QGraphicsSceneBspTreeIndex(this); - for (int i = 0 ; i < oldIndex->items().size() ; ++ i) - d->index->addItem(oldIndex->items().at(i)); - } - - if (d->indexMethod == CustomIndex && method == NoIndex) { + else d->index = new QGraphicsSceneLinearIndex(this); - } - - d->indexMethod = method; -} - -/*! - \internal - - \brief the item indexing method. - This method allow to apply an indexing algorithm \a index to the scene, to speed up - item discovery functions like items() and itemAt(). - - \sa sceneIndex(), QGraphicsSceneIndex -*/ -void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) -{ - Q_D(QGraphicsScene); - if (!index) { - qWarning("QGraphicsScene::setSceneIndex: Attempt to insert a null indexer"); - } else { - if (d->indexMethod == BspTreeIndex) { - delete d->index; - } - d->indexMethod = CustomIndex; - d->index = index; - } -} - -/*! - \internal - - This method return the current indexing algorithm of the scene. - - \sa setSceneIndex(), QGraphicsSceneIndex -*/ -QGraphicsSceneIndex* QGraphicsScene::sceneIndex() const -{ - Q_D(const QGraphicsScene); - return d->index; } /*! @@ -1814,7 +1746,8 @@ QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemS \sa itemAt() */ -QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(pos, mode, order, deviceTransform); @@ -1833,7 +1766,8 @@ QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelecti \sa itemAt() */ -QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(rect, mode, order, deviceTransform); @@ -1852,7 +1786,8 @@ QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti \sa itemAt() */ -QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(polygon, mode, order, deviceTransform); @@ -1871,7 +1806,8 @@ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS \sa itemAt() */ -QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(path, mode, order, deviceTransform); diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 36374c8..b922be5 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -114,7 +114,6 @@ class Q_GUI_EXPORT QGraphicsScene : public QObject public: enum ItemIndexMethod { BspTreeIndex, - CustomIndex, NoIndex = -1 }; @@ -144,8 +143,6 @@ public: ItemIndexMethod itemIndexMethod() const; void setItemIndexMethod(ItemIndexMethod method); - void setSceneIndex(QGraphicsSceneIndex *index); - QGraphicsSceneIndex* sceneIndex() const; bool isSortCacheEnabled() const; void setSortCacheEnabled(bool enabled); @@ -162,10 +159,10 @@ public: QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - QList items(const QPointF &pos) const; - QList items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; - QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; - QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; + QList items(const QPointF &pos) const; // ### obsolete + QList items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete + QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete + QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete QList collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QGraphicsItem *itemAt(const QPointF &pos) const; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 563e016..8e05c00 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -229,46 +229,6 @@ public: QStyleOptionGraphicsItem styleOptionTmp; }; -static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) -{ - qreal xp = s.left(); - qreal yp = s.top(); - qreal w = s.width(); - qreal h = s.height(); - qreal l1 = xp; - qreal r1 = xp; - if (w < 0) - l1 += w; - else - r1 += w; - - qreal l2 = r.left(); - qreal r2 = r.left(); - if (w < 0) - l2 += r.width(); - else - r2 += r.width(); - - if (l1 >= r2 || l2 >= r1) - return false; - - qreal t1 = yp; - qreal b1 = yp; - if (h < 0) - t1 += h; - else - b1 += h; - - qreal t2 = r.top(); - qreal b2 = r.top(); - if (r.height() < 0) - t2 += r.height(); - else - b2 += r.height(); - - return !(t1 >= b2 || t2 >= b1); -} - // QRectF::intersects() returns false always if either the source or target // rectangle's width or height are 0. This works around that problem. static inline void _q_adjustRect(QRectF *rect) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 76fd218..969d3c5 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -589,12 +589,16 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * \a deviceTransform is the transformation apply to the view. */ -QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, + const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneBspTreeIndex); const_cast(d)->purgeRemovedItems(); const_cast(d)->_q_updateSortCache(); + // ### Handle items that ignore transformations + Q_UNUSED(deviceTransform); + QList rectItems = d->bsp.items(rect); // Fill in with any unindexed items for (int i = 0; i < d->unindexedItems.size(); ++i) { diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 6bafbc8..b6f782d 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -142,6 +142,46 @@ static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphics } +static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) +{ + qreal xp = s.left(); + qreal yp = s.top(); + qreal w = s.width(); + qreal h = s.height(); + qreal l1 = xp; + qreal r1 = xp; + if (w < 0) + l1 += w; + else + r1 += w; + + qreal l2 = r.left(); + qreal r2 = r.left(); + if (w < 0) + l2 += r.width(); + else + r2 += r.width(); + + if (l1 >= r2 || l2 >= r1) + return false; + + qreal t1 = yp; + qreal b1 = yp; + if (h < 0) + t1 += h; + else + b1 += h; + + qreal t2 = r.top(); + qreal b2 = r.top(); + if (r.height() < 0) + t2 += r.height(); + else + b2 += r.height(); + + return !(t1 >= b2 || t2 >= b1); +} + QT_END_NAMESPACE #endif // QGRAPHICSSCENEBSPTREEINDEX_P_H -- cgit v0.12 From 625dadcc9b88dccebf607b84089ab960740b94f2 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 17 Jun 2009 14:36:55 +0200 Subject: Don't lose all the items when we switch item index method. Readd the items to the new index. Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsscene.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index dacfc87..36af30d 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1535,11 +1535,14 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->indexMethod = method; + QList oldItems = d->index->items(); delete d->index; if (method == BspTreeIndex) d->index = new QGraphicsSceneBspTreeIndex(this); else d->index = new QGraphicsSceneLinearIndex(this); + for (int i = 0; i < oldItems.size(); ++i) + d->index->addItem(oldItems.at(i)); } /*! -- cgit v0.12 From ac8bf5ec1f99d0e00e3ffefe53306c0d511376bf Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 17 Jun 2009 14:46:54 +0200 Subject: More cleanups during code review. Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsscene.cpp | 104 --------------------------- src/gui/graphicsview/qgraphicsscene_p.h | 4 -- src/gui/graphicsview/qgraphicssceneindex.cpp | 54 +++++++++----- src/gui/graphicsview/qgraphicssceneindex.h | 18 +++-- 4 files changed, 47 insertions(+), 133 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 36af30d..380ac20 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1097,110 +1097,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } -void QGraphicsScenePrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, - QList *items, - const QTransform &parentTransform, - const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, - qreal parentOpacity) const -{ - // Calculate opacity. - qreal opacity; - if (item) { - if (!item->d_ptr->visible) - return; - QGraphicsItem *p = item->d_ptr->parent; - bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; - bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); - if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) { - opacity = parentOpacity * item->opacity(); - } else { - opacity = item->d_ptr->opacity; - } - if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) - return; - } else { - opacity = parentOpacity; - } - - // Calculate the full transform for this item. - QTransform transform = parentTransform; - bool keep = false; - if (item) { - item->d_ptr->combineTransformFromParent(&transform, &viewTransform); - - // ### This does not take the clip into account. - QRectF brect = item->boundingRect(); - _q_adjustRect(&brect); - - keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); - - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); - } - } - - bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); - bool dontProcessItem = !item || !keep; - bool dontProcessChildren = item && dontProcessItem && childClip; - - // Find and sort children. - QList &children = item ? item->d_ptr->children : const_cast(this)->topLevelItems; - if (!dontProcessChildren) { - if (item && item->d_ptr->needSortChildren) { - item->d_ptr->needSortChildren = 0; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); - } else if (!item && needSortTopLevelItems) { - const_cast(this)->needSortTopLevelItems = false; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); - } - } - - childClip &= !dontProcessChildren & !children.isEmpty(); - - // Clip. - if (childClip) - rect &= transform.map(item->shape()).controlPointRect(); - - // Process children behind - int i = 0; - if (!dontProcessChildren) { - for (i = 0; i < children.size(); ++i) { - QGraphicsItem *child = children.at(i); - if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) - break; - recursive_items_helper(child, rect, items, transform, viewTransform, - mode, order, opacity); - } - } - - // Process item - if (!dontProcessItem) - items->append(item); - - // Process children in front - if (!dontProcessChildren) { - for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), rect, items, transform, viewTransform, - mode, order, opacity); - } - - if (!item && order == Qt::AscendingOrder) { - int n = items->size(); - for (int i = 0; i < n / 2; ++i) { - QGraphicsItem *tmp = (*items)[n - i - 1]; - (*items)[n - i - 1] = (*items)[i]; - (*items)[i] = tmp; - } - } -} - /*! \internal diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 8e05c00..538ff3f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -188,10 +188,6 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList *items, - const QTransform &parentTransform, const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; - void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 966d8fe..4ca1c02 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -119,9 +119,8 @@ public: else keep = rect.intersects(transform.mapRect(brect)); - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(path), mode); - } return keep; } QPainterPath path; @@ -290,24 +289,27 @@ QRectF QGraphicsSceneIndex::indexedRect() const } /*! - \fn QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QPointF &pos, + Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform + &deviceTransform) const - Returns all visible items that, depending on \a mode, are at the specified \a pos - and return a list sorted using \a order. + Returns all visible items that, depending on \a mode, are at the specified + \a pos and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose exact shape intersects with \a pos are returned. \a deviceTransform is the transformation apply to the view. - This method use the estimation of the index (estimateItems) and refine - the list to get an exact result. If you want to implement your own - refinement algorithm you can reimplement this method. + This method use the estimation of the index (estimateItems) and refine the + list to get an exact result. If you want to implement your own refinement + algorithm you can reimplement this method. \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -319,7 +321,9 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe } /*! - \fn QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QRectF &rect, + Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform + &deviceTransform) const \overload @@ -338,7 +342,8 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -349,7 +354,9 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe } /*! - \fn QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QPolygonF + &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const + QTransform &deviceTransform) const \overload @@ -368,7 +375,8 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -384,7 +392,9 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: } /*! - \fn QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QPainterPath + &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform + &deviceTransform) const \overload @@ -403,7 +413,8 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -421,13 +432,16 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: This method return a list sorted using \a order. \a deviceTransform is the transformation apply to the view. */ -QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, + const QTransform &deviceTransform) const { return estimateItems(QRectF(point, QSize(1,1)), order, deviceTransform); } /*! - \fn virtual QList QGraphicsSceneIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 + \fn virtual QList + QGraphicsSceneIndex::estimateItems(const QRectF &rect, Qt::SortOrder + order, const QTransform &deviceTransform) const = 0 This pure virtual function return an estimation of items in the \a rect. This method return a list sorted using \a order. @@ -436,8 +450,10 @@ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, */ /*! - \fn virtual QList QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; - This pure virtual function all items in the index and sort them using \a order. + \fn virtual QList + QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const + = 0; This pure virtual function all items in the index and sort them using + \a order. */ /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index c0e415c..ddce9d4 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -85,12 +85,18 @@ public: virtual QRectF indexedRect() const; virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; - virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const; - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0; + virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList estimateItems(const QPointF &point, + Qt::SortOrder order, const QTransform &deviceTransform) const; + virtual QList estimateItems(const QRectF &rect, + Qt::SortOrder order, const QTransform &deviceTransform) const = 0; protected: virtual void clear(); -- cgit v0.12 From 0d839e3655d985920aff81882bd444605d97c21c Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:28:29 +0200 Subject: Changes after first round of code reviewing. This change removes all code that handles ItemIgnoresTransformations from QGraphicsView, and changes the APIs of the scene index intersectors. Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsitem.cpp | 33 ++-- src/gui/graphicsview/qgraphicsitem_p.h | 9 + src/gui/graphicsview/qgraphicsscene.cpp | 141 ++++++-------- src/gui/graphicsview/qgraphicsscene.h | 17 +- src/gui/graphicsview/qgraphicsscene_p.h | 4 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 96 +++++---- src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 2 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 216 ++++++++++++++------- src/gui/graphicsview/qgraphicssceneindex.h | 2 +- src/gui/graphicsview/qgraphicssceneindex_p.h | 19 +- src/gui/graphicsview/qgraphicsview.cpp | 161 ++++----------- src/gui/graphicsview/qgraphicsview_p.h | 7 +- 13 files changed, 368 insertions(+), 344 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 593d7be..75683d8 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -857,6 +857,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) if (newParent == parent) return; + if (scene) { + // Deliver the change to the index + scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); + } + if (QGraphicsWidget *w = isWidget ? static_cast(q) : q->parentWidget()) { // Update the child focus chain; when reparenting a widget that has a // focus child, ensure that that focus child clears its focus child @@ -951,11 +956,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) // Deliver post-change notification q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); - if (scene) { - // Deliver the change to the index - scene->d_func()->index->itemChanged(q, QGraphicsItem::ItemParentHasChanged, newParentVariant); - } - if (isObject) emit static_cast(q)->parentChanged(); } @@ -1426,6 +1426,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); if (quint32(d_ptr->flags) == quint32(flags)) return; + if (d_ptr->scene) + d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); // Flags that alter the geometry of the item (or its children). const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations); @@ -3577,17 +3579,20 @@ void QGraphicsItem::setZValue(qreal z) qreal newZ = qreal(newZVariant.toDouble()); if (newZ == d_ptr->z) return; + + if (d_ptr->scene) { + // Z Value has changed, we have to notify the index. + d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant); + } + d_ptr->z = newZ; if (d_ptr->parent) d_ptr->parent->d_ptr->needSortChildren = 1; else if (d_ptr->scene) d_ptr->scene->d_func()->needSortTopLevelItems = 1; - if (d_ptr->scene) { + if (d_ptr->scene) d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true); - //Z Value has changed, we have to notify the index. - d_ptr->scene->d_func()->index->itemChanged(this, ItemZValueChange, z); - } itemChange(ItemZValueHasChanged, newZVariant); @@ -9655,17 +9660,11 @@ QDebug operator<<(QDebug debug, QGraphicsItem *item) return debug; } - QStringList flags; - if (item->isVisible()) flags << QLatin1String("isVisible"); - if (item->isEnabled()) flags << QLatin1String("isEnabled"); - if (item->isSelected()) flags << QLatin1String("isSelected"); - if (item->hasFocus()) flags << QLatin1String("HasFocus"); - debug << "QGraphicsItem(this =" << ((void*)item) << ", parent =" << ((void*)item->parentItem()) << ", pos =" << item->pos() - << ", z =" << item->zValue() << ", flags = {" - << flags.join(QLatin1String("|")) << " })"; + << ", z =" << item->zValue() << ", flags = " + << item->flags() << ")"; return debug; } diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 9c1ee4f..1c95a62 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -158,6 +158,15 @@ public: inline virtual ~QGraphicsItemPrivate() { } + static const QGraphicsItemPrivate *get(const QGraphicsItem *item) + { + return item->d_ptr; + } + static QGraphicsItemPrivate *get(QGraphicsItem *item) + { + return item->d_ptr; + } + void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag, AncestorFlag flag = NoFlag, bool enabled = false, bool root = true); void setIsMemberOfGroup(bool enabled); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 380ac20..55f0f20 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -774,41 +774,8 @@ QList QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre { Q_Q(const QGraphicsScene); QGraphicsView *view = widget ? qobject_cast(widget->parentWidget()) : 0; - QList items; - if (view) - items = view->items(view->viewport()->mapFromGlobal(screenPos)); - else - items = q->items(scenePos); - return items; -} - -/*! - \internal - - Checks if item collides with the path and mode, but also checks that if it - doesn't collide, maybe its frame rect will. -*/ -bool QGraphicsScenePrivate::itemCollidesWithPath(QGraphicsItem *item, - const QPainterPath &path, - Qt::ItemSelectionMode mode) -{ - if (item->collidesWithPath(path, mode)) - return true; - if (item->isWidget()) { - // Check if this is a window, and if its frame rect collides. - QGraphicsWidget *widget = static_cast(item); - if (widget->isWindow()) { - QRectF frameRect = widget->windowFrameRect(); - QPainterPath framePath; - framePath.addRect(frameRect); - bool intersects = path.intersects(frameRect); - if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect) - return intersects || path.contains(frameRect.topLeft()) - || framePath.contains(path.elementAt(0)); - return !intersects && path.contains(frameRect.topLeft()); - } - } - return false; + return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, + view ? view->viewportTransform() : QTransform()); } /*! @@ -820,7 +787,7 @@ void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouse if (event->buttons() & i) { mouseGrabberButtonDownPos.insert(Qt::MouseButton(i), mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(), - event->widget())); + event->widget())); mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos()); mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos()); } @@ -1282,6 +1249,8 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); + /// ### Remove? The growing items bounding rect might be managed + // by the scene. return d->index->indexedRect(); } void QGraphicsScene::setSceneRect(const QRectF &rect) @@ -1332,6 +1301,8 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source, Qt::AspectRatioMode aspectRatioMode) { + // ### Switch to using the recursive rendering algorithm instead. + // Default source rect = scene rect QRectF sourceRect = source; if (sourceRect.isNull()) @@ -1431,14 +1402,16 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->indexMethod = method; - QList oldItems = d->index->items(); + QList oldItems = d->index->items(Qt::AscendingOrder); delete d->index; if (method == BspTreeIndex) d->index = new QGraphicsSceneBspTreeIndex(this); else d->index = new QGraphicsSceneLinearIndex(this); - for (int i = 0; i < oldItems.size(); ++i) + for (int i = oldItems.size() - 1; i >= 0; --i) d->index->addItem(oldItems.at(i)); + + d->index->sceneRectChanged(d->sceneRect); } /*! @@ -1476,7 +1449,7 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) int QGraphicsScene::bspTreeDepth() const { Q_D(const QGraphicsScene); - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); return bspTree ? bspTree->bspTreeDepth() : 0; } void QGraphicsScene::setBspTreeDepth(int depth) @@ -1487,14 +1460,11 @@ void QGraphicsScene::setBspTreeDepth(int depth) return; } - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); if (!bspTree) { qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP"); return; } - if (bspTree->bspTreeDepth() == depth) - return; - bspTree->setBspTreeDepth(depth); } @@ -1502,37 +1472,21 @@ void QGraphicsScene::setBspTreeDepth(int depth) \property QGraphicsScene::sortCacheEnabled \brief whether sort caching is enabled \since 4.5 + \obsolete - When enabled, this property adds a cache that speeds up sorting and - transformations for scenes with deep hierarchies (i.e., items with many - levels of descendents), at the cost of using more memory (approx. 100 more - bytes of memory per item). - - Items that are not part of a deep hierarchy suffer no penalty from this - cache. + Since Qt 4.6, this property has no effect. */ bool QGraphicsScene::isSortCacheEnabled() const { Q_D(const QGraphicsScene); - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); - if (!bspTree) { - qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); - return false; - } - return bspTree->d_func()->sortCacheEnabled; + return d->sortCacheEnabled; } void QGraphicsScene::setSortCacheEnabled(bool enabled) { Q_D(QGraphicsScene); - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); - if (!bspTree) { - qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); + if (d->sortCacheEnabled == enabled) return; - } - if (enabled == bspTree->d_func()->sortCacheEnabled) - return; - if ((bspTree->d_func()->sortCacheEnabled = enabled)) - bspTree->d_func()->invalidateSortCache(); + d->sortCacheEnabled = enabled; } /*! @@ -1544,6 +1498,7 @@ void QGraphicsScene::setSortCacheEnabled(bool enabled) */ QRectF QGraphicsScene::itemsBoundingRect() const { + // Does not take untransformable items into account. QRectF boundingRect; foreach (QGraphicsItem *item, items()) boundingRect |= item->sceneBoundingRect(); @@ -1558,7 +1513,19 @@ QRectF QGraphicsScene::itemsBoundingRect() const QList QGraphicsScene::items() const { Q_D(const QGraphicsScene); - return d->index->items(); + return d->index->items(Qt::AscendingOrder); +} + +/*! + Returns an ordered list of all items on the scene. \a order decides the + sorting. + + \sa addItem(), removeItem() +*/ +QList QGraphicsScene::items(Qt::SortOrder order) const +{ + Q_D(const QGraphicsScene); + return d->index->items(order); } /*! @@ -1732,6 +1699,7 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, return QList(); } + // Does not support ItemIgnoresTransformations. QList tmp; foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::AscendingOrder, QTransform())) { if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode)) @@ -1756,6 +1724,13 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &pos) const return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first(); } +QGraphicsItem *QGraphicsScene::itemAt(const QPointF &pos, const QTransform &deviceTransform) const +{ + QList itemsAtPoint = items(pos, Qt::IntersectsItemShape, + Qt::AscendingOrder, deviceTransform); + return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first(); +} + /*! \fn QGraphicsScene::itemAt(qreal x, qreal y) const \overload @@ -1831,6 +1806,21 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path) */ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode) { + setSelectionArea(path, Qt::IntersectsItemShape, QTransform()); +} + +/*! + \overload + \since 4.3 + + Sets the selection area to \a path using \a mode to determine if items are + included in the selection area. + + \sa clearSelection(), selectionArea() +*/ +void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, + const QTransform &deviceTransform) +{ Q_D(QGraphicsScene); // Note: with boolean path operations, we can improve performance here @@ -1846,7 +1836,7 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectio bool changed = false; // Set all items in path to selected. - foreach (QGraphicsItem *item, items(path, mode)) { + foreach (QGraphicsItem *item, items(path, mode, Qt::AscendingOrder, deviceTransform)) { if (item->flags() & QGraphicsItem::ItemIsSelectable) { if (!item->isSelected()) changed = true; @@ -1904,7 +1894,10 @@ void QGraphicsScene::clear() { Q_D(QGraphicsScene); QList items = d->index->items(); +#if 1 QList toDelete; + // ### As the item list is already in ascending order, + // the items should be deleted in topological order. // Recursive descent delete for (int i = 0; i < items.size(); ++i) { if (QGraphicsItem *item = items.at(i)) { @@ -1912,11 +1905,13 @@ void QGraphicsScene::clear() toDelete << item; } } - //We delete all top level items + // We delete all top level items qDeleteAll(toDelete); +#else + qDeleteAll(items); +#endif d->lastItemCount = 0; d->index->clear(); - d->largestUntransformableItem = QRectF(); d->allItemsIgnoreHoverEvents = true; d->allItemsUseDefaultCursor = true; } @@ -4129,16 +4124,6 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * children = &this->topLevelItems; } else { QRectF sceneRect = viewTransform.inverted().mapRect(QRectF(exposedRegion->boundingRect().adjusted(-1, -1, 1, 1))); - if (!largestUntransformableItem.isEmpty()) { - // ### Nuke this when we move the indexing code into a separate - // class. All the largestUntransformableItem code should then go - // away, and the estimate function should return untransformable - // items as well. - QRectF untr = largestUntransformableItem; - QRectF ltri = viewTransform.inverted().mapRect(untr); - ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); - sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); - } tmp = index->estimateItems(sceneRect, Qt::DescendingOrder, viewTransform); QList tli; diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index b922be5..421adbd 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -153,6 +153,7 @@ public: QRectF itemsBoundingRect() const; QList items() const; + QList items(Qt::SortOrder order) const; // ### Qt 5: unify QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; @@ -165,17 +166,25 @@ public: QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete QList collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; - QGraphicsItem *itemAt(const QPointF &pos) const; + + QGraphicsItem *itemAt(const QPointF &pos) const; // ### obsolete + QGraphicsItem *itemAt(const QPointF &pos, const QTransform &deviceTransform) const; inline QList items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const - { return items(QRectF(x, y, w, h), mode); } - inline QGraphicsItem *itemAt(qreal x, qreal y) const + { return items(QRectF(x, y, w, h), mode); } // ### obsolete + inline QList items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order, + const QTransform &deviceTransform = QTransform()) const + { return items(QRectF(x, y, w, h), mode, order, deviceTransform); } + inline QGraphicsItem *itemAt(qreal x, qreal y) const // ### obsolete { return itemAt(QPointF(x, y)); } + inline QGraphicsItem *itemAt(qreal x, qreal y, const QTransform &deviceTransform) const + { return itemAt(QPointF(x, y), deviceTransform); } QList selectedItems() const; QPainterPath selectionArea() const; void setSelectionArea(const QPainterPath &path); - void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode); + void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode); + void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, const QTransform &deviceTransform); QGraphicsItemGroup *createItemGroup(const QList &items); void destroyItemGroup(QGraphicsItemGroup *group); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 538ff3f..a081e04 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -96,7 +96,6 @@ public: QRectF sceneRect; bool hasSceneRect; QRectF growingItemsBoundingRect; - QRectF largestUntransformableItem; void _q_emitUpdated(); QList updatedRects; @@ -162,7 +161,6 @@ public: QList itemsAtPosition(const QPoint &screenPos, const QPointF &scenePos, QWidget *widget) const; - static bool itemCollidesWithPath(QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode); void storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event); QList views; @@ -188,6 +186,8 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; + bool sortCacheEnabled; // for compatibility + void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 969d3c5..40cafa6 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -170,11 +170,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() unindexedItems = indexedItems; lastItemCount = indexedItems.size(); q->scene()->update(); - - // Take this opportunity to reset our largest-item counter for - // untransformable items. When the items are inserted into the BSP - // tree, we'll get an accurate calculation. - scenePrivate->largestUntransformableItem = QRectF(); } // Insert all unindexed items into the tree. @@ -185,19 +180,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() continue; bsp.insertItem(item, rect); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); - } } } unindexedItems.clear(); @@ -467,17 +449,23 @@ void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) // Indexing requires sceneBoundingRect(), but because \a item might // not be completely constructed at this point, we need to store it in // a temporary list and schedule an indexing for later. - d->unindexedItems << item; - item->d_func()->index = -1; - d->startIndexTimer(0); + item->d_ptr->index = -1; + if (item->d_ptr->itemIsUntransformable()) { + d->untransformableItems << item; + } else { + d->unindexedItems << item; + d->startIndexTimer(0); + } } /*! This really add the item in the BSP. \internal */ -void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::addToBspTree(QGraphicsItem *item) { + if (item->d_ptr->itemIsUntransformable()) + return; if (item->d_func()->index != -1) { bsp.insertItem(item, item->sceneBoundingRect()); foreach (QGraphicsItem *child, item->children()) @@ -496,10 +484,11 @@ void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); + // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - d->removeFromIndex(item); + d->removeFromBspTree(item); // Invalidate any sort caching; arrival of a new item means we need to // resort. @@ -511,7 +500,10 @@ void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) d->freeItemIndexes << index; d->indexedItems[index] = 0; } else { - d->unindexedItems.removeAll(item); + if (item->d_ptr->itemIsUntransformable()) + d->untransformableItems.removeOne(item); + else + d->unindexedItems.removeOne(item); } } @@ -539,7 +531,10 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) } else { // Recently added items are purged immediately. unindexedItems() never // contains stale items. - d->unindexedItems.removeAll(item); + if (item->d_ptr->itemIsUntransformable()) + d->untransformableItems.removeOne(item); + else + d->unindexedItems.removeOne(item); scene()->update(); } } @@ -548,8 +543,11 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) Really remove the item from the BSP \internal */ -void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) { + if (item->d_ptr->itemIsUntransformable()) + return; + if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { // ### remove from child index only if applicable return; @@ -579,7 +577,7 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - d->removeFromIndex(const_cast(item)); + d->removeFromBspTree(const_cast(item)); } /*! @@ -633,7 +631,8 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co Q_D(const QGraphicsSceneBspTreeIndex); const_cast(d)->purgeRemovedItems(); QList itemList; - // If freeItemIndexes is empty, we know there are no holes in indexedItems and + + // If freeItemIndexes is empty, we know there are no holes in indexedItems and // unindexedItems. if (d->freeItemIndexes.isEmpty()) { if (d->unindexedItems.isEmpty()) { @@ -649,6 +648,7 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co itemList << item; } } + itemList += d->untransformableItems; if (order != -1) { //We sort descending order d->sortItems(&itemList, order, d->sortCacheEnabled); @@ -692,6 +692,8 @@ int QGraphicsSceneBspTreeIndex::bspTreeDepth() void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) { Q_D(QGraphicsSceneBspTreeIndex); + if (d->bspTreeDepth == depth) + return; d->bspTreeDepth = depth; d->resetIndex(); } @@ -716,19 +718,41 @@ void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) update the BSP tree if necessary. */ -void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { Q_D(QGraphicsSceneBspTreeIndex); switch (change) { - case QGraphicsItem::ItemZValueChange: - case QGraphicsItem::ItemParentChange: { - d->invalidateSortCache(); - break; + case QGraphicsItem::ItemFlagsChange: { + // Handle ItemIgnoresTransformations + bool ignoredTransform = item->flags() & QGraphicsItem::ItemIgnoresTransformations; + bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations; + if (ignoredTransform != willIgnoreTransform) { + QGraphicsItem *thatItem = const_cast(item); + removeItem(thatItem); + addItem(thatItem); } - default: - break; + break; + } + case QGraphicsItem::ItemZValueChange: + d->invalidateSortCache(); + break; + case QGraphicsItem::ItemParentChange: { + d->invalidateSortCache(); + // Handle ItemIgnoresTransformations + QGraphicsItem *newParent = qVariantValue(value); + bool ignoredTransform = item->d_ptr->itemIsUntransformable(); + bool willIgnoreTransform = (item->flags() & QGraphicsItem::ItemIgnoresTransformations) || (newParent && newParent->d_ptr->itemIsUntransformable()); + if (ignoredTransform != willIgnoreTransform) { + QGraphicsItem *thatItem = const_cast(item); + removeItem(thatItem); + addItem(thatItem); + } + break; + } + default: + break; } - return QGraphicsSceneIndex::itemChanged(item, change, value); + return QGraphicsSceneIndex::itemChange(item, change, value); } /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h index 0444a30..504ea8b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h @@ -98,7 +98,7 @@ protected: void prepareBoundingRectChange(const QGraphicsItem *item); void sceneRectChanged(const QRectF &rect); - void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index b6f782d..ed12fac 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -82,6 +82,7 @@ public: QList indexedItems; QList unindexedItems; + QList untransformableItems; QList freeItemIndexes; bool purgePending; @@ -92,8 +93,8 @@ public: void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); void resetIndex(); - void addToIndex(QGraphicsItem *item); - void removeFromIndex(QGraphicsItem *item); + void addToBspTree(QGraphicsItem *item); + void removeFromBspTree(QGraphicsItem *item); void _q_updateSortCache(); bool sortCacheEnabled; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 4ca1c02..eb3abc1 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -61,6 +61,7 @@ #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" +#include "qgraphicswidget.h" #ifndef QT_NO_GRAPHICSVIEW @@ -69,61 +70,118 @@ QT_BEGIN_NAMESPACE class QGraphicsSceneIndexRectIntersector : public QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexRectIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} - bool intersect(const QRectF &brect) const + bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const { + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + // ### Add test for this (without making things slower?) + Q_UNUSED(exposeRect); + bool keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); - - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + // Untransformable items; map the scene rect to item coordinates. + QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect); + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = itemRect.contains(brect) && itemRect != brect; + else + keep = itemRect.intersects(brect); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath itemPath; + itemPath.addRect(itemRect); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); + } + } else { + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = sceneRect.contains(transform.mapRect(brect)) && sceneRect != brect; + else + keep = sceneRect.intersects(transform.mapRect(brect)); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(sceneRect); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } } return keep; } + + QRectF sceneRect; }; class QGraphicsSceneIndexPointIntersector : public QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexPointIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} - bool intersect(const QRectF &brect) const + bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const { + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + // ### Add test for this (without making things slower?) + Q_UNUSED(exposeRect); + bool keep = false; - if (rect.intersects(transform.mapRect(brect))) - if (item->contains(transform.inverted().map(pos))) - keep = true; - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + // Untransformable items; map the scene point to item coordinates. + QPointF itemPoint = (deviceTransform * transform.inverted()).map(scenePoint); + keep = brect.contains(itemPoint); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath pointPath; + pointPath.addRect(QRectF(itemPoint, QSizeF(1, 1))); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); + } + } else { + QRectF sceneBrect = transform.mapRect(brect); + keep = sceneBrect.contains(scenePoint); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath pointPath; + pointPath.addRect(QRectF(transform.inverted().map(scenePoint), QSizeF(1, 1))); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); + } } return keep; } - QPointF pos; + + QPointF scenePoint; }; class QGraphicsSceneIndexPathIntersector : public QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexPathIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} - bool intersect(const QRectF &brect) const + bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const { - bool keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + // ### Add test for this (without making things slower?) + Q_UNUSED(exposeRect); - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) - keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(path), mode); + bool keep = true; + if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + // Untransformable items; map the scene rect to item coordinates. + QPainterPath itemPath = (deviceTransform * transform.inverted()).map(scenePath); + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = itemPath.contains(brect); + else + keep = itemPath.intersects(brect); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); + } else { + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = scenePath.contains(transform.mapRect(brect)); + else + keep = scenePath.intersects(transform.mapRect(brect)); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath itemPath = transform.inverted().map(scenePath); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); + } + } return keep; } - QPainterPath path; + + QPainterPath scenePath; }; /*! @@ -131,9 +189,9 @@ public: */ QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene) { - pointIntersector = new QGraphicsSceneIndexPointIntersector(scene); - rectIntersector = new QGraphicsSceneIndexRectIntersector(scene); - pathIntersector = new QGraphicsSceneIndexPathIntersector(scene); + pointIntersector = new QGraphicsSceneIndexPointIntersector; + rectIntersector = new QGraphicsSceneIndexRectIntersector; + pathIntersector = new QGraphicsSceneIndexPathIntersector; } /*! @@ -148,19 +206,50 @@ QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate() /*! \internal + + Checks if item collides with the path and mode, but also checks that if it + doesn't collide, maybe its frame rect will. +*/ +bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item, + const QPainterPath &path, + Qt::ItemSelectionMode mode) +{ + if (item->collidesWithPath(path, mode)) + return true; + if (item->isWidget()) { + // Check if this is a window, and if its frame rect collides. + const QGraphicsWidget *widget = static_cast(item); + if (widget->isWindow()) { + QRectF frameRect = widget->windowFrameRect(); + QPainterPath framePath; + framePath.addRect(frameRect); + bool intersects = path.intersects(frameRect); + if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect) + return intersects || path.contains(frameRect.topLeft()) + || framePath.contains(path.elementAt(0)); + return !intersects && path.contains(frameRect.topLeft()); + } + } + return false; +} + +/*! + \internal */ -void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, - QList *items, - const QTransform &parentTransform, - const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, - qreal parentOpacity) const +void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, + QGraphicsSceneIndexIntersector *intersector, + QList *items, + const QTransform &parentTransform, + const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, + qreal parentOpacity) const { // Calculate opacity. qreal opacity; if (item) { if (!item->d_ptr->visible) return; + QGraphicsItem *p = item->d_ptr->parent; bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); @@ -186,9 +275,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr _q_adjustRect(&brect); //We fill the intersector with needed informations - intersector->transform = transform; - intersector->item = item; - keep = intersector->intersect(brect); + keep = intersector->intersect(item, exposeRect, mode, transform, viewTransform); } bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); @@ -211,7 +298,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr // Clip. if (childClip) - intersector->rect &= transform.map(item->shape()).controlPointRect(); + exposeRect &= transform.map(item->shape()).controlPointRect(); // Process children behind int i = 0; @@ -220,7 +307,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr QGraphicsItem *child = children.at(i); if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; - recursive_items_helper(child, intersector, items, transform, viewTransform, + recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); } } @@ -232,7 +319,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr // Process children in front if (!dontProcessChildren) { for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), intersector, items, transform, viewTransform, + recursive_items_helper(children.at(i), exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); } @@ -311,12 +398,12 @@ QRectF QGraphicsSceneIndex::indexedRect() const QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_D(const QGraphicsSceneIndex); QList itemList; - d->pointIntersector->mode = mode; - d->pointIntersector->rect = QRectF(pos, QSize(1,1)); - d->pointIntersector->pos = pos; - d->recursive_items_helper(0, d->pointIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->pointIntersector->scenePoint = pos; + d->recursive_items_helper(0, QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, + QTransform(), deviceTransform, mode, order); return itemList; } @@ -346,10 +433,11 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); + QRectF exposeRect = rect; + _q_adjustRect(&exposeRect); QList itemList; - d->rectIntersector->mode = mode; - d->rectIntersector->rect = rect; - d->recursive_items_helper(0, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->rectIntersector->sceneRect = rect; + d->recursive_items_helper(0, exposeRect, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } @@ -380,14 +468,12 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: { Q_D(const QGraphicsSceneIndex); QList itemList; - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - d->pathIntersector->mode = mode; - d->pathIntersector->rect = polyRect; + QRectF exposeRect = polygon.boundingRect(); + _q_adjustRect(&exposeRect); QPainterPath path; path.addPolygon(polygon); - d->pathIntersector->path = path; - d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->pathIntersector->scenePath = path; + d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } @@ -418,12 +504,10 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: { Q_D(const QGraphicsSceneIndex); QList itemList; - QRectF pathRect(path.controlPointRect()); - _q_adjustRect(&pathRect); - d->pathIntersector->mode = mode; - d->pathIntersector->rect = pathRect; - d->pathIntersector->path = path; - d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + QRectF exposeRect = path.controlPointRect(); + _q_adjustRect(&exposeRect); + d->pathIntersector->scenePath = path; + d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } @@ -508,7 +592,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) \sa QGraphicsItem::GraphicsItemChange */ -void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { Q_UNUSED(item); Q_UNUSED(change); diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index ddce9d4..25ece04 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -104,7 +104,7 @@ protected: virtual void removeItem(QGraphicsItem *item) = 0; virtual void deleteItem(QGraphicsItem *item); - virtual void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); virtual void sceneRectChanged(const QRectF &rect); diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index d0d181b..576ee98 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -75,9 +75,12 @@ public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); ~QGraphicsSceneIndexPrivate(); - void recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, - const QTransform &parentTransform, const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; + static bool itemCollidesWithPath(const QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode); + + void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, + QGraphicsSceneIndexIntersector *intersector, QList *items, + const QTransform &parentTransform, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; QGraphicsScene *scene; QGraphicsSceneIndexPointIntersector *pointIntersector; QGraphicsSceneIndexRectIntersector *rectIntersector; @@ -87,14 +90,10 @@ public: class QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexIntersector(QGraphicsScene *scene) : scene(scene) { } + QGraphicsSceneIndexIntersector() { } virtual ~QGraphicsSceneIndexIntersector() { } - virtual bool intersect(const QRectF &rect) const = 0; - Qt::ItemSelectionMode mode; - QGraphicsItem *item; - QGraphicsScene *scene; - QRectF rect; - QTransform transform; + virtual bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const = 0; }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 8c40878..a1e6d9c 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -914,44 +914,32 @@ extern QPainterPath qt_regionToPath(const QRegion ®ion); is at risk of painting 1 pixel outside the bounding rect. Therefore we must search for items with an adjustment of (-1, -1, 1, 1). */ -QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const +QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems, + const QTransform &viewTransform) const { Q_Q(const QGraphicsView); // Step 1) If all items are contained within the expose region, then - // return a list of all visible items. + // return a list of all visible items. ### the scene's growing bounding + // rect does not take into account untransformable items. const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1)) .boundingRect(); if (exposedRegionSceneBounds.contains(scene->d_func()->growingItemsBoundingRect)) { Q_ASSERT(allItems); *allItems = true; - // All items are guaranteed within the exposed region, don't bother using the index. - QList itemList(scene->d_func()->index->items(Qt::DescendingOrder)); - int i = 0; - while (i < itemList.size()) { - const QGraphicsItem *item = itemList.at(i); - // But we only want to include items that are visible - // The following check is basically the same as item->d_ptr->isInvisible(), except - // that we don't check whether the item clips children to shape or propagates its - // opacity (we loop through all items, so those checks are wrong in this context). - if (!item->isVisible() || item->d_ptr->isClippedAway() || item->d_ptr->isFullyTransparent()) - itemList.removeAt(i); - else - ++i; - } - return itemList; + // All items are guaranteed within the exposed region. + return scene->items(Qt::DescendingOrder); } // Step 2) If the expose region is a simple rect and the view is only // translated or scaled, search for items using // QGraphicsScene::items(QRectF). - bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull() - && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale); + bool simpleRectLookup = exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale; if (simpleRectLookup) { - return scene->d_func()->index->items(exposedRegionSceneBounds, - Qt::IntersectsItemBoundingRect, - Qt::DescendingOrder); + return scene->items(exposedRegionSceneBounds, + Qt::IntersectsItemBoundingRect, + Qt::DescendingOrder, viewTransform); } // If the region is complex or the view has a complex transform, adjust @@ -961,16 +949,9 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg foreach (const QRect &r, exposedRegion.rects()) adjustedRegion += r.adjusted(-1, -1, 1, 1); - const QPainterPath exposedPath(qt_regionToPath(adjustedRegion)); - if (scene->d_func()->largestUntransformableItem.isNull()) { - const QPainterPath exposedScenePath(q->mapToScene(exposedPath)); - return scene->d_func()->index->items(exposedScenePath, - Qt::IntersectsItemBoundingRect, - Qt::DescendingOrder); - } - - // NB! Path must be in viewport coordinates. - return itemsInArea(exposedPath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); + const QPainterPath exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion))); + return scene->items(exposedScenePath, Qt::IntersectsItemBoundingRect, + Qt::DescendingOrder, viewTransform); } /*! @@ -1875,6 +1856,8 @@ void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode asp void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect &source, Qt::AspectRatioMode aspectRatioMode) { + // ### Switch to using the recursive rendering algorithm instead. + Q_D(QGraphicsView); if (!d->scene || !(painter && painter->isActive())) return; @@ -1972,67 +1955,6 @@ QList QGraphicsView::items() const } /*! - Returns all items in the area \a path, which is in viewport coordinates, - also taking untransformable items into consideration. This function is - considerably slower than just checking the scene directly. There is - certainly room for improvement. -*/ -QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &path, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - Q_Q(const QGraphicsView); - - // Determine the size of the largest untransformable subtree of children - // mapped to scene coordinates. - QRectF untr = scene->d_func()->largestUntransformableItem; - QRectF ltri = matrix.inverted().mapRect(untr); - ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); - - QRectF rect = path.controlPointRect(); - - // Find all possible items in the relevant area. - // ### Improve this algorithm; it might be searching a too large area. - QRectF adjustedRect = q->mapToScene(rect.adjusted(-1, -1, 1, 1).toRect()).boundingRect(); - adjustedRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); - - // First build a (potentially large) list of all items in the vicinity - // that might be untransformable. - QList allCandidates = scene->d_func()->index->estimateItems(adjustedRect, order, q->transform()); - - // Then find the minimal list of items that are inside \a path, and - // convert it to a set. - QList regularCandidates = scene->items(q->mapToScene(path), mode, order, q->transform()); - QSet candSet = QSet::fromList(regularCandidates); - - QTransform viewMatrix = q->viewportTransform(); - - QList result; - - //### this will disapear - - // Run through all candidates and keep all items that are in candSet, or - // are untransformable and collide with \a path. ### We can improve this - // algorithm. - QList::Iterator it = allCandidates.begin(); - while (it != allCandidates.end()) { - QGraphicsItem *item = *it; - if (item->d_ptr->itemIsUntransformable()) { - // Check if this untransformable item collides with the - // original selection rect. - QTransform itemTransform = item->deviceTransform(viewMatrix); - if (QGraphicsScenePrivate::itemCollidesWithPath(item, itemTransform.inverted().map(path), mode)) - result << item; - } else { - if (candSet.contains(item)) - result << item; - } - ++it; - } - return result; -} - -/*! Returns a list of all the items at the position \a pos in the view. The items are listed in descending Z order (i.e., the first item in the list is the top-most item, and the last item is the bottom-most item). \a pos @@ -2051,17 +1973,22 @@ QList QGraphicsView::items(const QPoint &pos) const Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) { - if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) { - QTransform xinv = viewportTransform().inverted(); - return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1))); - } - return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1)); + // ### Unify these two, and use the items(QPointF) version in + // QGraphicsScene instead. The scene items function could use the viewport + // transform to map the point to a rect/polygon. + if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) { + // Use the rect version + QTransform xinv = viewportTransform().inverted(); + return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)), + Qt::IntersectsItemShape, + Qt::AscendingOrder, + viewportTransform()); } - - QPainterPath path; - path.addRect(QRectF(pos.x(), pos.y(), 1, 1)); - return d->itemsInArea(path); + // Use the polygon version + return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1), + Qt::IntersectsItemShape, + Qt::AscendingOrder, + viewportTransform()); } /*! @@ -2088,12 +2015,7 @@ QList QGraphicsView::items(const QRect &rect, Qt::ItemSelection Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) - return d->scene->items(mapToScene(rect), mode); - - QPainterPath path; - path.addRect(rect); - return d->itemsInArea(path); + return d->scene->items(mapToScene(rect), mode, Qt::AscendingOrder, viewportTransform()); } /*! @@ -2121,13 +2043,7 @@ QList QGraphicsView::items(const QPolygon &polygon, Qt::ItemSel Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) - return d->scene->items(mapToScene(polygon), mode); - - QPainterPath path; - path.addPolygon(polygon); - path.closeSubpath(); - return d->itemsInArea(path); + return d->scene->items(mapToScene(polygon), mode, Qt::AscendingOrder, viewportTransform()); } /*! @@ -2147,9 +2063,7 @@ QList QGraphicsView::items(const QPainterPath &path, Qt::ItemSe Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) - return d->scene->items(mapToScene(path), mode); - return d->itemsInArea(path); + return d->scene->items(mapToScene(path), mode, Qt::AscendingOrder, viewportTransform()); } /*! @@ -2168,7 +2082,9 @@ QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const Q_D(const QGraphicsView); if (!d->scene) return 0; - QList itemsAtPos = items(pos); + // ### Use QGraphicsScene::itemAt() instead. + QList itemsAtPos = d->scene->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder, + viewportTransform()); return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first(); } @@ -3073,7 +2989,8 @@ void QGraphicsView::mouseMoveEvent(QMouseEvent *event) selectionArea.addPolygon(mapToScene(d->rubberBandRect)); selectionArea.closeSubpath(); if (d->scene) - d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode); + d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode, + viewportTransform()); return; } } else @@ -3280,7 +3197,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event) } else { // Find all exposed items bool allItems = false; - QList itemList = d->findItems(d->exposedRegion, &allItems); + QList itemList = d->findItems(d->exposedRegion, &allItems, viewTransform); if (!itemList.isEmpty()) { // Generate the style options. diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index fac7bf9..760f54e 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -84,10 +84,6 @@ public: qint64 horizontalScroll() const; qint64 verticalScroll() const; - QList itemsInArea(const QPainterPath &path, - Qt::ItemSelectionMode mode = Qt::IntersectsItemShape, - Qt::SortOrder = Qt::AscendingOrder) const; - QPointF mousePressItemPoint; QPointF mousePressScenePoint; QPoint mousePressViewPoint; @@ -176,7 +172,8 @@ public: bool updateSceneSlotReimplementedChecked; QRegion exposedRegion; - QList findItems(const QRegion &exposedRegion, bool *allItems) const; + QList findItems(const QRegion &exposedRegion, bool *allItems, + const QTransform &viewTransform) const; }; QT_END_NAMESPACE -- cgit v0.12 From b8ca90d6ca745915455f044f967a345bab7a910e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:49:24 +0200 Subject: Move QGraphicsSceneIndex into private headers (=> _p.h). We'd like to keep this API private for now. Reviewed-by: Alexis --- src/gui/graphicsview/graphicsview.pri | 57 +++++---- src/gui/graphicsview/qgraphicsscene.cpp | 5 +- src/gui/graphicsview/qgraphicsscene_p.h | 2 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 4 +- src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 2 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 5 +- src/gui/graphicsview/qgraphicssceneindex.h | 129 --------------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 79 +++++++++++-- src/gui/graphicsview/qgraphicsscenelinearindex.h | 2 +- 9 files changed, 106 insertions(+), 179 deletions(-) delete mode 100644 src/gui/graphicsview/qgraphicssceneindex.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 5ac1c54..2d8f37e 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -1,46 +1,43 @@ # Qt graphicsview module -HEADERS += graphicsview/qgraphicsitem.h \ +HEADERS += graphicsview/qgraphicsgridlayout.h \ + graphicsview/qgraphicsitem.h \ graphicsview/qgraphicsitem_p.h \ graphicsview/qgraphicsitemanimation.h \ + graphicsview/qgraphicslayout.h \ + graphicsview/qgraphicslayout_p.h \ + graphicsview/qgraphicslayoutitem.h \ + graphicsview/qgraphicslayoutitem_p.h \ + graphicsview/qgraphicslinearlayout.h \ + graphicsview/qgraphicsproxywidget.h \ graphicsview/qgraphicsscene.h \ - graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ - graphicsview/qgraphicsscenelinearindex.h \ - graphicsview/qgraphicssceneindex.h \ - graphicsview/qgraphicssceneindex_p.h \ + graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscenebsptreeindex.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ graphicsview/qgraphicssceneevent.h \ + graphicsview/qgraphicssceneindex_p.h \ + graphicsview/qgraphicsscenelinearindex.h \ + graphicsview/qgraphicsview.h \ graphicsview/qgraphicsview_p.h \ - graphicsview/qgraphicsview.h -SOURCES += graphicsview/qgraphicsitem.cpp \ - graphicsview/qgraphicsitemanimation.cpp \ - graphicsview/qgraphicsscene.cpp \ - graphicsview/qgraphicsscene_bsp.cpp \ - graphicsview/qgraphicsscenebsptreeindex.cpp \ - graphicsview/qgraphicsscenelinearindex.cpp \ - graphicsview/qgraphicssceneindex.cpp \ - graphicsview/qgraphicssceneevent.cpp \ - graphicsview/qgraphicsview.cpp - - -# Widgets on the canvas -HEADERS += graphicsview/qgraphicslayout.h \ - graphicsview/qgraphicslayout_p.h \ - graphicsview/qgraphicslayoutitem.h \ - graphicsview/qgraphicslayoutitem_p.h \ - graphicsview/qgraphicslinearlayout.h \ graphicsview/qgraphicswidget.h \ graphicsview/qgraphicswidget_p.h \ - graphicsview/qgridlayoutengine_p.h \ - graphicsview/qgraphicsproxywidget.h \ - graphicsview/qgraphicsgridlayout.h -SOURCES += graphicsview/qgraphicslayout.cpp \ + graphicsview/qgridlayoutengine_p.h + +SOURCES += graphicsview/qgraphicsgridlayout.cpp \ + graphicsview/qgraphicsitem.cpp \ + graphicsview/qgraphicsitemanimation.cpp \ + graphicsview/qgraphicslayout.cpp \ graphicsview/qgraphicslayout_p.cpp \ graphicsview/qgraphicslayoutitem.cpp \ graphicsview/qgraphicslinearlayout.cpp \ + graphicsview/qgraphicsproxywidget.cpp \ + graphicsview/qgraphicsscene.cpp \ + graphicsview/qgraphicsscene_bsp.cpp \ + graphicsview/qgraphicsscenebsptreeindex.cpp \ + graphicsview/qgraphicssceneevent.cpp \ + graphicsview/qgraphicssceneindex.cpp \ + graphicsview/qgraphicsscenelinearindex.cpp \ + graphicsview/qgraphicsview.cpp \ graphicsview/qgraphicswidget.cpp \ graphicsview/qgraphicswidget_p.cpp \ - graphicsview/qgridlayoutengine.cpp \ - graphicsview/qgraphicsproxywidget.cpp \ - graphicsview/qgraphicsgridlayout.cpp + graphicsview/qgridlayoutengine.cpp diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 55f0f20..9d224b1 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -217,7 +217,6 @@ #include "qgraphicsview_p.h" #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" -#include "qgraphicssceneindex.h" #include "qgraphicsscenebsptreeindex.h" #include "qgraphicsscenelinearindex.h" @@ -244,6 +243,7 @@ #include #include #include +#include #include #ifdef Q_WS_X11 #include @@ -772,6 +772,7 @@ QList QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre const QPointF &scenePos, QWidget *widget) const { + Q_UNUSED(screenPos); Q_Q(const QGraphicsScene); QGraphicsView *view = widget ? qobject_cast(widget->parentWidget()) : 0; return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, @@ -1806,7 +1807,7 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path) */ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode) { - setSelectionArea(path, Qt::IntersectsItemShape, QTransform()); + setSelectionArea(path, mode, QTransform()); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index a081e04..fd25283 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -58,7 +58,6 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicssceneindex.h" #include "qgraphicsview.h" #include "qgraphicsitem_p.h" @@ -74,6 +73,7 @@ QT_BEGIN_NAMESPACE +class QGraphicsSceneIndex; class QGraphicsView; class QGraphicsWidget; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 40cafa6..54bf09b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -80,12 +80,12 @@ #ifndef QT_NO_GRAPHICSVIEW #include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicssceneindex_p.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" -#include +#include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h index 504ea8b..f3c77d3 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h @@ -67,7 +67,7 @@ QT_MODULE(Gui) #include #include #include -#include +#include #include "qgraphicsscene_bsp_p.h" diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index eb3abc1..8d7581f 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -56,12 +56,11 @@ \sa QGraphicsScene, QGraphicsView */ -#include "qgraphicssceneindex.h" -#include "qgraphicssceneindex_p.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" #include "qgraphicswidget.h" +#include #ifndef QT_NO_GRAPHICSVIEW @@ -621,6 +620,6 @@ void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) QT_END_NAMESPACE -#include "moc_qgraphicssceneindex.cpp" +#include "moc_qgraphicssceneindex_p.cpp" #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h deleted file mode 100644 index 25ece04..0000000 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENEINDEX_H -#define QGRAPHICSSCENEINDEX_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -class QGraphicsSceneIndexPrivate; -class QGraphicsScene; -class QRectF; -class QPointF; -template class QList; - -class Q_AUTOTEST_EXPORT QGraphicsSceneIndex: public QObject -{ - Q_OBJECT - -public: - QGraphicsSceneIndex(QGraphicsScene *scene = 0); - virtual ~QGraphicsSceneIndex(); - - QGraphicsScene *scene() const; - - virtual QRectF indexedRect() const; - - virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; - virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList estimateItems(const QPointF &point, - Qt::SortOrder order, const QTransform &deviceTransform) const; - virtual QList estimateItems(const QRectF &rect, - Qt::SortOrder order, const QTransform &deviceTransform) const = 0; - -protected: - virtual void clear(); - virtual void addItem(QGraphicsItem *item) = 0; - virtual void removeItem(QGraphicsItem *item) = 0; - virtual void deleteItem(QGraphicsItem *item); - - virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); - virtual void prepareBoundingRectChange(const QGraphicsItem *item); - virtual void sceneRectChanged(const QRectF &rect); - - QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); - - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; - friend class QGraphicsItem; - friend class QGraphicsItemPrivate; - friend class QGraphicsSceneBspTreeIndex; -private: - Q_DISABLE_COPY(QGraphicsSceneIndex) - Q_DECLARE_PRIVATE(QGraphicsSceneIndex) -}; - -#endif // QT_NO_GRAPHICSVIEW - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGRAPHICSSCENEINDEX_H diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 576ee98..85a1140 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QGRAPHICSSCENEINDEX_P_H -#define QGRAPHICSSCENEINDEX_P_H +#ifndef QGRAPHICSSCENEINDEX_H +#define QGRAPHICSSCENEINDEX_H // // W A R N I N G @@ -53,20 +53,77 @@ // We mean it. // -#include "qgraphicssceneindex.h" - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - +#include +#include +#include +#include #include -#include + +QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + class QGraphicsScene; class QGraphicsSceneIndexIntersector; -class QGraphicsSceneIndexRectIntersector; class QGraphicsSceneIndexPointIntersector; +class QGraphicsSceneIndexRectIntersector; class QGraphicsSceneIndexPathIntersector; +class QGraphicsSceneIndexPrivate; +class QPointF; +class QRectF; +template class QList; + +class Q_AUTOTEST_EXPORT QGraphicsSceneIndex : public QObject +{ + Q_OBJECT + +public: + QGraphicsSceneIndex(QGraphicsScene *scene = 0); + virtual ~QGraphicsSceneIndex(); + + QGraphicsScene *scene() const; + + virtual QRectF indexedRect() const; + + virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; + virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList estimateItems(const QPointF &point, + Qt::SortOrder order, const QTransform &deviceTransform) const; + virtual QList estimateItems(const QRectF &rect, + Qt::SortOrder order, const QTransform &deviceTransform) const = 0; + +protected: + virtual void clear(); + virtual void addItem(QGraphicsItem *item) = 0; + virtual void removeItem(QGraphicsItem *item) = 0; + virtual void deleteItem(QGraphicsItem *item); + + virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void prepareBoundingRectChange(const QGraphicsItem *item); + virtual void sceneRectChanged(const QRectF &rect); + + QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; + friend class QGraphicsItem; + friend class QGraphicsItemPrivate; + friend class QGraphicsSceneBspTreeIndex; +private: + Q_DISABLE_COPY(QGraphicsSceneIndex) + Q_DECLARE_PRIVATE(QGraphicsSceneIndex) +}; class QGraphicsSceneIndexPrivate : public QObjectPrivate { @@ -96,8 +153,10 @@ public: const QTransform &transform, const QTransform &deviceTransform) const = 0; }; +#endif // QT_NO_GRAPHICSVIEW + QT_END_NAMESPACE -#endif // QGRAPHICSSCENEINDEX_P_H +QT_END_HEADER -#endif +#endif // QGRAPHICSSCENEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.h b/src/gui/graphicsview/qgraphicsscenelinearindex.h index b793d98..a5327ef 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.h @@ -65,8 +65,8 @@ QT_MODULE(Gui) #include #include -#include #include +#include class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex { -- cgit v0.12 From d49fd874258c055b54b122a0c1f6f10ee20f11ea Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:52:47 +0200 Subject: Move QGraphicsSceneLinearIndex into private headers (=> _p.h). We want to keep this as private API for now. Reviewed-by: Alexis --- src/gui/graphicsview/graphicsview.pri | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 4 +- src/gui/graphicsview/qgraphicsscenelinearindex.h | 124 --------------------- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 124 +++++++++++++++++++++ 5 files changed, 128 insertions(+), 128 deletions(-) delete mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex.h create mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 2d8f37e..5981ce5 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -16,7 +16,7 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicssceneindex_p.h \ - graphicsview/qgraphicsscenelinearindex.h \ + graphicsview/qgraphicsscenelinearindex_p.h \ graphicsview/qgraphicsview.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicswidget.h \ diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9d224b1..e004917 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -218,7 +218,7 @@ #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" #include "qgraphicsscenebsptreeindex.h" -#include "qgraphicsscenelinearindex.h" +#include #include #include diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp index 5504493..694062b 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -1,5 +1,3 @@ -#include "qgraphicsscenelinearindex.h" - /*! \class QGraphicsSceneLinearIndex \brief The QGraphicsSceneLinearIndex class provides an implementation of @@ -16,6 +14,8 @@ \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex, QGraphicsSceneBspTreeIndex */ +#include + /*! \fn QGraphicsSceneLinearIndex::QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.h b/src/gui/graphicsview/qgraphicsscenelinearindex.h deleted file mode 100644 index a5327ef..0000000 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENELINEARINDEX_H -#define QGRAPHICSSCENELINEARINDEX_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include -#include -#include - -class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex -{ - Q_OBJECT - -public: - QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) - { - } - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - Q_UNUSED(order); - return m_items; - } - - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - Q_UNUSED(rect); - Q_UNUSED(order); - Q_UNUSED(deviceTransform); - return m_items; - } - - virtual QRectF indexedRect() const { - return m_sceneRect; - } - -protected : - void sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - } - - virtual void clear() { - m_items.clear(); - } - - virtual void addItem(QGraphicsItem *item) { - m_items << item; - } - - virtual void removeItem(QGraphicsItem *item) { - m_items.removeAll(item); - } - -private: - QRectF m_sceneRect; - QList m_items; -}; - -#endif // QT_NO_GRAPHICSVIEW - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGRAPHICSSCENELINEARINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h new file mode 100644 index 0000000..a5327ef --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENELINEARINDEX_H +#define QGRAPHICSSCENELINEARINDEX_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include + +class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + +public: + QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) + { + } + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { + Q_UNUSED(order); + return m_items; + } + + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_UNUSED(rect); + Q_UNUSED(order); + Q_UNUSED(deviceTransform); + return m_items; + } + + virtual QRectF indexedRect() const { + return m_sceneRect; + } + +protected : + void sceneRectChanged(const QRectF &rect) { + m_sceneRect = rect; + } + + virtual void clear() { + m_items.clear(); + } + + virtual void addItem(QGraphicsItem *item) { + m_items << item; + } + + virtual void removeItem(QGraphicsItem *item) { + m_items.removeAll(item); + } + +private: + QRectF m_sceneRect; + QList m_items; +}; + +#endif // QT_NO_GRAPHICSVIEW + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGRAPHICSSCENELINEARINDEX_H -- cgit v0.12 From 734cc7dd63147f80cd4794351b9124f8d6eb88fe Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:56:59 +0200 Subject: Move QGraphicsSceneBspTreeIndex into private headers (=> _p.h). We'll keep this as private API for now. Reviewed-by: Alexis --- src/gui/graphicsview/graphicsview.pri | 1 - src/gui/graphicsview/qgraphicsscene.cpp | 2 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 10 +- src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 119 --------------------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 66 ++++++++++-- 5 files changed, 61 insertions(+), 137 deletions(-) delete mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 5981ce5..0c0747e 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -12,7 +12,6 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_bsp_p.h \ graphicsview/qgraphicsscene_p.h \ - graphicsview/qgraphicsscenebsptreeindex.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicssceneindex_p.h \ diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e004917..28dd3be 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -217,7 +217,7 @@ #include "qgraphicsview_p.h" #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" -#include "qgraphicsscenebsptreeindex.h" +#include #include #include diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 54bf09b..27b5514 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -75,14 +75,10 @@ \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex */ -#include "qgraphicsscenebsptreeindex.h" - #ifndef QT_NO_GRAPHICSVIEW -#include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicsitem_p.h" -#include "qgraphicsscene_p.h" - +#include +#include #include #include @@ -783,7 +779,7 @@ bool QGraphicsSceneBspTreeIndex::event(QEvent *event) QT_END_NAMESPACE -#include "moc_qgraphicsscenebsptreeindex.cpp" +#include "moc_qgraphicsscenebsptreeindex_p.cpp" #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h deleted file mode 100644 index f3c77d3..0000000 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QGRAPHICSBSPTREEINDEX_H -#define QGRAPHICSBSPTREEINDEX_H - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include -#include -#include -#include - -#include "qgraphicsscene_bsp_p.h" - -class QGraphicsSceneBspTreeIndexPrivate; - -class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex -{ - Q_OBJECT - Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) -public: - QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect() const; - - QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const; - - int bspTreeDepth(); - void setBspTreeDepth(int depth); - -protected: - bool event(QEvent *event); - void clear(); - - void addItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); - void prepareBoundingRectChange(const QGraphicsItem *item); - - void sceneRectChanged(const QRectF &rect); - void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); - -private : - Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) - Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) - Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) - Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) - - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; -}; - -#endif // QT_NO_GRAPHICSVIEW - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGRAPHICSBSPTREEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index ed12fac..1e4234e 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -39,8 +39,7 @@ ** ****************************************************************************/ -#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_H -#define QGRAPHICSSCENEBSPTREEINDEX_P_H +#include // // W A R N I N G @@ -53,18 +52,66 @@ // We mean it. // -#include "qgraphicsscenebsptreeindex.h" +#ifndef QGRAPHICSBSPTREEINDEX_H +#define QGRAPHICSBSPTREEINDEX_H + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -#include +#include +#include +#include +#include #include - -QT_BEGIN_NAMESPACE +#include +#include static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; class QGraphicsScene; +class QGraphicsSceneBspTreeIndexPrivate; + +class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) +public: + QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + QRectF indexedRect() const; + + QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const; + + int bspTreeDepth(); + void setBspTreeDepth(int depth); + +protected: + bool event(QEvent *event); + void clear(); + + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); + + void sceneRectChanged(const QRectF &rect); + void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + +private : + Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) + Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) + Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; +}; class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate { @@ -183,9 +230,10 @@ static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) return !(t1 >= b2 || t2 >= b1); } -QT_END_NAMESPACE +#endif // QT_NO_GRAPHICSVIEW -#endif // QGRAPHICSSCENEBSPTREEINDEX_P_H +QT_END_NAMESPACE -#endif +QT_END_HEADER +#endif // QGRAPHICSBSPTREEINDEX_H -- cgit v0.12 From 378b5b603bd269b631bbe108268a683adde11828 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 15:02:05 +0200 Subject: Make the autotests compile again. Reviewed-by: Alexis --- .../tst_qgraphicssceneindex.cpp | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 6b352ab..d10f86d 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -42,11 +42,10 @@ #include #include -#include #include +#include #include - //TESTED_CLASS= //TESTED_FILES= @@ -118,6 +117,7 @@ void tst_QGraphicsSceneIndex::customIndex_data() void tst_QGraphicsSceneIndex::customIndex() { +#if 0 QFETCH(QString, indexMethod); QGraphicsSceneIndex *index = createIndex(indexMethod); @@ -126,6 +126,7 @@ void tst_QGraphicsSceneIndex::customIndex() scene.addRect(0, 0, 30, 40); QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1); +#endif } void tst_QGraphicsSceneIndex::scatteredItems_data() @@ -136,10 +137,14 @@ void tst_QGraphicsSceneIndex::scatteredItems_data() void tst_QGraphicsSceneIndex::scatteredItems() { QFETCH(QString, indexMethod); - QGraphicsSceneIndex *index = createIndex(indexMethod); QGraphicsScene scene; +#if 1 + scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex); +#else + QGraphicsSceneIndex *index = createIndex(indexMethod); scene.setSceneIndex(index); +#endif for (int i = 0; i < 10; ++i) scene.addRect(i*50, i*50, 40, 35); @@ -161,10 +166,14 @@ void tst_QGraphicsSceneIndex::overlappedItems_data() void tst_QGraphicsSceneIndex::overlappedItems() { QFETCH(QString, indexMethod); - QGraphicsSceneIndex *index = createIndex(indexMethod); QGraphicsScene scene; +#if 1 + scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex); +#else + QGraphicsSceneIndex *index = createIndex(indexMethod); scene.setSceneIndex(index); +#endif for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) @@ -191,10 +200,14 @@ void tst_QGraphicsSceneIndex::movingItems_data() void tst_QGraphicsSceneIndex::movingItems() { QFETCH(QString, indexMethod); - QGraphicsSceneIndex *index = createIndex(indexMethod); QGraphicsScene scene; +#if 1 + scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex); +#else + QGraphicsSceneIndex *index = createIndex(indexMethod); scene.setSceneIndex(index); +#endif for (int i = 0; i < 10; ++i) scene.addRect(i*50, i*50, 40, 35); -- cgit v0.12 From a18e5288324aa13da014ee52daffbfc589c87be3 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 18 Jun 2009 17:29:42 +0200 Subject: Fix crash with untransformable items. Be sure that item goes in the correct list if it set its flags to untransformable. Reviewed-by: andreas --- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 43 +++++++++++++++------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 27b5514..72636b8 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -548,14 +548,9 @@ void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) // ### remove from child index only if applicable return; } - int index = item->d_func()->index; - if (index != -1) { - bsp.removeItem(item, item->sceneBoundingRect()); - freeItemIndexes << index; - indexedItems[index] = 0; - item->d_func()->index = -1; - unindexedItems << item; + if (item->d_func()->index != -1) { + bsp.removeItem(item, item->sceneBoundingRect()); //prepareGeometryChange will call prepareBoundingRectChange foreach (QGraphicsItem *child, item->children()) child->prepareGeometryChange(); @@ -570,10 +565,20 @@ void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromBspTree(const_cast(item)); + if (!item->d_ptr->itemIsUntransformable()) { + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + QGraphicsItem *thatItem = const_cast(item); + d->removeFromBspTree(thatItem); + int index = item->d_func()->index; + if (index != -1) { + d->freeItemIndexes << index; + d->indexedItems[index] = 0; + thatItem->d_func()->index = -1; + d->unindexedItems << thatItem; + } + } } /*! @@ -725,7 +730,13 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics if (ignoredTransform != willIgnoreTransform) { QGraphicsItem *thatItem = const_cast(item); removeItem(thatItem); - addItem(thatItem); + thatItem->d_ptr->index = -1; + if (willIgnoreTransform) { + d->untransformableItems << thatItem; + } else { + d->unindexedItems << thatItem; + d->startIndexTimer(0); + } } break; } @@ -741,7 +752,13 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics if (ignoredTransform != willIgnoreTransform) { QGraphicsItem *thatItem = const_cast(item); removeItem(thatItem); - addItem(thatItem); + thatItem->d_ptr->index = -1; + if (willIgnoreTransform) { + d->untransformableItems << thatItem; + } else { + d->unindexedItems << thatItem; + d->startIndexTimer(0); + } } break; } -- cgit v0.12 From 8befd7589456c6fd193676daeba8f0779d88776e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Mon, 22 Jun 2009 11:32:51 +0200 Subject: Remove unused code / delay in this autotest. --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 1ca6c98..981efeb 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4710,11 +4710,6 @@ void tst_QGraphicsItem::itemClipsChildrenToShape() scene.render(&painter); painter.end(); - QGraphicsView view(&scene); - view.show(); - - QTest::qWait(5000); - QCOMPARE(image.pixel(16, 16), QColor(255, 0, 0).rgba()); QCOMPARE(image.pixel(32, 32), QColor(0, 0, 255).rgba()); QCOMPARE(image.pixel(50, 50), QColor(0, 255, 0).rgba()); -- cgit v0.12 From 375c4f53e9702aa3273154c0879e3b6dbd2723d6 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Mon, 22 Jun 2009 11:38:17 +0200 Subject: QGraphicsSceneLinearIndex: touch-ups. --- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 39 +++++++++------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index a5327ef..88e0e6a 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -73,42 +73,35 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex Q_OBJECT public: - QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) - { - } + QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0) : QGraphicsSceneIndex(scene) + { } - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - Q_UNUSED(order); - return m_items; - } + QList items(Qt::SortOrder order = Qt::AscendingOrder) const + { Q_UNUSED(order); return m_items; } - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const + { Q_UNUSED(rect); Q_UNUSED(order); Q_UNUSED(deviceTransform); return m_items; } - virtual QRectF indexedRect() const { - return m_sceneRect; - } + virtual QRectF indexedRect() const + { return m_sceneRect; } protected : - void sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - } + void sceneRectChanged(const QRectF &rect) + { m_sceneRect = rect; } - virtual void clear() { - m_items.clear(); - } + virtual void clear() + { m_items.clear(); } - virtual void addItem(QGraphicsItem *item) { - m_items << item; - } + virtual void addItem(QGraphicsItem *item) + { m_items << item; } - virtual void removeItem(QGraphicsItem *item) { - m_items.removeAll(item); - } + virtual void removeItem(QGraphicsItem *item) + { m_items.removeOne(item); } private: QRectF m_sceneRect; -- cgit v0.12 From be79229e9c454764d63262f46f686b3e1721ee2c Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Tue, 23 Jun 2009 12:35:31 +0200 Subject: More work on getting autotests to pass. --- src/gui/graphicsview/qgraphicsscene.cpp | 33 ++++++++++++++------ src/gui/graphicsview/qgraphicsscene_p.h | 1 + .../graphicsview/qgraphicsscenebsptreeindex.cpp | 36 +++++----------------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 3 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 23 +++----------- src/gui/graphicsview/qgraphicssceneindex_p.h | 4 +-- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 7 ----- src/gui/graphicsview/qgraphicsview.cpp | 16 +++++----- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 28 ++++++++++++++--- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 1 + 10 files changed, 71 insertions(+), 81 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 2f7ae04..6f92629 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -273,6 +273,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() index(0), lastItemCount(0), hasSceneRect(false), + dirtyGrowingItemsBoundingRect(true), updateAll(false), calledEmitUpdated(false), processDirtyItemsEmitted(false), @@ -378,8 +379,9 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) */ void QGraphicsScenePrivate::_q_updateLater() { + QRectF null; foreach (QGraphicsItem *item, pendingUpdateItems) - item->update(); + markDirty(item, null); pendingUpdateItems.clear(); } @@ -409,8 +411,11 @@ void QGraphicsScenePrivate::_q_processDirtyItems() const bool wasPendingSceneUpdate = calledEmitUpdated; const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; processDirtyItemsRecursive(0); - if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect) + dirtyGrowingItemsBoundingRect = false; + if (oldGrowingItemsBoundingRect != growingItemsBoundingRect) { + index->sceneRectChanged(); emit q_func()->sceneRectChanged(growingItemsBoundingRect); + } if (wasPendingSceneUpdate) return; @@ -1250,9 +1255,18 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - /// ### Remove? The growing items bounding rect might be managed - // by the scene. - return d->index->indexedRect(); + if (!d->hasSceneRect && d->dirtyGrowingItemsBoundingRect) { + // Lazily update the growing items bounding rect + QGraphicsScenePrivate *thatd = const_cast(d); + QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect; + thatd->growingItemsBoundingRect |= itemsBoundingRect(); + thatd->dirtyGrowingItemsBoundingRect = false; + if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect) { + thatd->index->sceneRectChanged(); + emit const_cast(this)->sceneRectChanged(thatd->growingItemsBoundingRect); + } + } + return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; } void QGraphicsScene::setSceneRect(const QRectF &rect) { @@ -1260,8 +1274,8 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) if (rect != d->sceneRect) { d->hasSceneRect = !rect.isNull(); d->sceneRect = rect; - d->index->sceneRectChanged(rect); - emit sceneRectChanged(rect); + d->index->sceneRectChanged(); + emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect); } } @@ -1411,8 +1425,6 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->index = new QGraphicsSceneLinearIndex(this); for (int i = oldItems.size() - 1; i >= 0; --i) d->index->addItem(oldItems.at(i)); - - d->index->sceneRectChanged(d->sceneRect); } /*! @@ -2057,6 +2069,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item) if (d->pendingUpdateItems.isEmpty()) QMetaObject::invokeMethod(this, "_q_updateLater", Qt::QueuedConnection); d->pendingUpdateItems << item; + } else { + d->dirtyGrowingItemsBoundingRect = true; } // Disable selectionChanged() for individual items @@ -4235,6 +4249,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b bool removingItemFromScene) { Q_ASSERT(item); + dirtyGrowingItemsBoundingRect = true; if (updateAll) return; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index ea65707..8c4b2d2 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -95,6 +95,7 @@ public: QRectF sceneRect; bool hasSceneRect; + bool dirtyGrowingItemsBoundingRect; QRectF growingItemsBoundingRect; void _q_emitUpdated(); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 72636b8..aeee982 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -122,7 +122,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() if (!indexTimerId) return; - QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); q->killTimer(indexTimerId); indexTimerId = 0; @@ -144,10 +143,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() } } - // Update growing scene rect. - QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; - scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; - // Determine whether we should regenerate the BSP tree. if (bspTreeDepth == 0) { int oldDepth = intmaxlog(lastItemCount); @@ -165,7 +160,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); unindexedItems = indexedItems; lastItemCount = indexedItems.size(); - q->scene()->update(); } // Insert all unindexed items into the tree. @@ -179,10 +173,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() } } unindexedItems.clear(); - - // Notify scene rect changes. - if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) - emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); } @@ -248,7 +238,7 @@ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stac { if (!item->d_ptr->children.isEmpty()) { QList childList = item->d_ptr->children; - qSort(childList.begin(), childList.end(), qt_closestLeaf); + qStableSort(childList.begin(), childList.end(), qt_closestLeaf); for (int i = 0; i < childList.size(); ++i) { QGraphicsItem *item = childList.at(i); if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) @@ -287,7 +277,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() topLevels << item; } - qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); + qStableSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); for (int i = 0; i < topLevels.size(); ++i) climbTree(topLevels.at(i), &stackingOrder); } @@ -379,15 +369,15 @@ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemLi { if (sortCacheEnabled) { if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); + qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); + qStableSort(itemList->begin(), itemList->end(), closestItemLast_withCache); } } else { if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); + qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); + qStableSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); } } } @@ -403,17 +393,6 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) /*! \reimp - Return the rect indexed by the BSP index. -*/ -QRectF QGraphicsSceneBspTreeIndex::indexedRect() const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->_q_updateIndex(); - return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; -} - -/*! - \reimp Clear the all the BSP index. */ void QGraphicsSceneBspTreeIndex::clear() @@ -705,10 +684,9 @@ void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) This method react to the \a rect change of the scene and reset the BSP tree index. */ -void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) +void QGraphicsSceneBspTreeIndex::sceneRectChanged() { Q_D(QGraphicsSceneBspTreeIndex); - d->sceneRect = rect; d->resetIndex(); } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 1e4234e..715b22f 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -82,7 +82,6 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect() const; QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; @@ -100,7 +99,7 @@ protected: void deleteItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); - void sceneRectChanged(const QRectF &rect); + void sceneRectChanged(); void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 8d7581f..4eaed2b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -56,6 +56,7 @@ \sa QGraphicsScene, QGraphicsView */ +#include "qdebug.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" @@ -131,14 +132,10 @@ public: keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); } } else { - QRectF sceneBrect = transform.mapRect(brect); - keep = sceneBrect.contains(scenePoint); - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath pointPath; - pointPath.addRect(QRectF(transform.inverted().map(scenePoint), QSizeF(1, 1))); - keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); - } + QRectF sceneBoundingRect = transform.mapRect(brect); + keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1))) && item->contains(transform.inverted().map(scenePoint)); } + return keep; } @@ -366,15 +363,6 @@ QGraphicsScene* QGraphicsSceneIndex::scene() const } /*! - Returns the indexed area for the index -*/ -QRectF QGraphicsSceneIndex::indexedRect() const -{ - Q_D(const QGraphicsSceneIndex); - return d->scene->d_func()->sceneRect; -} - -/*! \fn QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const @@ -613,9 +601,8 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) rectangle. \a rect is the new value of the scene rectangle. \sa QGraphicsScene::sceneRect() */ -void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) +void QGraphicsSceneIndex::sceneRectChanged() { - Q_UNUSED(rect); } QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 85a1140..60e9032 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -87,8 +87,6 @@ public: QGraphicsScene *scene() const; - virtual QRectF indexedRect() const; - virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; @@ -111,7 +109,7 @@ protected: virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); - virtual void sceneRectChanged(const QRectF &rect); + virtual void sceneRectChanged(); QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 88e0e6a..9463487 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -87,13 +87,7 @@ public: return m_items; } - virtual QRectF indexedRect() const - { return m_sceneRect; } - protected : - void sceneRectChanged(const QRectF &rect) - { m_sceneRect = rect; } - virtual void clear() { m_items.clear(); } @@ -104,7 +98,6 @@ protected : { m_items.removeOne(item); } private: - QRectF m_sceneRect; QList m_items; }; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index ec1746a..640f85b 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -802,13 +802,15 @@ void QGraphicsViewPrivate::processPendingUpdates() return; } + if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) + dirtyBoundingRect.adjust(-1, -1, 1, 1); + else + dirtyBoundingRect.adjust(-2, -2, 2, 2); + if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { - if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) - viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); - else - viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2)); + viewport->update((dirtyRegion + dirtyBoundingRect).boundingRect()); } else { - viewport->update(dirtyRegion); // Already adjusted in updateRect/Region. + viewport->update(dirtyRegion + dirtyBoundingRect); // Already adjusted in updateRect/Region. } dirtyBoundingRect = QRect(); @@ -2087,9 +2089,7 @@ QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const Q_D(const QGraphicsView); if (!d->scene) return 0; - // ### Use QGraphicsScene::itemAt() instead. - QList itemsAtPos = d->scene->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder, - viewportTransform()); + QList itemsAtPos = items(pos); return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first(); } diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 1d03ef1..1a7a076 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -271,28 +271,46 @@ void tst_QGraphicsScene::construction() void tst_QGraphicsScene::sceneRect() { QGraphicsScene scene; + QSignalSpy sceneRectChanged(&scene, SIGNAL(sceneRectChanged(QRectF))); QCOMPARE(scene.sceneRect(), QRectF()); + QCOMPARE(sceneRectChanged.count(), 0); QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10)); - qApp->processEvents(); item->setPos(-5, -5); - qApp->processEvents(); + QCOMPARE(sceneRectChanged.count(), 0); QCOMPARE(scene.itemAt(0, 0), item); QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0); + QCOMPARE(sceneRectChanged.count(), 0); + QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 10, 10)); + QCOMPARE(sceneRectChanged.count(), 1); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); + + item->setPos(0, 0); QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15)); + QCOMPARE(sceneRectChanged.count(), 2); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); scene.setSceneRect(-100, -100, 10, 10); + QCOMPARE(sceneRectChanged.count(), 3); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); QCOMPARE(scene.itemAt(0, 0), item); QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0); QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10)); + item->setPos(10, 10); + QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10)); + QCOMPARE(sceneRectChanged.count(), 3); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); scene.setSceneRect(QRectF()); - QCOMPARE(scene.itemAt(0, 0), item); - QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0); - QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15)); + QCOMPARE(scene.itemAt(10, 10), item); + QCOMPARE(scene.itemAt(20, 20), (QGraphicsItem *)0); + QCOMPARE(sceneRectChanged.count(), 4); + QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 25, 25)); + QCOMPARE(sceneRectChanged.count(), 5); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); } void tst_QGraphicsScene::itemIndexMethod() diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index c8c032a..02e4046 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -371,6 +371,7 @@ void tst_QGraphicsView::interactive() QCOMPARE(item->events.size(), 0); QPoint itemPoint = view.mapFromScene(item->scenePos()); + QVERIFY(view.itemAt(itemPoint)); for (int i = 0; i < 100; ++i) { -- cgit v0.12 From d39a62720ba67a0fa6e4e37519d22f14c7b7404e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Tue, 23 Jun 2009 14:35:30 +0200 Subject: Ensure that the BSP index returns all untransformable items. --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index aeee982..464fe8e 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -595,6 +595,8 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r for (int i = 0; i < rectItems.size(); ++i) rectItems.at(i)->d_func()->itemDiscovered = 0; + rectItems += d->untransformableItems; + d->sortItems(&rectItems, order, d->sortCacheEnabled); return rectItems; -- cgit v0.12 From b0f391ae8f2efc272be852f951403fa8e4a8f561 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Tue, 23 Jun 2009 16:57:32 +0200 Subject: Fix tst_QGraphicsItem::collidesWith_item autotest. Avoid unwanted recursion by keeping the sceneRect variable locally. The recursion happens if the call to sceneRect() lazily emits the sceneRectChanged() signal. --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 464fe8e..8861c7b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -157,7 +157,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() // Regenerate the tree. if (regenerateIndex) { regenerateIndex = false; - bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); + bsp.initialize(sceneRect, bspTreeDepth); unindexedItems = indexedItems; lastItemCount = indexedItems.size(); } @@ -689,6 +689,7 @@ void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) void QGraphicsSceneBspTreeIndex::sceneRectChanged() { Q_D(QGraphicsSceneBspTreeIndex); + d->sceneRect = d->scene->sceneRect(); d->resetIndex(); } -- cgit v0.12 From 4fb0f9d8d5275c21b3d16be1170b5e7d2ed77f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 14:36:03 +0200 Subject: Partially revert be79229e The change in processPendingUpdates was completely wrong and broke several auto-tests. --- src/gui/graphicsview/qgraphicsview.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 94547a5..e4decf9 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -802,15 +802,13 @@ void QGraphicsViewPrivate::processPendingUpdates() return; } - if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) - dirtyBoundingRect.adjust(-1, -1, 1, 1); - else - dirtyBoundingRect.adjust(-2, -2, 2, 2); - if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { - viewport->update((dirtyRegion + dirtyBoundingRect).boundingRect()); + if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) + viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); + else + viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2)); } else { - viewport->update(dirtyRegion + dirtyBoundingRect); // Already adjusted in updateRect/Region. + viewport->update(dirtyRegion); // Already adjusted in updateRect/Region. } dirtyBoundingRect = QRect(); -- cgit v0.12 From fe64e44b0dab0152101b4ec17a49305912415016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 14:42:16 +0200 Subject: Stabilize tst_QGraphicsView::moveItemWhileScrolling. --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 02e4046..65e066f 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3093,7 +3093,7 @@ void tst_QGraphicsView::moveItemWhileScrolling() #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&view); #endif - QTest::qWait(100); + QTest::qWait(200); view.lastPaintedRegion = QRegion(); view.horizontalScrollBar()->setValue(view.horizontalScrollBar()->value() + 10); -- cgit v0.12 From 93e3a72f56d4b9ab020c58a2a3fac79be5fe49eb Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 25 Jun 2009 16:15:01 +0200 Subject: Doc: Indicated that QCompleter::completionModel() returns a proxy model. Task-number: 256138 Reviewed-by: jasplin --- src/gui/util/qcompleter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index 3d25f13..f4adcea 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -1582,6 +1582,10 @@ QString QCompleter::currentCompletion() const that contains all the possible matches for the current completion prefix. The completion model is auto-updated to reflect the current completions. + \note The return value of this function is defined to be an QAbstractItemModel + purely for generality. This actual kind of model returned is an instance of an + QAbstractProxyModel subclass. + \sa completionPrefix, model() */ QAbstractItemModel *QCompleter::completionModel() const -- cgit v0.12 From 9dc1fc2d30205bb0bad12df4d3cb061f55f4f3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 16:42:10 +0200 Subject: Compile tst_QGrahicsSceneIndex after be79229e --- .../auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index d10f86d..ac21e20 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -56,8 +56,6 @@ public slots: void initTestCase(); private slots: - void sceneRect_data(); - void sceneRect(); void customIndex_data(); void customIndex(); void scatteredItems_data(); @@ -97,19 +95,6 @@ QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMe return index; } -void tst_QGraphicsSceneIndex::sceneRect_data() -{ - common_data(); -} - -void tst_QGraphicsSceneIndex::sceneRect() -{ - QGraphicsScene *scene = new QGraphicsScene(); - QGraphicsSceneIndex *index = new QGraphicsSceneBspTreeIndex(scene); - scene->setSceneRect(QRectF(0, 0, 2000, 2000)); - QCOMPARE(index->indexedRect(), QRectF(0, 0, 2000, 2000)); -} - void tst_QGraphicsSceneIndex::customIndex_data() { common_data(); -- cgit v0.12 From eab949e2ec8f820a54826c1a837c8c8de07814ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 11:31:04 +0200 Subject: Re-factor parts of the QGraphicsSceneBspTreeIndex. This patch adds better support for untransformable items and removes some redundant code. --- src/gui/graphicsview/qgraphicsscene.cpp | 22 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 282 +++++++++------------ .../graphicsview/qgraphicsscenebsptreeindex_p.h | 6 +- 3 files changed, 133 insertions(+), 177 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 06a251e..6efede2 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1954,25 +1954,13 @@ void QGraphicsScene::clearSelection() void QGraphicsScene::clear() { Q_D(QGraphicsScene); - QList items = d->index->items(); -#if 1 - QList toDelete; - // ### As the item list is already in ascending order, - // the items should be deleted in topological order. - // Recursive descent delete - for (int i = 0; i < items.size(); ++i) { - if (QGraphicsItem *item = items.at(i)) { - if (!item->parentItem()) - toDelete << item; - } - } - // We delete all top level items - qDeleteAll(toDelete); -#else + // NB! We have to clear the index before deleting items; otherwise the + // index might try to access dangling item pointers. + d->index->clear(); + const QList items = d->topLevelItems; qDeleteAll(items); -#endif + Q_ASSERT(d->topLevelItems.isEmpty()); d->lastItemCount = 0; - d->index->clear(); d->allItemsIgnoreHoverEvents = true; d->allItemsUseDefaultCursor = true; } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 8861c7b..f6994f9 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -128,10 +128,9 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() purgeRemovedItems(); // Add unindexedItems to indexedItems - QRectF unindexedItemsBoundingRect; for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); + item->d_ptr->itemDiscovered = 0; if (!freeItemIndexes.isEmpty()) { int freeIndex = freeItemIndexes.takeFirst(); item->d_func()->index = freeIndex; @@ -165,11 +164,14 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() // Insert all unindexed items into the tree. for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { - QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->itemIsUntransformable()) { + untransformableItems << item; + continue; + } if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) continue; - bsp.insertItem(item, rect); + bsp.insertItem(item, item->sceneBoundingRect()); } } unindexedItems.clear(); @@ -222,11 +224,13 @@ void QGraphicsSceneBspTreeIndexPrivate::resetIndex() for (int i = 0; i < indexedItems.size(); ++i) { if (QGraphicsItem *item = indexedItems.at(i)) { item->d_ptr->index = -1; + item->d_ptr->itemDiscovered = 0; unindexedItems << item; } } indexedItems.clear(); freeItemIndexes.clear(); + untransformableItems.clear(); regenerateIndex = true; startIndexTimer(); } @@ -270,10 +274,10 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() int stackingOrder = 0; QList topLevels; - - for (int i = 0; i < q->items().count(); ++i) { - QGraphicsItem *item = q->items().at(i); - if (item && item->parentItem() == 0) + const QList items = q->items(); + for (int i = 0; i < items.size(); ++i) { + QGraphicsItem *item = items.at(i); + if (item && !item->d_ptr->parent) topLevels << item; } @@ -295,6 +299,79 @@ void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); } +void QGraphicsSceneBspTreeIndexPrivate::addItem(QGraphicsItem *item, bool recursive) +{ + if (!item) + return; + + // Prevent reusing a recently deleted pointer: purge all removed item from our lists. + purgeRemovedItems(); + + // Invalidate any sort caching; arrival of a new item means we need to resort. + // Update the scene's sort cache settings. + item->d_ptr->globalStackingOrder = -1; + invalidateSortCache(); + + // Indexing requires sceneBoundingRect(), but because \a item might + // not be completely constructed at this point, we need to store it in + // a temporary list and schedule an indexing for later. + if (item->d_ptr->index == -1) { + Q_ASSERT(!unindexedItems.contains(item)); + unindexedItems << item; + startIndexTimer(0); + } else { + Q_ASSERT(indexedItems.contains(item)); + qWarning("QGraphicsSceneBspTreeIndex::addItem: item has already been added to this BSP"); + } + + if (recursive) { + for (int i = 0; i < item->d_ptr->children.size(); ++i) + addItem(item->d_ptr->children.at(i), recursive); + } +} + +void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool recursive, + bool moveToUnindexedItems) +{ + if (!item) + return; + + if (item->d_ptr->index != -1) { + Q_ASSERT(item->d_ptr->index < indexedItems.size()); + Q_ASSERT(indexedItems.at(item->d_ptr->index) == item); + freeItemIndexes << item->d_ptr->index; + indexedItems[item->d_ptr->index] = 0; + item->d_ptr->index = -1; + item->d_ptr->itemDiscovered = 0; + + if (item->d_ptr->itemIsUntransformable()) { + untransformableItems.removeOne(item); + } else if (item->d_ptr->inDestructor) { + // Avoid virtual function calls from the destructor. + purgePending = true; + removedItems << item; + } else if (!item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + bsp.removeItem(item, item->sceneBoundingRect()); + } + } else { + unindexedItems.removeOne(item); + } + invalidateSortCache(); // ### Only do this when removing from BSP? + + Q_ASSERT(item->d_ptr->index == -1); + Q_ASSERT(!indexedItems.contains(item)); + Q_ASSERT(!unindexedItems.contains(item)); + Q_ASSERT(!untransformableItems.contains(item)); + + if (moveToUnindexedItems) + addItem(item); + + if (recursive) { + for (int i = 0; i < item->d_ptr->children.size(); ++i) + removeItem(item->d_ptr->children.at(i), recursive, moveToUnindexedItems); + } +} + /*! Returns true if \a item1 is on top of \a item2. @@ -401,8 +478,16 @@ void QGraphicsSceneBspTreeIndex::clear() d->bsp.clear(); d->lastItemCount = 0; d->freeItemIndexes.clear(); + for (int i = 0; i < d->indexedItems.size(); ++i) { + // Ensure item bits are reset properly. + if (QGraphicsItem *item = d->indexedItems.at(i)) { + item->d_ptr->index = -1; + item->d_ptr->itemDiscovered = 0; + } + } d->indexedItems.clear(); d->unindexedItems.clear(); + d->untransformableItems.clear(); } /*! @@ -411,46 +496,7 @@ void QGraphicsSceneBspTreeIndex::clear() void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); - // Prevent reusing a recently deleted pointer: purge all removed items - // from our lists. - d->purgeRemovedItems(); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - // Update the scene's sort cache settings. - item->d_ptr->globalStackingOrder = -1; - d->invalidateSortCache(); - - // Indexing requires sceneBoundingRect(), but because \a item might - // not be completely constructed at this point, we need to store it in - // a temporary list and schedule an indexing for later. - item->d_ptr->index = -1; - if (item->d_ptr->itemIsUntransformable()) { - d->untransformableItems << item; - } else { - d->unindexedItems << item; - d->startIndexTimer(0); - } -} - -/*! - This really add the item in the BSP. - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::addToBspTree(QGraphicsItem *item) -{ - if (item->d_ptr->itemIsUntransformable()) - return; - if (item->d_func()->index != -1) { - bsp.insertItem(item, item->sceneBoundingRect()); - foreach (QGraphicsItem *child, item->children()) - child->addToIndex(); - } else { - // The BSP tree is regenerated if the number of items grows to a - // certain threshold, or if the bounding rect of the graph doubles in - // size. - startIndexTimer(); - } + d->addItem(item); } /*! @@ -459,105 +505,28 @@ void QGraphicsSceneBspTreeIndexPrivate::addToBspTree(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); - - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromBspTree(item); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - // Remove from our item lists. - int index = item->d_func()->index; - if (index != -1) { - d->freeItemIndexes << index; - d->indexedItems[index] = 0; - } else { - if (item->d_ptr->itemIsUntransformable()) - d->untransformableItems.removeOne(item); - else - d->unindexedItems.removeOne(item); - } + d->removeItem(item); } /*! \reimp - Delete the \a item from the BSP index (without accessing its boundingRect). -*/ -void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - int index = item->d_func()->index; - if (index != -1) { - // Important: The index is useless until purgeRemovedItems() is - // called. - d->indexedItems[index] = (QGraphicsItem *)0; - if (!d->purgePending) { - d->purgePending = true; - scene()->update(); - } - d->removedItems << item; - } else { - // Recently added items are purged immediately. unindexedItems() never - // contains stale items. - if (item->d_ptr->itemIsUntransformable()) - d->untransformableItems.removeOne(item); - else - d->unindexedItems.removeOne(item); - scene()->update(); - } -} - -/*! - Really remove the item from the BSP - \internal + Update the BSP when the \a item 's bounding rect has changed. */ -void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { - if (item->d_ptr->itemIsUntransformable()) + if (!item) return; - if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - // ### remove from child index only if applicable - return; + if (item->d_ptr->index == -1 || item->d_ptr->itemIsUntransformable() + || item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + return; // Item is not in BSP tree; nothing to do. } - if (item->d_func()->index != -1) { - bsp.removeItem(item, item->sceneBoundingRect()); - //prepareGeometryChange will call prepareBoundingRectChange - foreach (QGraphicsItem *child, item->children()) - child->prepareGeometryChange(); - } - startIndexTimer(); -} - -/*! - \reimp - Update the BSP when the \a item 's bounding rect has changed. -*/ -void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) -{ Q_D(QGraphicsSceneBspTreeIndex); - if (!item->d_ptr->itemIsUntransformable()) { - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - QGraphicsItem *thatItem = const_cast(item); - d->removeFromBspTree(thatItem); - int index = item->d_func()->index; - if (index != -1) { - d->freeItemIndexes << index; - d->indexedItems[index] = 0; - thatItem->d_func()->index = -1; - d->unindexedItems << thatItem; - } - } + QGraphicsItem *thatItem = const_cast(item); + d->removeItem(thatItem, /*recursive=*/false, /*moveToUnindexedItems=*/true); + for (int i = 0; i < item->d_ptr->children.size(); ++i) // ### Do we really need this? + prepareBoundingRectChange(item->d_ptr->children.at(i)); } /*! @@ -706,18 +675,17 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics switch (change) { case QGraphicsItem::ItemFlagsChange: { // Handle ItemIgnoresTransformations - bool ignoredTransform = item->flags() & QGraphicsItem::ItemIgnoresTransformations; + bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations; bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations; - if (ignoredTransform != willIgnoreTransform) { + bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; + bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape; + if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) { QGraphicsItem *thatItem = const_cast(item); - removeItem(thatItem); - thatItem->d_ptr->index = -1; - if (willIgnoreTransform) { - d->untransformableItems << thatItem; - } else { - d->unindexedItems << thatItem; - d->startIndexTimer(0); - } + // Remove item and its descendants from the index and append + // them to the list of unindexed items. Then, when the index + // is updated, they will be put into the bsp-tree or the list + // of untransformable items. + d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true); } break; } @@ -729,17 +697,19 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics // Handle ItemIgnoresTransformations QGraphicsItem *newParent = qVariantValue(value); bool ignoredTransform = item->d_ptr->itemIsUntransformable(); - bool willIgnoreTransform = (item->flags() & QGraphicsItem::ItemIgnoresTransformations) || (newParent && newParent->d_ptr->itemIsUntransformable()); - if (ignoredTransform != willIgnoreTransform) { + bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations) + || (newParent && newParent->d_ptr->itemIsUntransformable()); + bool ancestorClippedChildren = item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren; + bool ancestorWillClipChildren = newParent + && ((newParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) + || (newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)); + if ((ignoredTransform != willIgnoreTransform) || (ancestorClippedChildren != ancestorWillClipChildren)) { QGraphicsItem *thatItem = const_cast(item); - removeItem(thatItem); - thatItem->d_ptr->index = -1; - if (willIgnoreTransform) { - d->untransformableItems << thatItem; - } else { - d->unindexedItems << thatItem; - d->startIndexTimer(0); - } + // Remove item and its descendants from the index and append + // them to the list of unindexed items. Then, when the index + // is updated, they will be put into the bsp-tree or the list + // of untransformable items. + d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true); } break; } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 715b22f..f2f958f 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -96,7 +96,6 @@ protected: void addItem(QGraphicsItem *item); void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); void sceneRectChanged(); @@ -139,13 +138,12 @@ public: void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); void resetIndex(); - void addToBspTree(QGraphicsItem *item); - void removeFromBspTree(QGraphicsItem *item); - void _q_updateSortCache(); bool sortCacheEnabled; bool updatingSortCache; void invalidateSortCache(); + void addItem(QGraphicsItem *item, bool recursive = false); + void removeItem(QGraphicsItem *item, bool recursive = false, bool moveToUnindexedItems = false); static void climbTree(QGraphicsItem *item, int *stackingOrder); static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); -- cgit v0.12 From 7541247a025bf112716a752bc4d114303f2a77f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 26 Jun 2009 15:54:04 +0200 Subject: Proper handling of scene rect in QGraphicsScene(Index). Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + src/gui/graphicsview/qgraphicsitem_p.h | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 65 +++++++++------------- src/gui/graphicsview/qgraphicsscene.h | 1 - src/gui/graphicsview/qgraphicsscene_p.h | 1 - .../graphicsview/qgraphicsscenebsptreeindex.cpp | 4 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 4 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 25 ++++++--- src/gui/graphicsview/qgraphicssceneindex_p.h | 4 +- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 6 -- 10 files changed, 52 insertions(+), 61 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7393f00..e9d1076 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -6322,6 +6322,7 @@ void QGraphicsItem::removeFromIndex() void QGraphicsItem::prepareGeometryChange() { if (d_ptr->scene) { + d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true; d_ptr->geometryChanged = 1; d_ptr->paintedViewBoundingRectsNeedRepaint = 1; diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 1dfb140..243582a 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -148,7 +148,7 @@ public: dirtyChildrenBoundingRect(1), paintedViewBoundingRectsNeedRepaint(0), dirtySceneTransform(1), - geometryChanged(0), + geometryChanged(1), inDestructor(0), isObject(0), ignoreVisible(0), diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 6efede2..de6f5c4 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -326,6 +326,16 @@ void QGraphicsScenePrivate::_q_emitUpdated() Q_Q(QGraphicsScene); calledEmitUpdated = false; + if (dirtyGrowingItemsBoundingRect) { + if (!hasSceneRect) { + const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; + growingItemsBoundingRect |= q->itemsBoundingRect(); + if (oldGrowingItemsBoundingRect != growingItemsBoundingRect) + emit q->sceneRectChanged(growingItemsBoundingRect); + } + dirtyGrowingItemsBoundingRect = false; + } + // Ensure all views are connected if anything is connected. This disables // the optimization that items send updates directly to the views, but it // needs to happen in order to keep compatibility with the behavior from @@ -373,20 +383,6 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) /*! \internal - - Updates all items in the pending update list. At this point, the list is - unlikely to contain partially constructed items. -*/ -void QGraphicsScenePrivate::_q_updateLater() -{ - QRectF null; - foreach (QGraphicsItem *item, pendingUpdateItems) - markDirty(item, null); - pendingUpdateItems.clear(); -} - -/*! - \internal */ void QGraphicsScenePrivate::_q_polishItems() { @@ -412,10 +408,8 @@ void QGraphicsScenePrivate::_q_processDirtyItems() const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; processDirtyItemsRecursive(0); dirtyGrowingItemsBoundingRect = false; - if (oldGrowingItemsBoundingRect != growingItemsBoundingRect) { - index->sceneRectChanged(); + if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect) emit q_func()->sceneRectChanged(growingItemsBoundingRect); - } if (wasPendingSceneUpdate) return; @@ -507,7 +501,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) hoverItems.removeAll(item); cachedItemsUnderMouse.removeAll(item); unpolishedItems.removeAll(item); - pendingUpdateItems.removeAll(item); resetDirtyItem(item); //We remove all references of item from the sceneEventFilter arrays @@ -1303,18 +1296,19 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - if (!d->hasSceneRect && d->dirtyGrowingItemsBoundingRect) { + if (d->hasSceneRect) + return d->sceneRect; + + if (d->dirtyGrowingItemsBoundingRect) { // Lazily update the growing items bounding rect QGraphicsScenePrivate *thatd = const_cast(d); QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect; thatd->growingItemsBoundingRect |= itemsBoundingRect(); thatd->dirtyGrowingItemsBoundingRect = false; - if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect) { - thatd->index->sceneRectChanged(); + if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect) emit const_cast(this)->sceneRectChanged(thatd->growingItemsBoundingRect); - } } - return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; + return d->growingItemsBoundingRect; } void QGraphicsScene::setSceneRect(const QRectF &rect) { @@ -1322,7 +1316,6 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) if (rect != d->sceneRect) { d->hasSceneRect = !rect.isNull(); d->sceneRect = rect; - d->index->sceneRectChanged(); emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect); } } @@ -2101,13 +2094,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Add to list of items that require an update. We cannot assume that the // item is fully constructed, so calling item->update() can lead to a pure // virtual function call to boundingRect(). - if (!d->updateAll) { - if (d->pendingUpdateItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_updateLater", Qt::QueuedConnection); - d->pendingUpdateItems << item; - } else { - d->dirtyGrowingItemsBoundingRect = true; - } + d->markDirty(item); + d->dirtyGrowingItemsBoundingRect = true; // Disable selectionChanged() for individual items ++d->selectionChanging; @@ -4245,7 +4233,6 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b bool removingItemFromScene) { Q_ASSERT(item); - dirtyGrowingItemsBoundingRect = true; if (updateAll) return; @@ -4351,6 +4338,13 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool item->d_ptr->dirty = 0; item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; } + + if (item->d_ptr->geometryChanged) { + // Update growingItemsBoundingRect. + if (!hasSceneRect && !itemIsHidden) + growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); + item->d_ptr->geometryChanged = 0; + } } // Process item. @@ -4359,13 +4353,6 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool const bool untransformableItem = item->d_ptr->itemIsUntransformable(); const QRectF itemBoundingRect = adjustedItemBoundingRect(item); - if (item->d_ptr->geometryChanged) { - // Update growingItemsBoundingRect. - if (!hasSceneRect) - growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(itemBoundingRect); - item->d_ptr->geometryChanged = 0; - } - if (useCompatUpdate && !untransformableItem && qFuzzyIsNull(item->boundingRegionGranularity())) { // This block of code is kept for compatibility. Since 4.5, by default // QGraphicsView does not connect the signal and we use the below diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 421adbd..560671a 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -291,7 +291,6 @@ private: Q_DECLARE_PRIVATE(QGraphicsScene) Q_DISABLE_COPY(QGraphicsScene) Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated()) - Q_PRIVATE_SLOT(d_func(), void _q_updateLater()) Q_PRIVATE_SLOT(d_func(), void _q_polishItems()) Q_PRIVATE_SLOT(d_func(), void _q_processDirtyItems()) friend class QGraphicsItem; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 36a7e63..f286a8d 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -107,7 +107,6 @@ public: QPainterPath selectionArea; int selectionChanging; QSet selectedItems; - QList pendingUpdateItems; QList unpolishedItems; QList topLevelItems; bool needSortTopLevelItems; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index f6994f9..3efc742 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -655,10 +655,10 @@ void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) This method react to the \a rect change of the scene and reset the BSP tree index. */ -void QGraphicsSceneBspTreeIndex::sceneRectChanged() +void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect) { Q_D(QGraphicsSceneBspTreeIndex); - d->sceneRect = d->scene->sceneRect(); + d->sceneRect = rect; d->resetIndex(); } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index f2f958f..850cc3f 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -90,6 +90,9 @@ public: int bspTreeDepth(); void setBspTreeDepth(int depth); +protected Q_SLOTS: + void updateSceneRect(const QRectF &rect); + protected: bool event(QEvent *event); void clear(); @@ -98,7 +101,6 @@ protected: void removeItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); - void sceneRectChanged(); void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 4eaed2b..88fb6b0 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -335,6 +335,10 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) : QObject(*new QGraphicsSceneIndexPrivate(scene), scene) { + if (scene) { + connect(scene, SIGNAL(sceneRectChanged(const QRectF&)), + this, SLOT(updateSceneRect(const QRectF&))); + } } /*! @@ -527,6 +531,18 @@ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, \a order. */ + +/*! + Notifies the index that the scene's scene rect has changed. \a rect + is thew new scene rect. + + \sa QGraphicsScene::sceneRect() +*/ +void QGraphicsSceneIndex::updateSceneRect(const QRectF &rect) +{ + Q_UNUSED(rect); +} + /*! This virtual function removes all items in the scene index. */ @@ -596,15 +612,6 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) Q_UNUSED(item); } -/*! - This virtual function is called when the scene changes its bounding - rectangle. \a rect is the new value of the scene rectangle. - \sa QGraphicsScene::sceneRect() -*/ -void QGraphicsSceneIndex::sceneRectChanged() -{ -} - QT_END_NAMESPACE #include "moc_qgraphicssceneindex_p.cpp" diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 60e9032..dc6a740 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -101,6 +101,9 @@ public: virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0; +protected Q_SLOTS: + virtual void updateSceneRect(const QRectF &rect); + protected: virtual void clear(); virtual void addItem(QGraphicsItem *item) = 0; @@ -109,7 +112,6 @@ protected: virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); - virtual void sceneRectChanged(); QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp index 694062b..bc401f2 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -46,12 +46,6 @@ */ /*! - \fn void QGraphicsSceneLinearIndex::sceneRectChanged(const QRectF &rect); - \reimp - This method react to the \a rect change of the scene. -*/ - -/*! \fn void QGraphicsSceneLinearIndex::clear(); \reimp Clear the all the BSP index. -- cgit v0.12 From eff4c4b4172d1a95b1b5806622b4e7fe43c2b006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 26 Jun 2009 16:32:27 +0200 Subject: Fix broken point item lookup in Graphics View. Done with Andreas. --- src/gui/graphicsview/qgraphicsscene.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index de6f5c4..7c46598 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -770,11 +770,22 @@ QList QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre const QPointF &scenePos, QWidget *widget) const { - Q_UNUSED(screenPos); Q_Q(const QGraphicsScene); QGraphicsView *view = widget ? qobject_cast(widget->parentWidget()) : 0; - return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, - view ? view->viewportTransform() : QTransform()); + if (!view) + return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, QTransform()); + + const QRectF pointRect(QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1)); + if (!view->isTransformed()) + return q->items(pointRect, Qt::IntersectsItemShape, Qt::AscendingOrder); + + const QTransform viewTransform = view->viewportTransform(); + if (viewTransform.type() <= QTransform::TxScale) { + return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape, + Qt::AscendingOrder, viewTransform); + } + return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape, + Qt::AscendingOrder, viewTransform); } /*! -- cgit v0.12 From 7fe4f8ff71cf09bbabbd3438ef637fe408a11c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 29 Jun 2009 15:33:30 +0200 Subject: Graphics View: BSP tree cleanup. Ensure the BSP resets the QGraphicsItemPrivate::itemDiscovered bit before returning the list of discovered items. --- src/gui/graphicsview/qgraphicsitem.h | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 7 +++++-- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 11 ++++++++--- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 21 ++++++++------------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 12dcad2..48fb5c3 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -434,6 +434,7 @@ private: friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QGraphicsSceneFindItemBspTreeVisitor; + friend class QGraphicsSceneBspTree; friend class QGraphicsView; friend class QGraphicsViewPrivate; friend class QGraphicsWidget; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 7c46598..f1e56c1 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1097,8 +1097,11 @@ QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), viewTransform ? *viewTransform : QTransform()); - for (int i = 0; i < tmp.size(); ++i) - tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; + for (int i = 0; i < tmp.size(); ++i) { + QGraphicsItem *item = tmp.at(i); + if (!item->d_ptr->parent) + item->d_ptr->itemDiscovered = 1; + } // Sort if the toplevel list is unsorted. if (needSortTopLevelItems) { diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index eaeec54..5858eab 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -148,6 +148,9 @@ QList QGraphicsSceneBspTree::items(const QRectF &rect) const QList tmp; findVisitor->foundItems = &tmp; climbTree(findVisitor, rect); + // Reset discovery bits. + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->d_ptr->itemDiscovered = 0; return tmp; } @@ -156,6 +159,9 @@ QList QGraphicsSceneBspTree::items(const QPointF &pos) const QList tmp; findVisitor->foundItems = &tmp; climbTree(findVisitor, pos); + // Reset discovery bits. + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->d_ptr->itemDiscovered = 0; return tmp; } @@ -241,7 +247,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con return; const Node &node = nodes.at(index); - int childIndex = firstChildIndex(index); + const int childIndex = firstChildIndex(index); switch (node.type) { case Node::Leaf: { @@ -271,7 +277,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con return; const Node &node = nodes.at(index); - int childIndex = firstChildIndex(index); + const int childIndex = firstChildIndex(index); switch (node.type) { case Node::Leaf: { @@ -288,7 +294,6 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con } break; case Node::Horizontal: - int childIndex = firstChildIndex(index); if (rect.top() < node.offset) { climbTree(visitor, rect, childIndex); if (rect.bottom() >= node.offset) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 3efc742..44a0082 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -130,7 +130,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() // Add unindexedItems to indexedItems for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { - item->d_ptr->itemDiscovered = 0; + Q_ASSERT(!item->d_ptr->itemDiscovered); if (!freeItemIndexes.isEmpty()) { int freeIndex = freeItemIndexes.takeFirst(); item->d_func()->index = freeIndex; @@ -224,7 +224,7 @@ void QGraphicsSceneBspTreeIndexPrivate::resetIndex() for (int i = 0; i < indexedItems.size(); ++i) { if (QGraphicsItem *item = indexedItems.at(i)) { item->d_ptr->index = -1; - item->d_ptr->itemDiscovered = 0; + Q_ASSERT(!item->d_ptr->itemDiscovered); unindexedItems << item; } } @@ -339,10 +339,10 @@ void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool rec if (item->d_ptr->index != -1) { Q_ASSERT(item->d_ptr->index < indexedItems.size()); Q_ASSERT(indexedItems.at(item->d_ptr->index) == item); + Q_ASSERT(!item->d_ptr->itemDiscovered); freeItemIndexes << item->d_ptr->index; indexedItems[item->d_ptr->index] = 0; item->d_ptr->index = -1; - item->d_ptr->itemDiscovered = 0; if (item->d_ptr->itemIsUntransformable()) { untransformableItems.removeOne(item); @@ -481,8 +481,8 @@ void QGraphicsSceneBspTreeIndex::clear() for (int i = 0; i < d->indexedItems.size(); ++i) { // Ensure item bits are reset properly. if (QGraphicsItem *item = d->indexedItems.at(i)) { + Q_ASSERT(!item->d_ptr->itemDiscovered); item->d_ptr->index = -1; - item->d_ptr->itemDiscovered = 0; } } d->indexedItems.clear(); @@ -547,25 +547,20 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r Q_UNUSED(deviceTransform); QList rectItems = d->bsp.items(rect); + // Fill in with any unindexed items for (int i = 0; i < d->unindexedItems.size(); ++i) { if (QGraphicsItem *item = d->unindexedItems.at(i)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { + if (item->d_ptr->visible + && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { QRectF boundingRect = item->sceneBoundingRect(); - if (QRectF_intersects(boundingRect, rect)) { - item->d_ptr->itemDiscovered = 1; + if (QRectF_intersects(boundingRect, rect)) rectItems << item; - } } } } - // Reset the discovered state of all discovered items - for (int i = 0; i < rectItems.size(); ++i) - rectItems.at(i)->d_func()->itemDiscovered = 0; - rectItems += d->untransformableItems; - d->sortItems(&rectItems, order, d->sortCacheEnabled); return rectItems; -- cgit v0.12 From 4dcb46a3796fbd9baf1ba6dcddcc9944e69e3153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 29 Jun 2009 15:44:11 +0200 Subject: Add lacking parenthesis around bitwise AND operator. This caused a crash in the diagramscene example because "!bits & something" does not have the same meaning as "!(bits & something)", hence item was never removed from the BSP resulting in a stale item pointer. --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 44a0082..413c8de 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -350,7 +350,7 @@ void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool rec // Avoid virtual function calls from the destructor. purgePending = true; removedItems << item; - } else if (!item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + } else if (!(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { bsp.removeItem(item, item->sceneBoundingRect()); } } else { @@ -518,7 +518,7 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * return; if (item->d_ptr->index == -1 || item->d_ptr->itemIsUntransformable() - || item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + || (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { return; // Item is not in BSP tree; nothing to do. } -- cgit v0.12 From 6ee3fb750377eeedf161d96fef02c5fa336810e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 13:00:32 +0200 Subject: More re-factoring of QGraphicsSceneIndex. Mostly re-factoring of QGraphicsSceneIndexPrivate::recursive_items_helper so it can re-use code from the scene (topLevelItemsInStackingOrder). That also means we'll use the bsp tree in case of NoIndex instead of always looping through the top-levels. This function is now almost identical to QGraphicsScenePrivate::drawSubtreeRecursive, so it might be worth looking into how we can abstract it even more and have one common recursive function. --- src/gui/graphicsview/qgraphicsscene.cpp | 20 +--- src/gui/graphicsview/qgraphicsscene_p.h | 11 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 12 +-- src/gui/graphicsview/qgraphicssceneindex.cpp | 115 ++++++++------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 34 ++++-- 5 files changed, 89 insertions(+), 103 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f1e56c1..faacf4d 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -217,8 +217,9 @@ #include "qgraphicsview_p.h" #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" -#include -#include +#include "qgraphicssceneindex_p.h" +#include "qgraphicsscenebsptreeindex_p.h" +#include "qgraphicsscenelinearindex_p.h" #include #include @@ -243,7 +244,6 @@ #include #include #include -#include #include #ifdef Q_WS_X11 #include @@ -1075,9 +1075,9 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) } QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QTransform *const viewTransform, - QRegion *exposedRegion) + const QRectF &sceneRect) { - if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) { + if (indexMethod == QGraphicsScene::NoIndex || sceneRect.isNull()) { if (needSortTopLevelItems) { needSortTopLevelItems = false; qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); @@ -1085,16 +1085,6 @@ QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const return topLevelItems; } - const QRectF exposedRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); - QRectF sceneRect; - QTransform invertedViewTransform(Qt::Uninitialized); - if (!viewTransform) { - sceneRect = exposedRect; - } else { - invertedViewTransform = viewTransform->inverted(); - sceneRect = invertedViewTransform.mapRect(exposedRect); - } - QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), viewTransform ? *viewTransform : QTransform()); for (int i = 0; i < tmp.size(); ++i) { diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index f286a8d..b3d7535 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -57,7 +57,6 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -#include "qgraphicsscenebsptreeindex_p.h" #include "qgraphicsview.h" #include "qgraphicsitem_p.h" @@ -187,7 +186,7 @@ public: QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; bool sortCacheEnabled; // for compatibility - QList topLevelItemsInStackingOrder(const QTransform *const, QRegion *); + QList topLevelItemsInStackingOrder(const QTransform *const, const QRectF&); void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, @@ -196,7 +195,13 @@ public: inline void drawItems(QPainter *painter, const QTransform *const viewTransform, QRegion *exposedRegion, QWidget *widget) { - const QList tli = topLevelItemsInStackingOrder(viewTransform, exposedRegion); + QRectF exposedSceneRect; + if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) { + exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); + if (viewTransform) + exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect); + } + const QList tli = topLevelItemsInStackingOrder(viewTransform, exposedSceneRect); for (int i = 0; i < tli.size(); ++i) drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget); return; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 850cc3f..90cc8c3 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -39,8 +39,6 @@ ** ****************************************************************************/ -#include - // // W A R N I N G // ------------- @@ -63,13 +61,13 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW +#include "qgraphicssceneindex_p.h" +#include "qgraphicsitem_p.h" +#include "qgraphicsscene_bsp_p.h" + +#include #include #include -#include -#include -#include -#include -#include static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 88fb6b0..a42dc54 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -61,7 +61,8 @@ #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" #include "qgraphicswidget.h" -#include +#include "qgraphicssceneindex_p.h" +#include "qgraphicsscenebsptreeindex_p.h" #ifndef QT_NO_GRAPHICSVIEW @@ -240,91 +241,64 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity) const { - // Calculate opacity. - qreal opacity; - if (item) { - if (!item->d_ptr->visible) - return; + Q_ASSERT(item); + if (!item->d_ptr->visible) + return; - QGraphicsItem *p = item->d_ptr->parent; - bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; - bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); - if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) { - opacity = parentOpacity * item->opacity(); - } else { - opacity = item->d_ptr->opacity; - } - if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) - return; - } else { - opacity = parentOpacity; - } + const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); + const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemHasChildren = !item->d_ptr->children.isEmpty(); + if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) + return; // Calculate the full transform for this item. - QTransform transform = parentTransform; - bool keep = false; - if (item) { - item->d_ptr->combineTransformFromParent(&transform, &viewTransform); - - // ### This does not take the clip into account. - QRectF brect = item->boundingRect(); - _q_adjustRect(&brect); - - //We fill the intersector with needed informations - keep = intersector->intersect(item, exposeRect, mode, transform, viewTransform); - } - - bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); - bool dontProcessItem = !item || !keep; - bool dontProcessChildren = item && dontProcessItem && childClip; + QTransform transform(parentTransform); + item->d_ptr->combineTransformFromParent(&transform, &viewTransform); + + const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + bool processItem = !itemIsFullyTransparent; + if (processItem) { + processItem = intersector->intersect(item, exposeRect, mode, transform, viewTransform); + if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) + return; + } // else we know for sure this item has children we must process. - // Find and sort children. - QList &children = item ? item->d_ptr->children : const_cast(scene->d_func())->topLevelItems; - if (!dontProcessChildren) { - if (item && item->d_ptr->needSortChildren) { + int i = 0; + if (itemHasChildren) { + // Sort children. + if (item->d_ptr->needSortChildren) { item->d_ptr->needSortChildren = 0; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); - } else if (!item && scene->d_func()->needSortTopLevelItems) { - const_cast(scene->d_func())->needSortTopLevelItems = false; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); + qStableSort(item->d_ptr->children.begin(), item->d_ptr->children.end(), qt_notclosestLeaf); } - } - - childClip &= !dontProcessChildren & !children.isEmpty(); - // Clip. - if (childClip) - exposeRect &= transform.map(item->shape()).controlPointRect(); + // Clip to shape. + if (itemClipsChildrenToShape) + exposeRect &= transform.map(item->shape()).controlPointRect(); - // Process children behind - int i = 0; - if (!dontProcessChildren) { - for (i = 0; i < children.size(); ++i) { - QGraphicsItem *child = children.at(i); + // Process children behind + for (i = 0; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); } } // Process item - if (!dontProcessItem) + if (processItem) items->append(item); // Process children in front - if (!dontProcessChildren) { - for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), exposeRect, intersector, items, transform, viewTransform, + if (itemHasChildren) { + for (; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); - } - - if (!item && order == Qt::AscendingOrder) { - int n = items->size(); - for (int i = 0; i < n / 2; ++i) { - QGraphicsItem *tmp = (*items)[n - i - 1]; - (*items)[n - i - 1] = (*items)[i]; - (*items)[i] = tmp; } } } @@ -393,8 +367,7 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe Q_D(const QGraphicsSceneIndex); QList itemList; d->pointIntersector->scenePoint = pos; - d->recursive_items_helper(0, QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, - QTransform(), deviceTransform, mode, order); + d->items_helper(QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, deviceTransform, mode, order); return itemList; } @@ -428,7 +401,7 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe _q_adjustRect(&exposeRect); QList itemList; d->rectIntersector->sceneRect = rect; - d->recursive_items_helper(0, exposeRect, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->items_helper(exposeRect, d->rectIntersector, &itemList, deviceTransform, mode, order); return itemList; } @@ -464,7 +437,7 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: QPainterPath path; path.addPolygon(polygon); d->pathIntersector->scenePath = path; - d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order); return itemList; } @@ -498,7 +471,7 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: QRectF exposeRect = path.controlPointRect(); _q_adjustRect(&exposeRect); d->pathIntersector->scenePath = path; - d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order); return itemList; } diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index dc6a740..122d7ae 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -53,11 +53,13 @@ // We mean it. // +#include "qgraphicsscene_p.h" +#include "qgraphicsscene.h" +#include + #include #include #include -#include -#include QT_BEGIN_HEADER @@ -67,7 +69,6 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -class QGraphicsScene; class QGraphicsSceneIndexIntersector; class QGraphicsSceneIndexPointIntersector; class QGraphicsSceneIndexRectIntersector; @@ -138,12 +139,31 @@ public: QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; - QGraphicsScene *scene; - QGraphicsSceneIndexPointIntersector *pointIntersector; - QGraphicsSceneIndexRectIntersector *rectIntersector; - QGraphicsSceneIndexPathIntersector *pathIntersector; + inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector, + QList *items, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order) const; + + QGraphicsScene *scene; + QGraphicsSceneIndexPointIntersector *pointIntersector; + QGraphicsSceneIndexRectIntersector *rectIntersector; + QGraphicsSceneIndexPathIntersector *pathIntersector; }; +inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector, + QList *items, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order) const +{ + const QList tli = scene->d_func()->topLevelItemsInStackingOrder(&viewTransform, rect); + const QTransform identity; + for (int i = 0; i < tli.size(); ++i) + recursive_items_helper(tli.at(i), rect, intersector, items, identity, viewTransform, mode, order); + if (order == Qt::AscendingOrder) { + const int n = items->size(); + for (int i = 0; i < n / 2; ++i) + items->swap(i, n - i - 1); + } +} + class QGraphicsSceneIndexIntersector { public: -- cgit v0.12 From 99bea47fd9b868fb22f175943c11ecb05b51f07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 15:54:19 +0200 Subject: Fix broken tst_QGraphicsView::embeddedViews. This test has been broken after 32f32ee3e752a6cc03505ddaa48d2849eaedc2a6, but the test continued to pass because another bug, which is fixed by 6ee3fb750377eeedf161d96fef02c5fa336810e9. The transform should be exactly the same in both cases. --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 65e066f..6db8f27 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -2989,14 +2989,7 @@ void tst_QGraphicsView::embeddedViews() v2->QWidget::render(&actual); QTransform b = item->transform; -#ifdef Q_WS_MAC - // We don't use shared painter on the Mac, so the - // transform should be exactly the same. QVERIFY(a == b); -#else - QVERIFY(a != b); -#endif - delete v1; } -- cgit v0.12 From 3a00930fe167e6db5588d9e93d429486f9591bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 16:15:28 +0200 Subject: More BSP tree index cleanup. Ensure the index of indexed items are reset to -1. Makes tst_QGraphicsScene::itemIndexMethod happy. (this test passed before we actually started using the BSP from the items() functions, see 6ee3fb750377eeedf161d96fef02c5fa336810e9) --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 12 ++++++++++++ src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 413c8de..ff9a3da 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -468,6 +468,18 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } +QGraphicsSceneBspTreeIndex::~QGraphicsSceneBspTreeIndex() +{ + Q_D(QGraphicsSceneBspTreeIndex); + for (int i = 0; i < d->indexedItems.size(); ++i) { + // Ensure item bits are reset properly. + if (QGraphicsItem *item = d->indexedItems.at(i)) { + Q_ASSERT(!item->d_ptr->itemDiscovered); + item->d_ptr->index = -1; + } + } +} + /*! \reimp Clear the all the BSP index. diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 90cc8c3..7b431e6 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -80,6 +80,7 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + ~QGraphicsSceneBspTreeIndex(); QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; -- cgit v0.12 From 53ef0b0f8b1227cff6ce4c9e2a91a6fbc7e7ee3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 16:19:25 +0200 Subject: Make QGraphicsSceneIndex::clear() less nasty. --- src/gui/graphicsview/qgraphicssceneindex.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index a42dc54..2f2f05e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -521,8 +521,9 @@ void QGraphicsSceneIndex::updateSceneRect(const QRectF &rect) */ void QGraphicsSceneIndex::clear() { - for (int i = 0 ; i < items().size(); ++i) - removeItem(items().at(i)); + const QList allItems = items(); + for (int i = 0 ; i < allItems.size(); ++i) + removeItem(allItems.at(i)); } /*! -- cgit v0.12 From a1d5b33bd33ecf1d809346a39d2386cafaf50cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 18:41:18 +0200 Subject: Partially revert 7fe4f8ff71cf09bbabbd3438ef637fe408a11c33 We have to ensure that the item's top-level is marked as discovered. This broke the dragandroprobot example after we started using the BSP from QGraphicsSceneIndex::items()* (see 6ee3fb750377eeedf161d96fef02c5fa336810e9) --- src/gui/graphicsview/qgraphicsscene.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index faacf4d..ed1d2f3 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1087,11 +1087,8 @@ QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), viewTransform ? *viewTransform : QTransform()); - for (int i = 0; i < tmp.size(); ++i) { - QGraphicsItem *item = tmp.at(i); - if (!item->d_ptr->parent) - item->d_ptr->itemDiscovered = 1; - } + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; // Sort if the toplevel list is unsorted. if (needSortTopLevelItems) { -- cgit v0.12 From b2d61c982e860a532f931dfaea143749927784a6 Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 1 Jul 2009 08:49:22 +1000 Subject: Don assume QVariant::String data is going to always be unicode in QODBC - as was not the case for the psqlODBC driver Reviewed-by: Bill King --- src/sql/drivers/odbc/qsql_odbc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 2bedf7f..e18a9eb 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -1006,7 +1006,7 @@ QVariant QODBCResult::data(int field) d->fieldCache[i] = qGetBinaryData(d->hStmt, i); break; case QVariant::String: - d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), true); + d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), d->unicode); break; case QVariant::Double: { -- cgit v0.12 From 70137e0601549af1056082cdfbb4f141c70befab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chusslove=20Illich=20=28=D0=A7=D0=B0=D1=81=D0=BB=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=98=D0=BB=D0=B8=D1=9B=29?= Date: Tue, 30 Jun 2009 23:29:02 +0200 Subject: operator==() for Unicode properties was omitting one property, which resulted in wrong choice of unique properties for characters 451-45f. Reviewed-By: Thiago Macieira Reviewed-By: Denis Dzyubenko --- util/unicode/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index cab6570..f1b4641 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -293,6 +293,7 @@ struct PropertyFlags { && lowerCaseDiff == o.lowerCaseDiff && upperCaseDiff == o.upperCaseDiff && titleCaseDiff == o.titleCaseDiff + && caseFoldDiff == o.caseFoldDiff && lowerCaseSpecial == o.lowerCaseSpecial && upperCaseSpecial == o.upperCaseSpecial && titleCaseSpecial == o.titleCaseSpecial -- cgit v0.12 From 5057276344a061b7f5553ef3ac12c513ccd9c694 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 30 Jun 2009 17:30:58 +0200 Subject: Document unified toolbar change with regard to full screen change. --- src/gui/widgets/qmainwindow.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 0a0faa0..0c841eb 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1419,9 +1419,10 @@ bool QMainWindow::event(QEvent *event) \i Toolbar breaks are not respected or preserved \i Any custom widgets in the toolbar will not be shown if the toolbar becomes too small (only actions will be shown) - \i If you call showFullScreen() on the main window, the QToolbar will - disappear since it is considered to be part of the title bar. You can - work around this by turning off the unified toolbar before you call + \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would + disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling + the toolbars out and back into the regular toolbar and vice versa when you swap out. + However, a good practice would be that turning off the unified toolbar before you call showFullScreen() and restoring it after you call showNormal(). \endlist -- cgit v0.12 From f79955fc9b250f03d54be3c99b79062368b6273d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 1 Jul 2009 11:42:22 +0200 Subject: Improve QtHelp error reporting. Reviewed-by: kh --- tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index b6e726b..c50f48d 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -639,7 +639,7 @@ void QHelpSearchIndexWriter::run() QFileInfo fInfo(indexPath); if (fInfo.exists() && !fInfo.isWritable()) { - qWarning("Full Text Search, could not create index (missing permissions)."); + qWarning("Full Text Search, could not create index (missing permissions for '%s').", qPrintable(indexPath)); return; } @@ -720,7 +720,7 @@ void QHelpSearchIndexWriter::run() } #if !defined(QT_NO_EXCEPTIONS) } catch (...) { - qWarning("Full Text Search, could not create index writer."); + qWarning("Full Text Search, could not create index writer in '%s'.", qPrintable(indexPath)); return; } #endif -- cgit v0.12 From 16e84b77571cb5dc97312ae613d96d7cd28ab4d2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Jul 2009 10:52:28 +0200 Subject: Fixed the license header that the unicode table generated uses. Also made sure that the generated code will not have trailing whitespaces. Reviewed-by: Thiago Macieira --- util/unicode/main.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index f1b4641..3c32e6d 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -1911,6 +1911,8 @@ static QByteArray createPropertyInfo() out += " // 0x" + QByteArray::number(BMP_END, 16); for (int i = 0; i < BMP_END/BMP_BLOCKSIZE; ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!((i*BMP_BLOCKSIZE) % 0x1000)) out += "\n"; out += "\n "; @@ -1918,9 +1920,13 @@ static QByteArray createPropertyInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n\n // 0x" + QByteArray::number(BMP_END, 16) + " - 0x" + QByteArray::number(SMP_END, 16) + "\n";; for (int i = BMP_END/BMP_BLOCKSIZE; i < blockMap.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!(i % (0x10000/SMP_BLOCKSIZE))) out += "\n"; out += "\n "; @@ -1928,14 +1934,21 @@ static QByteArray createPropertyInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n"; // write the data for (int i = 0; i < blocks.size(); ++i) { + if (out.endsWith(' ')) + out.chop(1); out += "\n"; const PropertyBlock &b = blocks.at(i); for (int j = 0; j < b.properties.size(); ++j) { - if (!(j % 8)) + if (!(j % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; + } out += QByteArray::number(b.properties.at(j)); out += ", "; } @@ -1948,6 +1961,8 @@ static QByteArray createPropertyInfo() Q_ASSERT(maxTitleCaseDiff < (1<<14)); Q_ASSERT(maxCaseFoldDiff < (1<<14)); + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n" "#define GET_PROP_INDEX(ucs4) \\\n" @@ -2204,6 +2219,8 @@ static QByteArray createCompositionInfo() out += " // 0 - 0x" + QByteArray::number(BMP_END, 16); for (int i = 0; i < BMP_END/BMP_BLOCKSIZE; ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!((i*BMP_BLOCKSIZE) % 0x1000)) out += "\n"; out += "\n "; @@ -2211,9 +2228,13 @@ static QByteArray createCompositionInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n\n // 0x" + QByteArray::number(BMP_END, 16) + " - 0x" + QByteArray::number(SMP_END, 16) + "\n";; for (int i = BMP_END/BMP_BLOCKSIZE; i < blockMap.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!(i % (0x10000/SMP_BLOCKSIZE))) out += "\n"; out += "\n "; @@ -2221,19 +2242,28 @@ static QByteArray createCompositionInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n"; // write the data for (int i = 0; i < blocks.size(); ++i) { + if (out.endsWith(' ')) + out.chop(1); out += "\n"; const DecompositionBlock &b = blocks.at(i); for (int j = 0; j < b.decompositionPositions.size(); ++j) { - if (!(j % 8)) + if (!(j % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; + } out += "0x" + QByteArray::number(b.decompositionPositions.at(j), 16); out += ", "; } } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n" "#define GET_DECOMPOSITION_INDEX(ucs4) \\\n" @@ -2250,12 +2280,16 @@ static QByteArray createCompositionInfo() for (int i = 0; i < decompositions.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; } out += "0x" + QByteArray::number(decompositions.at(i), 16); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n"; return out; @@ -2328,6 +2362,8 @@ static QByteArray createLigatureInfo() out += " // 0 - 0x" + QByteArray::number(BMP_END, 16); for (int i = 0; i < BMP_END/BMP_BLOCKSIZE; ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); if (!((i*BMP_BLOCKSIZE) % 0x1000)) out += "\n"; out += "\n "; @@ -2335,18 +2371,27 @@ static QByteArray createLigatureInfo() out += QByteArray::number(blockMap.at(i) + blockMap.size()); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n"; // write the data for (int i = 0; i < blocks.size(); ++i) { + if (out.endsWith(' ')) + out.chop(1); out += "\n"; const DecompositionBlock &b = blocks.at(i); for (int j = 0; j < b.decompositionPositions.size(); ++j) { - if (!(j % 8)) + if (!(j % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; + } out += "0x" + QByteArray::number(b.decompositionPositions.at(j), 16); out += ", "; } } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n" "#define GET_LIGATURE_INDEX(u2) " @@ -2358,12 +2403,16 @@ static QByteArray createLigatureInfo() for (int i = 0; i < ligatures.size(); ++i) { if (!(i % 8)) { + if (out.endsWith(' ')) + out.chop(1); out += "\n "; } out += "0x" + QByteArray::number(ligatures.at(i), 16); out += ", "; } + if (out.endsWith(' ')) + out.chop(1); out += "\n};\n\n"; return out; @@ -2420,18 +2469,46 @@ int main(int, char **) "/****************************************************************************\n" "**\n" "** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).\n" + "** Contact: Nokia Corporation (qt-info@nokia.com)\n" + "**\n" + "** This file is part of the QtCore module of the Qt Toolkit.\n" "**\n" - "** This file is part of the $MODULE$ of the Qt Toolkit.\n" + "** $QT_BEGIN_LICENSE:LGPL$\n" + "** No Commercial Usage\n" + "** This file contains pre-release code and may not be distributed.\n" + "** You may use this file in accordance with the terms and conditions\n" + "** contained in the either Technology Preview License Agreement or the\n" + "** Beta Release License Agreement.\n" "**\n" - "** $TROLLTECH_DUAL_LICENSE$\n" + "** GNU Lesser General Public License Usage\n" + "** Alternatively, this file may be used under the terms of the GNU Lesser\n" + "** General Public License version 2.1 as published by the Free Software\n" + "** Foundation and appearing in the file LICENSE.LGPL included in the\n" + "** packaging of this file. Please review the following information to\n" + "** ensure the GNU Lesser General Public License version 2.1 requirements\n" + "** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.\n" "**\n" - "** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE\n" - "** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\n" + "** In addition, as a special exception, Nokia gives you certain\n" + "** additional rights. These rights are described in the Nokia Qt LGPL\n" + "** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this\n" + "** package.\n" + "**\n" + "** GNU General Public License Usage\n" + "** Alternatively, this file may be used under the terms of the GNU\n" + "** General Public License version 3.0 as published by the Free Software\n" + "** Foundation and appearing in the file LICENSE.GPL included in the\n" + "** packaging of this file. Please review the following information to\n" + "** ensure the GNU General Public License version 3.0 requirements will be\n" + "** met: http://www.gnu.org/copyleft/gpl.html.\n" + "**\n" + "** If you are unsure which license is appropriate for your use, please\n" + "** contact the sales department at http://www.qtsoftware.com/contact.\n" + "** $QT_END_LICENSE$\n" "**\n" "****************************************************************************/\n\n" "/* This file is autogenerated from the Unicode 5.0 database. Do not edit */\n\n"; - + QByteArray warning = "//\n" "// W A R N I N G\n" -- cgit v0.12 From 3b9f9c1abaee60e94031e0a46f46c67410dc3d2f Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Jul 2009 10:55:01 +0200 Subject: Regenerated unicode tables after the fix in the generator. This is related to the following fix: 70137e0601549af1056082cdfbb4f141c70befab Reviewed-by: trustme --- src/corelib/tools/qunicodetables.cpp | 13383 +++++++++++++++++---------------- src/corelib/tools/qunicodetables_p.h | 4 +- 2 files changed, 6694 insertions(+), 6693 deletions(-) diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp index 11ae801..0387181 100644 --- a/src/corelib/tools/qunicodetables.cpp +++ b/src/corelib/tools/qunicodetables.cpp @@ -46,3374 +46,3374 @@ QT_BEGIN_NAMESPACE static const unsigned short uc_property_trie[] = { // 0x11000 - 6256, 6288, 6320, 6352, 6384, 6416, 6448, 6480, - 6512, 6544, 6576, 6608, 6640, 6672, 6704, 6736, - 6768, 6800, 6832, 6864, 6896, 6928, 6960, 6992, - 7024, 7056, 7088, 7120, 7152, 7184, 7216, 7248, - 7280, 7312, 7344, 6512, 7376, 6512, 7408, 7440, - 7472, 7504, 7536, 7568, 7600, 7632, 7664, 7696, - 7728, 7760, 7792, 7824, 7856, 7888, 7920, 7952, - 7984, 8016, 8048, 8080, 8112, 8144, 8176, 8208, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8272, 8304, 8336, 8368, 8400, 8432, 8464, 8496, - 8528, 8560, 8592, 8624, 8656, 8688, 8720, 8752, - 8400, 8784, 8816, 8848, 8880, 8912, 8944, 8976, - 9008, 9040, 9072, 9104, 9136, 9168, 9200, 9232, - 9136, 9264, 9296, 9104, 9328, 9360, 9392, 9424, - 9456, 9488, 9520, 9552, 9584, 9616, 9648, 9552, - 9680, 9712, 9744, 9776, 9808, 9840, 9872, 9552, - - 9904, 9936, 9968, 9552, 9552, 10000, 10032, 10064, - 10096, 10096, 10128, 10160, 10160, 10192, 10224, 10256, - 10288, 10320, 10352, 10320, 10384, 10416, 10448, 10480, - 10512, 10320, 10544, 10576, 10608, 10320, 10320, 10640, - 10672, 10320, 10320, 10320, 10320, 10320, 10320, 10320, - 10320, 10320, 10320, 10320, 10320, 10320, 10320, 10320, - 10320, 10320, 10320, 10704, 10736, 10320, 10320, 10768, - 10800, 10832, 10864, 10896, 9904, 10928, 10960, 10992, - 11024, 10320, 11056, 11088, 10320, 11120, 9552, 9552, - 11152, 11184, 11216, 11248, 11280, 11312, 11344, 11376, - 11408, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 11440, 11472, 11504, 11536, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 11568, 11600, 11632, 11664, 11696, 11728, 11760, 11792, - 6512, 6512, 6512, 6512, 11824, 6512, 6512, 11856, - 11888, 11920, 11952, 11984, 12016, 12048, 12080, 12112, - - 12144, 12176, 12208, 12240, 12272, 12304, 12336, 12368, - 12400, 12432, 12464, 12496, 12528, 12560, 12592, 12624, - 12656, 12688, 12720, 12752, 12784, 12816, 12848, 12880, - 12912, 12944, 12976, 13008, 13040, 13072, 13104, 13136, - 13168, 13200, 13232, 13264, 13296, 13328, 13360, 13392, - 13168, 13168, 13168, 13168, 13424, 13456, 13488, 13520, - 13552, 13168, 13168, 13584, 13616, 13648, 9552, 9552, - 13680, 13712, 13744, 13776, 13808, 13840, 13872, 13904, - 13936, 13936, 13936, 13936, 13936, 13936, 13936, 13936, - 13968, 13968, 13968, 13968, 14000, 14032, 14064, 14096, - 13968, 14128, 13968, 14160, 14192, 14224, 14256, 14288, - 14320, 14352, 9552, 9552, 9552, 9552, 9552, 9552, - 14384, 14416, 14448, 14480, 14512, 14512, 14512, 14544, - 14576, 14608, 14640, 14672, 14704, 14736, 14736, 9552, - 14768, 9552, 9552, 9552, 14800, 14832, 14832, 14864, - 14832, 14832, 14832, 14832, 14832, 14832, 14896, 14928, - - 14960, 14992, 15024, 15056, 15088, 15120, 15152, 15184, - 15216, 15248, 15280, 15280, 15312, 15344, 15376, 15408, - 15440, 15472, 15504, 15536, 15472, 15568, 15600, 15632, - 15664, 15664, 15664, 15696, 15664, 15664, 15728, 15760, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, - 15792, 15792, 15792, 15792, 15792, 15824, 11376, 11376, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 15856, 15856, 15856, 15856, 15888, 9552, 9552, - - 15920, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, - 15952, 15952, 15952, 15952, 15984, 16016, 16048, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 16080, 16112, 9552, 9552, 9552, 9552, 9552, 9552, - 16144, 16176, 16208, 16240, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - - 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, - 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, - 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, - 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, - 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, - 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, - 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, - 16304, 16336, 16368, 16400, 16432, 16496, 9552, 9552, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, - - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, - 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, - 15856, 16592, 16624, 16656, 16688, 16688, 16720, 9552, - 16752, 16784, 16816, 16848, 16848, 16880, 16912, 16848, - 16848, 16848, 16848, 16848, 16848, 16848, 16848, 16848, - 16848, 16944, 16976, 16848, 17008, 16848, 17040, 17072, - 17104, 17136, 17168, 17200, 16848, 16848, 16848, 17232, - 17264, 17296, 17328, 17360, 17392, 17424, 17456, 17488, - - 17520, 17552, 17584, 9552, 17616, 17616, 17616, 17648, - 17680, 17712, 17744, 17776, 17808, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 17840, 17872, 17904, 9552, 17936, 14640, 17968, 9552, - 18000, 18032, 18064, 17616, 18096, 18128, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, - 18160, 18192, 8240, 8240, 8240, 8240, 8240, 8240, - 18224, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 18256, 18288, 18320, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, - 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 6256, 6288, 6320, 6352, 6384, 6416, 6448, 6480, + 6512, 6544, 6576, 6608, 6640, 6672, 6704, 6736, + 6768, 6800, 6832, 6864, 6896, 6928, 6960, 6992, + 7024, 7056, 7088, 7120, 7152, 7184, 7216, 7248, + 7280, 7312, 7344, 6512, 7376, 6512, 7408, 7440, + 7472, 7504, 7536, 7568, 7600, 7632, 7664, 7696, + 7728, 7760, 7792, 7824, 7856, 7888, 7920, 7952, + 7984, 8016, 8048, 8080, 8112, 8144, 8176, 8208, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8272, 8304, 8336, 8368, 8400, 8432, 8464, 8496, + 8528, 8560, 8592, 8624, 8656, 8688, 8720, 8752, + 8400, 8784, 8816, 8848, 8880, 8912, 8944, 8976, + 9008, 9040, 9072, 9104, 9136, 9168, 9200, 9232, + 9136, 9264, 9296, 9104, 9328, 9360, 9392, 9424, + 9456, 9488, 9520, 9552, 9584, 9616, 9648, 9552, + 9680, 9712, 9744, 9776, 9808, 9840, 9872, 9552, + + 9904, 9936, 9968, 9552, 9552, 10000, 10032, 10064, + 10096, 10096, 10128, 10160, 10160, 10192, 10224, 10256, + 10288, 10320, 10352, 10320, 10384, 10416, 10448, 10480, + 10512, 10320, 10544, 10576, 10608, 10320, 10320, 10640, + 10672, 10320, 10320, 10320, 10320, 10320, 10320, 10320, + 10320, 10320, 10320, 10320, 10320, 10320, 10320, 10320, + 10320, 10320, 10320, 10704, 10736, 10320, 10320, 10768, + 10800, 10832, 10864, 10896, 9904, 10928, 10960, 10992, + 11024, 10320, 11056, 11088, 10320, 11120, 9552, 9552, + 11152, 11184, 11216, 11248, 11280, 11312, 11344, 11376, + 11408, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 11440, 11472, 11504, 11536, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 11568, 11600, 11632, 11664, 11696, 11728, 11760, 11792, + 6512, 6512, 6512, 6512, 11824, 6512, 6512, 11856, + 11888, 11920, 11952, 11984, 12016, 12048, 12080, 12112, + + 12144, 12176, 12208, 12240, 12272, 12304, 12336, 12368, + 12400, 12432, 12464, 12496, 12528, 12560, 12592, 12624, + 12656, 12688, 12720, 12752, 12784, 12816, 12848, 12880, + 12912, 12944, 12976, 13008, 13040, 13072, 13104, 13136, + 13168, 13200, 13232, 13264, 13296, 13328, 13360, 13392, + 13168, 13168, 13168, 13168, 13424, 13456, 13488, 13520, + 13552, 13168, 13168, 13584, 13616, 13648, 9552, 9552, + 13680, 13712, 13744, 13776, 13808, 13840, 13872, 13904, + 13936, 13936, 13936, 13936, 13936, 13936, 13936, 13936, + 13968, 13968, 13968, 13968, 14000, 14032, 14064, 14096, + 13968, 14128, 13968, 14160, 14192, 14224, 14256, 14288, + 14320, 14352, 9552, 9552, 9552, 9552, 9552, 9552, + 14384, 14416, 14448, 14480, 14512, 14512, 14512, 14544, + 14576, 14608, 14640, 14672, 14704, 14736, 14736, 9552, + 14768, 9552, 9552, 9552, 14800, 14832, 14832, 14864, + 14832, 14832, 14832, 14832, 14832, 14832, 14896, 14928, + + 14960, 14992, 15024, 15056, 15088, 15120, 15152, 15184, + 15216, 15248, 15280, 15280, 15312, 15344, 15376, 15408, + 15440, 15472, 15504, 15536, 15472, 15568, 15600, 15632, + 15664, 15664, 15664, 15696, 15664, 15664, 15728, 15760, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15792, 15792, 15792, + 15792, 15792, 15792, 15792, 15792, 15824, 11376, 11376, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 15856, 15856, 15856, 15856, 15888, 9552, 9552, + + 15920, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15952, 15952, 15952, 15952, + 15952, 15952, 15952, 15952, 15984, 16016, 16048, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 16080, 16112, 9552, 9552, 9552, 9552, 9552, 9552, + 16144, 16176, 16208, 16240, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + + 16304, 16336, 16368, 16400, 16432, 16464, 16272, 16304, + 16336, 16368, 16400, 16432, 16464, 16272, 16304, 16336, + 16368, 16400, 16432, 16464, 16272, 16304, 16336, 16368, + 16400, 16432, 16464, 16272, 16304, 16336, 16368, 16400, + 16432, 16464, 16272, 16304, 16336, 16368, 16400, 16432, + 16464, 16272, 16304, 16336, 16368, 16400, 16432, 16464, + 16272, 16304, 16336, 16368, 16400, 16432, 16464, 16272, + 16304, 16336, 16368, 16400, 16432, 16496, 9552, 9552, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + 16528, 16528, 16528, 16528, 16528, 16528, 16528, 16528, + + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 16560, 16560, 16560, 16560, 16560, 16560, 16560, 16560, + 15856, 15856, 15856, 15856, 15856, 15856, 15856, 15856, + 15856, 16592, 16624, 16656, 16688, 16688, 16720, 9552, + 16752, 16784, 16816, 16848, 16848, 16880, 16912, 16848, + 16848, 16848, 16848, 16848, 16848, 16848, 16848, 16848, + 16848, 16944, 16976, 16848, 17008, 16848, 17040, 17072, + 17104, 17136, 17168, 17200, 16848, 16848, 16848, 17232, + 17264, 17296, 17328, 17360, 17392, 17424, 17456, 17488, + + 17520, 17552, 17584, 9552, 17616, 17616, 17616, 17648, + 17680, 17712, 17744, 17776, 17808, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 17840, 17872, 17904, 9552, 17936, 14640, 17968, 9552, + 18000, 18032, 18064, 17616, 18096, 18128, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 9552, 9552, 9552, 9552, 9552, 9552, 9552, 9552, + 18160, 18192, 8240, 8240, 8240, 8240, 8240, 8240, + 18224, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 18256, 18288, 18320, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, + 8240, 8240, 8240, 8240, 8240, 8240, 8240, 8240, // 0x11000 - 0x110000 - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18608, 18608, 18608, 18864, 19120, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 19376, 19632, 19888, 20144, 20400, 20656, 20912, 21168, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, - 21680, 21680, 21680, 21680, 21680, 21680, 21936, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 21680, 21680, 22192, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 22448, 22704, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, - 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, - 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, - - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 6, 7, - - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 14, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 9, - - 14, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 39, 40, 41, 42, 43, - - 42, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 39, 45, 41, 36, 0, - - 0, 0, 0, 0, 0, 46, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 47, 14, 48, 12, 12, 12, 49, 49, - 42, 49, 50, 51, 36, 52, 49, 42, - 53, 54, 55, 56, 57, 58, 49, 59, - 42, 60, 50, 61, 62, 62, 62, 14, - - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 36, - 38, 38, 38, 38, 38, 38, 38, 63, - - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 36, - 44, 44, 44, 44, 44, 44, 44, 64, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 67, 68, 65, 66, 65, 66, 65, 66, - 50, 65, 66, 65, 66, 65, 66, 65, - - 66, 65, 66, 65, 66, 65, 66, 65, - 66, 69, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 70, 65, 66, 65, 66, 65, 66, 71, - - 72, 73, 65, 66, 65, 66, 74, 65, - 66, 75, 75, 65, 66, 50, 76, 77, - 78, 65, 66, 75, 79, 80, 81, 82, - 65, 66, 83, 50, 81, 84, 85, 86, - - 65, 66, 65, 66, 65, 66, 87, 65, - 66, 87, 50, 50, 65, 66, 87, 65, - 66, 88, 88, 65, 66, 65, 66, 89, - 65, 66, 50, 90, 65, 66, 50, 91, - - 90, 90, 90, 90, 92, 93, 94, 92, - 93, 94, 92, 93, 94, 65, 66, 65, - 66, 65, 66, 65, 66, 65, 66, 65, - 66, 65, 66, 65, 66, 95, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 96, 92, 93, 94, 65, 66, 97, 98, - 99, 100, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 99, 100, 99, 100, 99, 100, 99, 100, - - 101, 102, 99, 100, 99, 100, 99, 100, - 99, 100, 99, 100, 99, 100, 99, 100, - 99, 100, 99, 100, 102, 102, 102, 103, - 103, 103, 104, 105, 106, 107, 108, 103, - - 103, 105, 109, 110, 111, 112, 113, 109, - 113, 109, 113, 109, 113, 109, 113, 109, - 50, 50, 50, 114, 115, 50, 116, 116, - 50, 117, 50, 118, 50, 50, 50, 50, - - 116, 50, 50, 119, 50, 50, 50, 50, - 120, 121, 50, 122, 50, 50, 50, 121, - 50, 50, 123, 50, 50, 124, 50, 50, - 50, 50, 50, 50, 50, 125, 50, 50, - - 126, 50, 50, 126, 50, 50, 50, 50, - 126, 127, 128, 128, 129, 50, 50, 50, - 50, 50, 130, 50, 90, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, - - 50, 50, 50, 50, 50, 50, 50, 50, - 50, 131, 131, 131, 131, 131, 102, 102, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 133, 133, 134, 134, 134, 134, 134, - - 132, 132, 42, 42, 42, 42, 133, 133, - 135, 133, 133, 133, 135, 133, 133, 133, - 134, 134, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 136, - - 132, 132, 132, 132, 132, 42, 42, 42, - 42, 42, 136, 136, 136, 136, 137, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, - - 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 140, 141, 141, - 141, 141, 140, 142, 141, 141, 141, 141, - - 141, 143, 143, 141, 141, 141, 141, 143, - 143, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 144, 144, 144, 144, - 144, 141, 141, 141, 141, 139, 139, 139, - - 139, 139, 139, 139, 139, 145, 146, 147, - 147, 147, 146, 146, 146, 147, 147, 148, - 149, 149, 149, 150, 150, 150, 150, 149, - 151, 152, 152, 153, 154, 155, 155, 156, - - 157, 157, 158, 159, 159, 159, 159, 159, - 159, 159, 159, 159, 159, 159, 159, 159, - 160, 160, 160, 160, 42, 42, 160, 160, - 160, 160, 132, 161, 161, 161, 34, 160, - - 160, 160, 160, 160, 42, 42, 162, 14, - 163, 163, 163, 160, 164, 160, 165, 165, - 166, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - - 38, 38, 160, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 167, 168, 168, 168, - 169, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - - 44, 44, 170, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 171, 172, 172, 160, - 173, 174, 175, 175, 175, 176, 177, 131, - 178, 179, 65, 100, 65, 100, 65, 100, - - 65, 100, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 180, 181, 182, 50, 183, 184, 185, 186, - 187, 188, 186, 187, 103, 189, 189, 189, - - 190, 191, 191, 191, 191, 191, 191, 191, - 191, 191, 191, 191, 191, 190, 191, 191, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 192, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 192, 181, 181, - - 65, 66, 193, 139, 139, 139, 139, 160, - 194, 194, 178, 179, 99, 100, 99, 100, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 195, 65, 66, 65, 66, 178, 179, 65, - 66, 178, 179, 65, 66, 178, 179, 196, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 99, 100, 65, 66, - 65, 66, 65, 66, 65, 66, 105, 106, - 65, 66, 113, 109, 113, 109, 113, 109, - - 178, 179, 178, 179, 178, 179, 178, 179, - 178, 179, 178, 179, 178, 179, 178, 179, - 113, 109, 113, 109, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, - - 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 160, - 160, 134, 198, 198, 199, 198, 199, 198, - - 160, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 200, 200, 200, - - 200, 200, 200, 200, 200, 200, 200, 201, - 160, 202, 203, 160, 160, 160, 160, 160, - 204, 205, 206, 206, 206, 206, 205, 206, - 206, 206, 207, 205, 206, 206, 206, 206, - - 206, 206, 152, 205, 205, 205, 205, 205, - 206, 206, 205, 206, 206, 207, 208, 206, - 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, - - 225, 226, 227, 225, 206, 152, 228, 229, - 204, 204, 204, 204, 204, 204, 204, 204, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 204, 204, 204, 204, 204, - 230, 230, 230, 231, 232, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - - 233, 233, 233, 233, 234, 234, 234, 234, - 234, 234, 234, 235, 236, 237, 238, 238, - 149, 149, 149, 149, 149, 149, 234, 234, - 234, 234, 234, 239, 234, 234, 240, 241, - - 234, 242, 243, 243, 243, 243, 244, 243, - 244, 243, 244, 244, 244, 244, 244, 243, - 243, 243, 243, 244, 244, 244, 244, 244, - 244, 244, 244, 234, 234, 234, 234, 234, - - 245, 244, 244, 244, 244, 244, 244, 244, - 243, 244, 244, 246, 247, 248, 249, 250, - 251, 252, 253, 146, 146, 147, 150, 149, - 149, 153, 153, 153, 152, 153, 153, 234, - - 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 265, 266, 267, 267, - 268, 243, 243, 243, 242, 243, 243, 243, - 244, 244, 244, 244, 244, 244, 244, 244, - - 244, 244, 244, 244, 244, 244, 244, 244, - 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 244, 244, 244, 244, 244, 244, - - 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, - 269, 269, 244, 244, 244, 244, 244, 269, - - 243, 244, 244, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 244, 243, 244, 270, - 244, 244, 243, 243, 241, 243, 139, 139, - 139, 139, 139, 139, 139, 271, 272, 139, - - 139, 139, 139, 141, 139, 273, 273, 139, - 139, 49, 141, 139, 139, 141, 274, 274, - 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 269, 269, 269, 275, 275, 276, - - 277, 277, 277, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 234, 279, - 270, 280, 269, 269, 269, 270, 270, 270, - 270, 270, 269, 269, 269, 269, 270, 269, - - 269, 269, 269, 269, 269, 269, 269, 269, - 270, 269, 270, 269, 270, 276, 276, 274, - 146, 147, 146, 146, 147, 146, 146, 147, - 147, 147, 146, 147, 147, 146, 147, 146, - - 146, 146, 147, 146, 147, 146, 147, 146, - 147, 146, 146, 234, 234, 274, 276, 276, - 281, 281, 281, 281, 281, 281, 281, 281, - 281, 282, 282, 282, 281, 281, 281, 281, - - 281, 281, 281, 281, 281, 281, 281, 281, - 281, 281, 281, 282, 282, 281, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - - 283, 283, 283, 283, 283, 283, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 285, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - - 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, - - 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 297, 297, 297, 297, 297, - 297, 297, 298, 297, 299, 299, 300, 301, - 302, 303, 304, 204, 204, 204, 204, 204, - - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - - 160, 305, 305, 306, 307, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 160, 160, 308, 90, 306, 306, - - 306, 305, 305, 305, 305, 305, 305, 305, - 305, 306, 306, 306, 306, 309, 160, 160, - 90, 139, 141, 139, 139, 160, 160, 160, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 305, 305, 310, 310, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 198, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 321, 321, 322, 321, 321, - - 160, 305, 306, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 90, 160, 160, 90, - 90, 160, 160, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 160, 160, 160, 90, 90, - 90, 90, 160, 160, 308, 307, 323, 306, - - 306, 305, 305, 305, 305, 160, 160, 306, - 306, 160, 160, 306, 306, 309, 322, 160, - 160, 160, 160, 160, 160, 160, 160, 323, - 160, 160, 160, 160, 90, 90, 160, 90, - - 90, 90, 305, 305, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 90, 90, 12, 12, 324, 324, 324, 324, - 324, 324, 193, 160, 160, 160, 160, 160, - - 160, 325, 305, 326, 160, 90, 90, 90, - 90, 90, 90, 160, 160, 160, 160, 90, - 90, 160, 160, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 160, 90, 90, 160, - 90, 90, 160, 160, 308, 160, 306, 306, - - 306, 305, 305, 160, 160, 160, 160, 305, - 305, 160, 160, 305, 305, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 90, 90, 90, 90, 160, 90, 160, - - 160, 160, 160, 160, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 305, 305, 90, 90, 90, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 305, 305, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 307, 90, 160, 90, - 90, 90, 160, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 160, 90, 90, 90, - 90, 90, 160, 160, 308, 90, 306, 306, - - 306, 305, 305, 305, 305, 305, 160, 305, - 305, 306, 160, 306, 306, 309, 160, 160, - 90, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 307, 325, 325, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 160, 327, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 160, 307, 90, 90, - 90, 90, 160, 160, 308, 90, 323, 305, - - 306, 305, 305, 305, 160, 160, 160, 306, - 306, 160, 160, 306, 306, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 305, 323, - 160, 160, 160, 160, 90, 90, 160, 90, - - 90, 90, 160, 160, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 193, 307, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 305, 90, 160, 90, 90, 90, - 90, 90, 90, 160, 160, 160, 90, 90, - 90, 160, 90, 90, 90, 90, 160, 160, - 160, 90, 90, 160, 90, 160, 90, 90, - - 160, 160, 160, 90, 90, 160, 160, 160, - 90, 90, 90, 160, 160, 160, 90, 90, - 90, 90, 90, 90, 90, 90, 322, 90, - 90, 90, 160, 160, 160, 160, 323, 306, - - 305, 306, 306, 160, 160, 160, 306, 306, - 306, 160, 306, 306, 306, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 323, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 328, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 324, 324, 324, 238, 238, 238, 238, 238, - 238, 327, 238, 160, 160, 160, 160, 160, - - 160, 306, 306, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 90, 160, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 160, 90, 90, 90, - 90, 90, 160, 160, 160, 160, 305, 305, - - 305, 306, 306, 306, 306, 160, 305, 305, - 305, 160, 305, 305, 305, 309, 160, 160, - 160, 160, 160, 160, 160, 329, 330, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 90, 160, 160, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 306, 306, 160, 90, 90, 90, - 90, 90, 90, 90, 90, 160, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 160, 90, 90, 90, - 90, 90, 160, 160, 331, 307, 306, 332, - - 306, 306, 323, 306, 306, 160, 332, 306, - 306, 160, 306, 306, 305, 309, 160, 160, - 160, 160, 160, 160, 160, 323, 323, 160, - 160, 160, 160, 160, 160, 160, 90, 160, - - 90, 90, 333, 333, 160, 160, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, - 160, 300, 300, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 160, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 160, 160, 160, 160, 323, 306, - - 306, 305, 305, 305, 160, 160, 306, 306, - 306, 160, 306, 306, 306, 309, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 323, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 334, 334, 160, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 160, - 160, 160, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 160, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 160, 335, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 160, - 160, 160, 336, 160, 160, 160, 160, 337, - 334, 334, 284, 284, 284, 160, 284, 160, - 334, 334, 334, 334, 334, 334, 334, 337, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 334, 334, 338, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, - 339, 340, 339, 339, 340, 340, 340, 340, - 341, 341, 342, 160, 160, 160, 160, 12, - - 339, 339, 339, 339, 339, 339, 343, 340, - 344, 344, 344, 344, 340, 340, 340, 198, - 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 345, 345, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 339, 339, 160, 339, 160, 160, 339, - 339, 160, 339, 160, 160, 339, 160, 160, - 160, 160, 160, 160, 339, 339, 339, 339, - 160, 339, 339, 339, 339, 339, 339, 339, - - 160, 339, 339, 339, 160, 339, 160, 339, - 160, 160, 339, 339, 160, 339, 339, 339, - 339, 340, 339, 339, 340, 340, 340, 340, - 346, 346, 160, 340, 340, 339, 160, 160, - - 339, 339, 339, 339, 339, 160, 343, 160, - 347, 347, 347, 347, 340, 340, 160, 160, - 311, 312, 313, 314, 315, 316, 317, 318, - 319, 320, 160, 160, 339, 339, 160, 160, - - 348, 349, 349, 349, 350, 351, 350, 350, - 352, 350, 350, 353, 352, 354, 354, 354, - 354, 354, 352, 355, 356, 355, 355, 355, - 205, 205, 355, 355, 355, 355, 355, 355, - - 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 368, 205, 355, 205, - 355, 369, 370, 371, 370, 371, 372, 372, - - 348, 348, 348, 348, 348, 348, 348, 348, - 160, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 348, 348, 348, 348, 348, - - 348, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 335, 160, 160, 160, 160, 160, - 160, 373, 374, 375, 376, 375, 375, 375, - 375, 375, 374, 374, 374, 374, 375, 377, - - 374, 375, 206, 206, 378, 353, 206, 206, - 348, 348, 348, 348, 160, 160, 160, 160, - 375, 375, 375, 375, 375, 375, 284, 375, - 160, 375, 375, 375, 375, 375, 375, 375, - - 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 284, 284, - 284, 375, 375, 375, 375, 375, 375, 375, - 284, 375, 284, 284, 284, 160, 379, 379, - - 380, 380, 380, 380, 380, 380, 147, 380, - 380, 380, 380, 380, 380, 160, 160, 380, - 381, 381, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - - 382, 382, 160, 382, 382, 382, 382, 382, - 160, 382, 382, 160, 383, 384, 384, 384, - 384, 383, 384, 160, 160, 160, 384, 385, - 383, 386, 160, 160, 160, 160, 160, 160, - - 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 397, 338, 338, 338, 338, - 382, 382, 382, 382, 382, 382, 383, 383, - 384, 384, 160, 160, 160, 160, 160, 160, - - 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 398, - - 398, 398, 398, 398, 398, 398, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 399, - 399, 322, 322, 198, 400, 160, 160, 160, - - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 160, 160, 160, 160, 160, 401, - - 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 402, 402, 402, 402, 402, - - 402, 402, 402, 160, 160, 160, 160, 160, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 160, - 335, 160, 335, 335, 335, 335, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 160, - - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 160, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 160, 335, 335, 335, 335, 160, 160, - 335, 335, 335, 335, 335, 335, 335, 322, - - 335, 335, 335, 335, 335, 335, 335, 322, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 160, 160, 160, 160, 153, - - 404, 405, 406, 338, 338, 338, 338, 406, - 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 416, 416, 416, 416, 416, - 416, 416, 416, 416, 416, 160, 160, 160, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 338, 406, 335, - 335, 335, 335, 335, 335, 335, 335, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 418, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 419, 420, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 405, 405, 405, 421, 421, - 421, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 160, 399, 399, - 399, 399, 422, 422, 423, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 422, 422, 423, 424, 424, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 422, 422, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 399, 399, 399, 399, 399, 399, 399, 399, - 399, 399, 399, 399, 399, 160, 399, 399, - 399, 160, 422, 422, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 425, 425, 383, 384, - 384, 384, 384, 384, 384, 384, 383, 383, - - 383, 383, 383, 383, 383, 383, 384, 383, - 383, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 386, 384, 405, 405, 426, 427, - 405, 338, 405, 428, 382, 429, 160, 160, - - 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 160, 160, 160, 160, 160, 160, - 430, 430, 430, 430, 430, 430, 430, 430, - 430, 430, 160, 160, 160, 160, 160, 160, - - 431, 431, 432, 433, 432, 432, 434, 431, - 432, 433, 431, 284, 284, 284, 435, 160, - 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 137, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, - 160, 160, 160, 160, 160, 160, 160, 160, - - 335, 335, 335, 335, 335, 335, 335, 335, - 335, 436, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 160, 160, 160, - - 325, 325, 325, 326, 326, 326, 326, 325, - 325, 437, 437, 437, 160, 160, 160, 160, - 326, 326, 325, 326, 326, 326, 326, 326, - 326, 438, 149, 150, 160, 160, 160, 160, - - 238, 160, 160, 160, 439, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, - 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 450, 450, 450, 450, 450, 450, - - 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 450, 450, 450, 450, 160, 160, - 450, 450, 450, 450, 450, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 451, 451, 451, 451, 451, 451, - - 451, 451, 451, 451, 451, 451, 451, 451, - 451, 451, 160, 160, 160, 160, 160, 160, - 452, 452, 452, 452, 452, 452, 452, 452, - 452, 452, 452, 452, 452, 452, 452, 452, - - 452, 451, 451, 451, 451, 451, 451, 451, - 452, 452, 160, 160, 160, 160, 160, 160, - 328, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 160, 160, 160, 160, 462, 462, - - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 153, - 152, 463, 463, 463, 160, 160, 464, 465, - - 333, 333, 333, 333, 466, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 467, 466, 333, 333, - 333, 333, 333, 466, 333, 466, 466, 466, - - 466, 466, 333, 466, 468, 321, 321, 321, - 321, 321, 321, 321, 160, 160, 160, 160, - 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 479, 480, 480, 479, 479, - - 480, 481, 481, 481, 481, 481, 481, 481, - 481, 481, 481, 297, 298, 297, 297, 297, - 297, 297, 297, 297, 481, 481, 481, 481, - 481, 481, 481, 481, 481, 160, 160, 160, - - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, - - 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, - - 482, 482, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, - 483, 103, 103, 103, 103, 484, 103, 103, - - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 483, 483, 483, 483, 483, - - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 483, 483, 483, - - 153, 153, 152, 153, 297, 297, 297, 297, - 297, 297, 298, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 297, 298, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 485, 486, - 487, 488, 489, 490, 160, 160, 160, 160, - - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 160, 160, 160, 160, 160, 160, - - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - 491, 491, 491, 491, 491, 491, 160, 160, - 492, 492, 492, 492, 492, 492, 160, 160, - - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - - 491, 491, 491, 491, 491, 491, 160, 160, - 492, 492, 492, 492, 492, 492, 160, 160, - 493, 491, 494, 491, 495, 491, 496, 491, - 160, 492, 160, 492, 160, 492, 160, 492, - - 491, 491, 491, 491, 491, 491, 491, 491, - 492, 492, 492, 492, 492, 492, 492, 492, - 497, 497, 498, 498, 498, 498, 499, 499, - 500, 500, 501, 501, 502, 502, 160, 160, - - 503, 504, 505, 506, 507, 508, 509, 510, - 511, 512, 513, 514, 515, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, - 527, 528, 529, 530, 531, 532, 533, 534, - - 535, 536, 537, 538, 539, 540, 541, 542, - 543, 544, 545, 546, 547, 548, 549, 550, - 491, 491, 551, 552, 553, 160, 554, 555, - 492, 492, 556, 556, 557, 42, 558, 42, - - 42, 42, 559, 560, 561, 160, 562, 563, - 564, 564, 564, 564, 565, 42, 42, 42, - 491, 491, 566, 567, 160, 160, 568, 569, - 492, 492, 570, 570, 160, 42, 42, 42, - - 491, 491, 571, 572, 573, 182, 574, 575, - 492, 492, 576, 576, 577, 42, 42, 42, - 160, 160, 578, 579, 580, 160, 581, 582, - 583, 583, 584, 584, 585, 42, 42, 160, - - 586, 586, 586, 586, 586, 586, 586, 587, - 586, 586, 586, 588, 589, 590, 591, 592, - 593, 594, 593, 593, 595, 596, 14, 14, - 597, 598, 599, 600, 597, 601, 599, 600, - - 14, 14, 14, 14, 602, 602, 602, 603, - 604, 605, 606, 607, 608, 609, 610, 611, - 13, 13, 13, 13, 13, 612, 612, 612, - 14, 597, 601, 14, 613, 613, 14, 43, - - 43, 14, 14, 14, 614, 16, 17, 615, - 616, 616, 431, 431, 431, 431, 617, 617, - 617, 617, 185, 618, 619, 620, 621, 617, - 621, 621, 621, 621, 620, 621, 621, 622, - - 623, 624, 624, 624, 160, 160, 160, 160, - 160, 160, 625, 625, 625, 625, 625, 625, - 626, 627, 160, 160, 628, 629, 630, 631, - 632, 633, 634, 634, 36, 16, 17, 50, - - 626, 60, 55, 56, 628, 629, 630, 631, - 632, 633, 634, 634, 36, 16, 17, 160, - 483, 483, 483, 483, 483, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 12, 12, 12, 12, 12, 12, 12, 48, - 12, 12, 12, 635, 636, 428, 428, 428, - 637, 637, 638, 638, 638, 638, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 139, 139, 144, 144, 139, 139, 139, 139, - 144, 144, 144, 139, 139, 272, 272, 272, - - 272, 139, 194, 194, 639, 640, 640, 159, - 641, 159, 640, 642, 298, 298, 298, 298, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 49, 49, 175, 643, 49, 49, 49, 175, - 49, 643, 50, 175, 175, 175, 50, 50, - 175, 175, 175, 50, 49, 175, 644, 49, - 49, 175, 175, 175, 175, 175, 49, 49, - - 49, 49, 49, 49, 175, 49, 645, 49, - 175, 49, 646, 647, 175, 175, 648, 50, - 175, 175, 649, 175, 50, 90, 90, 90, - 90, 131, 650, 238, 103, 627, 651, 651, - - 185, 185, 185, 185, 185, 651, 627, 627, - 627, 627, 652, 185, 417, 300, 653, 160, - 160, 160, 160, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - - 654, 654, 654, 654, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 654, 654, - 655, 655, 655, 655, 655, 655, 655, 655, - 655, 655, 655, 655, 655, 655, 655, 655, - - 656, 656, 656, 99, 109, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 36, 36, 36, 36, 36, 49, 49, 49, - 49, 49, 36, 36, 49, 49, 49, 49, - - 36, 49, 49, 36, 49, 49, 36, 49, - 49, 49, 49, 49, 49, 49, 36, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 36, 36, - 49, 49, 36, 49, 36, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - - 36, 36, 36, 36, 36, 36, 36, 36, - 657, 657, 657, 658, 658, 658, 36, 36, - 36, 36, 18, 54, 36, 659, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 660, 661, 36, 36, - - 36, 36, 36, 662, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 660, 661, 660, 661, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 36, 36, 660, 661, 660, 661, - 660, 661, 660, 661, 36, 36, 660, 661, - 660, 661, 660, 661, 660, 661, 660, 661, - 660, 661, 660, 661, 660, 661, 660, 661, - - 660, 661, 660, 661, 660, 661, 660, 661, - 660, 661, 660, 661, 36, 36, 36, 660, - 661, 660, 661, 36, 36, 36, 36, 36, - 663, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 660, 661, 36, 36, 664, 36, - 665, 666, 36, 666, 36, 36, 36, 36, - 660, 661, 660, 661, 660, 661, 660, 661, - 36, 36, 36, 36, 36, 36, 36, 36, - - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 660, 661, 660, 661, 667, 36, 36, - 660, 661, 36, 36, 36, 36, 660, 661, - 660, 661, 660, 661, 660, 661, 660, 661, - - 660, 661, 660, 661, 660, 661, 660, 661, - 660, 661, 660, 661, 660, 661, 36, 36, - 660, 661, 668, 668, 668, 185, 669, 669, - 185, 185, 670, 670, 670, 671, 671, 185, - - 49, 650, 49, 49, 49, 49, 49, 49, - 660, 661, 660, 661, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 36, 36, 49, 49, 49, 49, 49, 49, - 49, 16, 17, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 650, 185, 650, 650, 650, - - 650, 650, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 380, 650, 650, - 650, 650, 650, 185, 185, 185, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 652, 652, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 652, - - 652, 652, 652, 652, 652, 652, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 238, - 238, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 672, 672, 672, 672, - - 672, 672, 300, 300, 300, 300, 300, 300, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 650, 650, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 673, 674, 675, 676, 677, 678, 679, 680, - 681, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 673, 674, 675, 676, - 677, 678, 679, 680, 681, 62, 62, 62, - - 62, 62, 62, 62, 62, 62, 62, 62, - 60, 55, 56, 628, 629, 630, 631, 632, - 633, 682, 682, 682, 682, 682, 682, 682, - 682, 682, 682, 682, 193, 193, 193, 193, - - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 683, 683, - 683, 683, 683, 683, 683, 683, 683, 683, - - 683, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 683, 683, 683, 683, 683, 683, - 684, 684, 684, 684, 684, 684, 684, 684, - 684, 684, 684, 684, 684, 684, 684, 684, - - 684, 684, 684, 684, 684, 684, 684, 684, - 684, 684, 685, 686, 686, 686, 686, 686, - 686, 686, 686, 686, 686, 687, 688, 689, - 690, 691, 692, 693, 694, 695, 686, 696, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 652, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 36, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 36, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 650, 650, 650, 650, 650, 650, 650, 650, - 185, 185, 185, 185, 185, 185, 185, 185, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 238, 238, 652, 652, - 417, 650, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 36, - 650, 650, 652, 652, 652, 652, 652, 652, - 652, 652, 652, 652, 652, 652, 417, 417, - - 652, 652, 652, 652, 652, 652, 652, 652, - 652, 652, 238, 238, 238, 238, 238, 238, - 238, 238, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 160, 160, 160, - - 238, 238, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 404, 417, 417, 417, - 417, 417, 300, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 49, 49, 49, 49, 160, 49, 49, - 49, 49, 160, 160, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 160, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 160, 49, 160, 49, - 49, 49, 49, 160, 160, 160, 49, 160, - 49, 49, 49, 697, 697, 697, 697, 160, - - 160, 49, 698, 698, 49, 49, 49, 49, - 699, 700, 699, 700, 699, 700, 699, 700, - 699, 700, 699, 700, 699, 700, 673, 674, - 675, 676, 677, 678, 679, 680, 681, 62, - - 673, 674, 675, 676, 677, 678, 679, 680, - 681, 62, 673, 674, 675, 676, 677, 678, - 679, 680, 681, 62, 49, 160, 160, 160, - 49, 49, 49, 49, 49, 49, 49, 49, - - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, - 160, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 160, - - 701, 701, 701, 702, 703, 704, 705, 672, - 672, 672, 672, 160, 160, 160, 160, 160, - 185, 185, 185, 185, 185, 706, 707, 185, - 185, 185, 185, 185, 185, 706, 707, 185, - - 185, 185, 706, 707, 706, 707, 699, 700, - 699, 700, 699, 700, 160, 160, 160, 160, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 380, 380, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - - 185, 185, 185, 699, 700, 699, 700, 699, - 700, 699, 700, 699, 700, 708, 709, 710, - 711, 699, 700, 699, 700, 699, 700, 699, - 700, 185, 185, 185, 185, 185, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 712, 185, 185, 185, 185, 185, 185, 185, - - 706, 707, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 706, - 707, 706, 707, 185, 706, 707, 185, 185, - 699, 700, 699, 700, 185, 185, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 713, 185, 185, - 706, 707, 185, 185, 699, 700, 185, 185, - - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 706, 707, 706, 707, 185, - 185, 185, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 706, 707, 185, 185, - - 185, 185, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, - 185, 706, 707, 185, 185, 706, 707, 706, - - 707, 706, 707, 706, 707, 185, 185, 185, - 185, 185, 185, 706, 707, 185, 185, 185, - 185, 706, 707, 706, 707, 706, 707, 706, - 707, 706, 707, 706, 707, 185, 185, 185, - - 185, 706, 707, 185, 185, 185, 706, 707, - 706, 707, 706, 707, 706, 707, 185, 706, - 707, 185, 185, 706, 707, 185, 185, 185, - 185, 185, 185, 706, 707, 706, 707, 706, - - 707, 706, 707, 706, 707, 706, 707, 185, - 185, 185, 185, 185, 185, 706, 707, 706, - 707, 706, 707, 706, 707, 706, 707, 185, - 185, 185, 185, 185, 185, 185, 714, 185, - - 185, 185, 185, 715, 716, 715, 185, 185, - 185, 185, 185, 185, 706, 707, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 706, - 707, 706, 707, 185, 185, 185, 185, 185, - - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 417, 417, - 417, 417, 417, 417, 300, 300, 300, 300, - 300, 300, 300, 160, 160, 160, 160, 160, - - 300, 300, 300, 300, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 717, - - 717, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 160, - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 718, - - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 718, - 718, 718, 718, 718, 718, 718, 718, 160, - - 113, 109, 719, 720, 721, 722, 723, 113, - 109, 113, 109, 113, 109, 160, 160, 160, - 160, 160, 160, 160, 724, 113, 109, 724, - 160, 160, 160, 160, 160, 160, 160, 160, - - 105, 106, 105, 106, 105, 106, 105, 106, - 105, 106, 105, 106, 105, 106, 105, 106, - 105, 106, 105, 106, 105, 106, 105, 106, - 105, 106, 105, 106, 105, 106, 105, 106, - - 105, 106, 105, 106, 103, 417, 417, 417, - 417, 417, 417, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 621, 621, 621, 621, 725, 621, 621, - - 726, 726, 726, 726, 726, 726, 726, 726, - 726, 726, 726, 726, 726, 726, 726, 726, - 726, 726, 726, 726, 726, 726, 726, 726, - 726, 726, 726, 726, 726, 726, 726, 726, - - 726, 726, 726, 726, 726, 726, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - - 322, 322, 322, 322, 322, 322, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 400, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 322, 322, 322, 322, 322, 322, 322, 160, - 322, 322, 322, 322, 322, 322, 322, 160, - 322, 322, 322, 322, 322, 322, 322, 160, - 322, 322, 322, 322, 322, 322, 322, 160, - - 727, 727, 728, 729, 728, 729, 727, 727, - 727, 728, 729, 727, 728, 729, 621, 621, - 621, 621, 621, 621, 621, 621, 620, 730, - 160, 160, 160, 160, 728, 729, 160, 160, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 160, 731, 731, 731, 731, 731, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 160, 160, 160, 160, - - 732, 733, 734, 735, 736, 737, 738, 739, - 16, 17, 16, 17, 16, 17, 16, 17, - 16, 17, 736, 736, 16, 17, 16, 17, - 16, 17, 16, 17, 740, 16, 17, 741, - - 736, 739, 739, 739, 739, 739, 739, 739, - 739, 739, 742, 743, 140, 744, 745, 745, - 746, 747, 747, 747, 747, 747, 736, 736, - 748, 748, 748, 749, 750, 751, 731, 736, - - 160, 752, 738, 752, 738, 752, 738, 752, - 738, 752, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - - 738, 738, 738, 752, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - - 738, 738, 738, 752, 738, 752, 738, 752, - 738, 738, 738, 738, 738, 738, 752, 738, - 738, 738, 738, 738, 738, 753, 753, 160, - 160, 754, 754, 755, 755, 756, 756, 757, - - 758, 759, 760, 759, 760, 759, 760, 759, - 760, 759, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - - 760, 760, 760, 759, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 760, 760, 760, 760, 760, 760, - - 760, 760, 760, 759, 760, 759, 760, 759, - 760, 760, 760, 760, 760, 760, 759, 760, - 760, 760, 760, 760, 760, 759, 759, 760, - 760, 760, 760, 761, 762, 762, 762, 763, - - 160, 160, 160, 160, 160, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 160, 160, 160, - 160, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 764, - - 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 764, 160, - 765, 765, 766, 766, 766, 766, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 160, 160, 160, 160, 160, 160, 160, 160, - - 768, 768, 768, 768, 768, 768, 768, 768, - 768, 768, 768, 768, 768, 768, 768, 768, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 769, 769, 769, 769, 769, 769, 769, 769, - 769, 769, 769, 769, 769, 769, 769, 769, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 770, 770, 160, - - 766, 766, 766, 766, 766, 766, 766, 766, - 766, 766, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 770, 771, 771, 771, 771, 771, 771, 771, - 771, 771, 771, 771, 771, 771, 771, 771, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 770, 770, 768, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 771, 771, 771, 771, 771, 771, 771, - 771, 771, 771, 771, 771, 771, 771, 771, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 770, 770, 770, 770, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 160, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 770, - 770, 770, 770, 765, 765, 765, 765, 765, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 770, 770, - - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 765, 765, 770, - - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 772, 772, - 772, 772, 772, 772, 772, 772, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, - - 738, 738, 738, 738, 738, 738, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 160, 160, 160, 160, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 774, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, - - 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 160, 160, 160, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - - 731, 731, 775, 775, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 775, 731, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 731, - - 731, 775, 731, 731, 731, 775, 731, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 776, 776, 776, 776, 776, 776, 776, 776, - 776, 776, 776, 776, 776, 776, 776, 776, - 776, 776, 776, 776, 776, 776, 776, 777, - 777, 777, 777, 160, 160, 160, 160, 160, - - 778, 778, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 322, 322, 779, 322, 322, 322, 780, 322, - 322, 322, 322, 781, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, - - 322, 322, 322, 463, 463, 781, 781, 463, - 417, 417, 417, 417, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 782, 782, 303, 303, - 160, 160, 160, 160, 160, 160, 160, 160, - - 783, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 783, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 783, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 783, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 783, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 783, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 784, 784, 784, 784, - 783, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 783, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - 784, 784, 784, 784, 784, 784, 784, 784, - - 784, 784, 784, 784, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 785, 785, 785, 785, 785, 785, 785, 785, - 785, 785, 785, 785, 785, 785, 785, 785, - 785, 785, 785, 785, 785, 785, 785, 785, - 785, 785, 785, 785, 785, 785, 785, 785, - - 786, 786, 786, 786, 786, 786, 786, 786, - 786, 786, 786, 786, 786, 786, 786, 786, - 786, 786, 786, 786, 786, 786, 786, 786, - 786, 786, 786, 786, 786, 786, 786, 786, - - 738, 738, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 160, 160, - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 787, 787, 787, 787, - - 787, 787, 787, 787, 787, 787, 787, 787, - 787, 787, 787, 160, 160, 160, 160, 160, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 773, 773, 773, 773, 773, 773, - 773, 773, 160, 160, 160, 160, 160, 160, - - 788, 789, 790, 791, 792, 793, 794, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 795, 796, 797, 798, 799, - 160, 160, 160, 160, 160, 800, 801, 230, - - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 634, 230, 230, 230, 230, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 204, - 230, 230, 230, 230, 230, 204, 230, 204, - - 230, 230, 204, 230, 230, 204, 230, 230, - 230, 230, 230, 230, 230, 230, 230, 230, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 599, 741, - - 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 234, 234, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 234, 234, 234, 234, 234, 234, 234, 234, - 802, 802, 802, 802, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 802, 802, 802, - - 802, 802, 802, 802, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 802, 802, 802, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 803, 238, 234, 234, - - 422, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, - 804, 805, 805, 804, 804, 806, 806, 807, - 808, 809, 160, 160, 160, 160, 160, 160, - - 139, 139, 139, 139, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 735, 746, 746, 810, 810, 599, 741, 599, - 741, 599, 741, 599, 741, 599, 741, 599, - - 741, 599, 741, 599, 741, 751, 751, 811, - 812, 735, 735, 735, 735, 810, 810, 810, - 813, 735, 814, 160, 761, 815, 9, 9, - 746, 16, 17, 16, 17, 16, 17, 816, - - 735, 735, 817, 818, 819, 820, 821, 160, - 735, 12, 13, 735, 160, 160, 160, 160, - 242, 242, 242, 285, 242, 234, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 234, 234, 822, - - 160, 9, 735, 816, 12, 13, 735, 735, - 16, 17, 735, 817, 813, 818, 814, 823, - 824, 825, 826, 827, 828, 829, 830, 831, - 832, 833, 815, 761, 834, 821, 835, 9, - - 735, 836, 836, 836, 836, 836, 836, 836, - 836, 836, 836, 836, 836, 836, 836, 836, - 836, 836, 836, 836, 836, 836, 836, 836, - 836, 836, 836, 39, 735, 41, 837, 810, - - 837, 838, 838, 838, 838, 838, 838, 838, - 838, 838, 838, 838, 838, 838, 838, 838, - 838, 838, 838, 838, 838, 838, 838, 838, - 838, 838, 838, 39, 821, 41, 821, 699, - - 700, 734, 16, 17, 733, 761, 839, 759, - 759, 759, 759, 759, 759, 759, 759, 759, - 762, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 839, - - 839, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 762, 762, - - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 160, - - 160, 160, 90, 90, 90, 90, 90, 90, - 160, 160, 90, 90, 90, 90, 90, 90, - 160, 160, 90, 90, 90, 90, 90, 90, - 160, 160, 90, 90, 90, 160, 160, 160, - - 48, 12, 821, 837, 736, 12, 12, 160, - 49, 36, 36, 36, 36, 49, 49, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 840, 840, 840, 841, 49, 842, 842, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 160, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 307, 160, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 160, 307, 307, 160, 307, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 160, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 160, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 160, 160, 160, 160, 160, - - 843, 844, 845, 160, 160, 160, 160, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 846, 846, 846, 846, - 846, 846, 846, 846, 160, 160, 160, 847, - 847, 847, 847, 847, 847, 847, 847, 847, - - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 848, 848, 848, - 848, 848, 848, 848, 848, 725, 725, 725, - 725, 417, 417, 417, 417, 417, 417, 417, - - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 725, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 160, - - 850, 850, 850, 850, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, - - 849, 851, 849, 849, 849, 849, 849, 849, - 849, 849, 851, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 843, - - 322, 322, 322, 322, 160, 160, 160, 160, - 322, 322, 322, 322, 322, 322, 322, 322, - 464, 852, 852, 852, 852, 852, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 853, 853, 853, 853, 853, 853, 853, 853, - 853, 853, 853, 853, 853, 853, 853, 853, - 853, 853, 853, 853, 853, 853, 853, 853, - 853, 853, 853, 853, 853, 853, 853, 853, - - 853, 853, 853, 853, 853, 853, 854, 854, - 855, 855, 855, 855, 855, 855, 855, 855, - 855, 855, 855, 855, 855, 855, 855, 855, - 855, 855, 855, 855, 855, 855, 855, 855, - - 855, 855, 855, 855, 855, 855, 855, 855, - 855, 855, 855, 855, 855, 855, 856, 856, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 307, 160, 160, - - 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 857, 857, 857, 857, 857, 857, 204, 204, - 857, 204, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 857, 857, - - 857, 857, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 857, 857, - 857, 857, 857, 857, 857, 857, 204, 857, - 857, 204, 204, 204, 857, 204, 204, 857, - - 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 859, 859, - 859, 859, 204, 204, 204, 204, 204, 860, - - 861, 781, 781, 781, 204, 781, 781, 204, - 204, 204, 204, 204, 781, 152, 781, 153, - 861, 861, 861, 861, 204, 861, 861, 861, - 204, 861, 861, 861, 861, 861, 861, 861, - - 861, 861, 861, 861, 861, 861, 861, 861, - 861, 861, 861, 861, 861, 861, 861, 861, - 861, 861, 861, 861, 204, 204, 204, 204, - 153, 642, 152, 204, 204, 204, 204, 780, - - 862, 863, 864, 865, 866, 866, 866, 866, - 204, 204, 204, 204, 204, 204, 204, 204, - 867, 867, 867, 867, 867, 867, 867, 867, - 868, 204, 204, 204, 204, 204, 204, 204, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 869, 869, 869, 869, 869, - 869, 869, 869, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 480, 480, 480, 480, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 160, - 160, 160, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 871, 872, 873, - 873, 873, 870, 870, 870, 874, 871, 871, - 871, 871, 871, 875, 875, 875, 875, 875, - 875, 875, 875, 876, 876, 876, 876, 876, - 876, 876, 876, 870, 870, 877, 877, 877, - 877, 877, 876, 876, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 877, 877, 877, 877, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 870, 870, - 870, 870, 870, 870, 870, 870, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 417, 417, 417, 417, 417, 417, - 417, 417, 153, 153, 153, 417, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 238, 238, 238, 238, 238, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 878, 878, 878, 878, 878, 878, - 878, 878, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 160, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 160, 879, 879, - 160, 160, 879, 160, 160, 879, 879, 160, - 160, 879, 879, 879, 879, 160, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 160, 880, 160, 880, 880, 880, - 880, 102, 880, 880, 160, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - - 880, 880, 880, 880, 879, 879, 160, 879, - 879, 879, 879, 160, 160, 879, 879, 879, - 879, 879, 879, 879, 879, 160, 879, 879, - 879, 879, 879, 879, 879, 160, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 160, 879, 879, 879, 879, 160, - 879, 879, 879, 879, 879, 160, 879, 160, - 160, 160, 879, 879, 879, 879, 879, 879, - 879, 160, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 103, 103, 160, 160, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 881, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 881, 880, 880, 880, 880, - 880, 880, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 881, 880, 880, 880, 880, - - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 881, 880, 880, - 880, 880, 880, 880, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 881, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 881, - 880, 880, 880, 880, 880, 880, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 881, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 881, 880, 880, 880, 880, 880, 880, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 879, 879, 879, 879, 879, 879, 879, - 879, 881, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 880, 880, 880, 880, 880, - 880, 880, 880, 881, 880, 880, 880, 880, - 880, 880, 882, 724, 160, 160, 883, 884, - 885, 886, 887, 888, 889, 890, 891, 892, - 883, 884, 885, 886, 887, 888, 889, 890, - 891, 892, 883, 884, 885, 886, 887, 888, - 889, 890, 891, 892, 883, 884, 885, 886, - 887, 888, 889, 890, 891, 892, 883, 884, - 885, 886, 887, 888, 889, 890, 891, 892, - - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 893, 893, - - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 894, 894, - 894, 894, 894, 894, 894, 894, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 160, 875, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 875, 875, 875, 875, 875, 875, 875, 875, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, - 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 160, 160, 160, - - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 895, 893, 893, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18608, 18608, 18608, 18864, 19120, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 19376, 19632, 19888, 20144, 20400, 20656, 20912, 21168, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21680, 21680, + 21680, 21680, 21680, 21680, 21680, 21680, 21936, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 21680, 21680, 22192, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 22448, 22704, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 18352, + 18352, 18352, 18352, 18352, 18352, 18352, 18352, 21424, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 22960, + 22960, 22960, 22960, 22960, 22960, 22960, 22960, 23216, + + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 6, 6, 7, + + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 14, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 9, + + 14, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 39, 40, 41, 42, 43, + + 42, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 39, 45, 41, 36, 0, + + 0, 0, 0, 0, 0, 46, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 47, 14, 48, 12, 12, 12, 49, 49, + 42, 49, 50, 51, 36, 52, 49, 42, + 53, 54, 55, 56, 57, 58, 49, 59, + 42, 60, 50, 61, 62, 62, 62, 14, + + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 36, + 38, 38, 38, 38, 38, 38, 38, 63, + + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 36, + 44, 44, 44, 44, 44, 44, 44, 64, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 67, 68, 65, 66, 65, 66, 65, 66, + 50, 65, 66, 65, 66, 65, 66, 65, + + 66, 65, 66, 65, 66, 65, 66, 65, + 66, 69, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 70, 65, 66, 65, 66, 65, 66, 71, + + 72, 73, 65, 66, 65, 66, 74, 65, + 66, 75, 75, 65, 66, 50, 76, 77, + 78, 65, 66, 75, 79, 80, 81, 82, + 65, 66, 83, 50, 81, 84, 85, 86, + + 65, 66, 65, 66, 65, 66, 87, 65, + 66, 87, 50, 50, 65, 66, 87, 65, + 66, 88, 88, 65, 66, 65, 66, 89, + 65, 66, 50, 90, 65, 66, 50, 91, + + 90, 90, 90, 90, 92, 93, 94, 92, + 93, 94, 92, 93, 94, 65, 66, 65, + 66, 65, 66, 65, 66, 65, 66, 65, + 66, 65, 66, 65, 66, 95, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 96, 92, 93, 94, 65, 66, 97, 98, + 99, 100, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 99, 100, 99, 100, 99, 100, 99, 100, + + 101, 102, 99, 100, 99, 100, 99, 100, + 99, 100, 99, 100, 99, 100, 99, 100, + 99, 100, 99, 100, 102, 102, 102, 103, + 103, 103, 104, 105, 106, 107, 108, 103, + + 103, 105, 109, 110, 111, 112, 113, 109, + 113, 109, 113, 109, 113, 109, 113, 109, + 50, 50, 50, 114, 115, 50, 116, 116, + 50, 117, 50, 118, 50, 50, 50, 50, + + 116, 50, 50, 119, 50, 50, 50, 50, + 120, 121, 50, 122, 50, 50, 50, 121, + 50, 50, 123, 50, 50, 124, 50, 50, + 50, 50, 50, 50, 50, 125, 50, 50, + + 126, 50, 50, 126, 50, 50, 50, 50, + 126, 127, 128, 128, 129, 50, 50, 50, + 50, 50, 130, 50, 90, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 131, 131, 131, 131, 131, 102, 102, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 133, 133, 134, 134, 134, 134, 134, + + 132, 132, 42, 42, 42, 42, 133, 133, + 135, 133, 133, 133, 135, 133, 133, 133, + 134, 134, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 136, + + 132, 132, 132, 132, 132, 42, 42, 42, + 42, 42, 136, 136, 136, 136, 137, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + + 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 140, 141, 141, + 141, 141, 140, 142, 141, 141, 141, 141, + + 141, 143, 143, 141, 141, 141, 141, 143, + 143, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 144, 144, 144, 144, + 144, 141, 141, 141, 141, 139, 139, 139, + + 139, 139, 139, 139, 139, 145, 146, 147, + 147, 147, 146, 146, 146, 147, 147, 148, + 149, 149, 149, 150, 150, 150, 150, 149, + 151, 152, 152, 153, 154, 155, 155, 156, + + 157, 157, 158, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, + 160, 160, 160, 160, 42, 42, 160, 160, + 160, 160, 132, 161, 161, 161, 34, 160, + + 160, 160, 160, 160, 42, 42, 162, 14, + 163, 163, 163, 160, 164, 160, 165, 165, + 166, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + + 38, 38, 160, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 167, 168, 168, 168, + 169, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + + 44, 44, 170, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 171, 172, 172, 160, + 173, 174, 175, 175, 175, 176, 177, 131, + 178, 179, 65, 100, 65, 100, 65, 100, + + 65, 100, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 180, 181, 182, 50, 183, 184, 185, 186, + 187, 188, 186, 187, 103, 189, 189, 189, + + 190, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 190, 191, 191, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 192, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 192, 193, 193, + + 65, 66, 194, 139, 139, 139, 139, 160, + 195, 195, 178, 179, 99, 100, 99, 100, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 196, 65, 66, 65, 66, 178, 179, 65, + 66, 178, 179, 65, 66, 178, 179, 197, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 99, 100, 65, 66, + 65, 66, 65, 66, 65, 66, 105, 106, + 65, 66, 113, 109, 113, 109, 113, 109, + + 178, 179, 178, 179, 178, 179, 178, 179, + 178, 179, 178, 179, 178, 179, 178, 179, + 113, 109, 113, 109, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 160, + 160, 134, 199, 199, 200, 199, 200, 199, + + 160, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + + 201, 201, 201, 201, 201, 201, 201, 202, + 160, 203, 204, 160, 160, 160, 160, 160, + 205, 206, 207, 207, 207, 207, 206, 207, + 207, 207, 208, 206, 207, 207, 207, 207, + + 207, 207, 152, 206, 206, 206, 206, 206, + 207, 207, 206, 207, 207, 208, 209, 207, + 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, + + 226, 227, 228, 226, 207, 152, 229, 230, + 205, 205, 205, 205, 205, 205, 205, 205, + 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, + + 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 205, 205, 205, 205, 205, + 231, 231, 231, 232, 233, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + + 234, 234, 234, 234, 235, 235, 235, 235, + 235, 235, 235, 236, 237, 238, 239, 239, + 149, 149, 149, 149, 149, 149, 235, 235, + 235, 235, 235, 240, 235, 235, 241, 242, + + 235, 243, 244, 244, 244, 244, 245, 244, + 245, 244, 245, 245, 245, 245, 245, 244, + 244, 244, 244, 245, 245, 245, 245, 245, + 245, 245, 245, 235, 235, 235, 235, 235, + + 246, 245, 245, 245, 245, 245, 245, 245, + 244, 245, 245, 247, 248, 249, 250, 251, + 252, 253, 254, 146, 146, 147, 150, 149, + 149, 153, 153, 153, 152, 153, 153, 235, + + 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 266, 267, 268, 268, + 269, 244, 244, 244, 243, 244, 244, 244, + 245, 245, 245, 245, 245, 245, 245, 245, + + 245, 245, 245, 245, 245, 245, 245, 245, + 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 245, 245, 245, 245, 245, 245, + + 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, + 270, 270, 245, 245, 245, 245, 245, 270, + + 244, 245, 245, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 245, 244, 245, 271, + 245, 245, 244, 244, 242, 244, 139, 139, + 139, 139, 139, 139, 139, 272, 273, 139, + + 139, 139, 139, 141, 139, 274, 274, 139, + 139, 49, 141, 139, 139, 141, 275, 275, + 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 270, 270, 270, 276, 276, 277, + + 278, 278, 278, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 235, 280, + 271, 281, 270, 270, 270, 271, 271, 271, + 271, 271, 270, 270, 270, 270, 271, 270, + + 270, 270, 270, 270, 270, 270, 270, 270, + 271, 270, 271, 270, 271, 277, 277, 275, + 146, 147, 146, 146, 147, 146, 146, 147, + 147, 147, 146, 147, 147, 146, 147, 146, + + 146, 146, 147, 146, 147, 146, 147, 146, + 147, 146, 146, 235, 235, 275, 277, 277, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 283, 283, 283, 282, 282, 282, 282, + + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 283, 283, 282, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + + 284, 284, 284, 284, 284, 284, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 286, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + + 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 297, 297, 297, 297, 297, + 297, 297, 297, 297, 297, 297, 297, 297, + 297, 297, 297, 297, 297, 297, 297, 297, + + 297, 297, 297, 297, 297, 297, 297, 297, + 297, 297, 297, 298, 298, 298, 298, 298, + 298, 298, 299, 298, 300, 300, 301, 302, + 303, 304, 305, 205, 205, 205, 205, 205, + + 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + + 160, 306, 306, 307, 308, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 160, 160, 309, 90, 307, 307, + + 307, 306, 306, 306, 306, 306, 306, 306, + 306, 307, 307, 307, 307, 310, 160, 160, + 90, 139, 141, 139, 139, 160, 160, 160, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 306, 306, 311, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 199, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 322, 322, 323, 322, 322, + + 160, 306, 307, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 90, 160, 160, 90, + 90, 160, 160, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 160, 160, 160, 90, 90, + 90, 90, 160, 160, 309, 308, 324, 307, + + 307, 306, 306, 306, 306, 160, 160, 307, + 307, 160, 160, 307, 307, 310, 323, 160, + 160, 160, 160, 160, 160, 160, 160, 324, + 160, 160, 160, 160, 90, 90, 160, 90, + + 90, 90, 306, 306, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 90, 90, 12, 12, 325, 325, 325, 325, + 325, 325, 194, 160, 160, 160, 160, 160, + + 160, 326, 306, 327, 160, 90, 90, 90, + 90, 90, 90, 160, 160, 160, 160, 90, + 90, 160, 160, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 160, 90, 90, 160, + 90, 90, 160, 160, 309, 160, 307, 307, + + 307, 306, 306, 160, 160, 160, 160, 306, + 306, 160, 160, 306, 306, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 90, 90, 90, 90, 160, 90, 160, + + 160, 160, 160, 160, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 306, 306, 90, 90, 90, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 306, 306, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 308, 90, 160, 90, + 90, 90, 160, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 160, 90, 90, 90, + 90, 90, 160, 160, 309, 90, 307, 307, + + 307, 306, 306, 306, 306, 306, 160, 306, + 306, 307, 160, 307, 307, 310, 160, 160, + 90, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 308, 326, 326, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 160, 328, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 160, 308, 90, 90, + 90, 90, 160, 160, 309, 90, 324, 306, + + 307, 306, 306, 306, 160, 160, 160, 307, + 307, 160, 160, 307, 307, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 306, 324, + 160, 160, 160, 160, 90, 90, 160, 90, + + 90, 90, 160, 160, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 194, 308, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 306, 90, 160, 90, 90, 90, + 90, 90, 90, 160, 160, 160, 90, 90, + 90, 160, 90, 90, 90, 90, 160, 160, + 160, 90, 90, 160, 90, 160, 90, 90, + + 160, 160, 160, 90, 90, 160, 160, 160, + 90, 90, 90, 160, 160, 160, 90, 90, + 90, 90, 90, 90, 90, 90, 323, 90, + 90, 90, 160, 160, 160, 160, 324, 307, + + 306, 307, 307, 160, 160, 160, 307, 307, + 307, 160, 307, 307, 307, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 324, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 329, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 325, 325, 325, 239, 239, 239, 239, 239, + 239, 328, 239, 160, 160, 160, 160, 160, + + 160, 307, 307, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 90, 160, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 160, 90, 90, 90, + 90, 90, 160, 160, 160, 160, 306, 306, + + 306, 307, 307, 307, 307, 160, 306, 306, + 306, 160, 306, 306, 306, 310, 160, 160, + 160, 160, 160, 160, 160, 330, 331, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 90, 160, 160, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 307, 307, 160, 90, 90, 90, + 90, 90, 90, 90, 90, 160, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 160, 90, 90, 90, + 90, 90, 160, 160, 332, 308, 307, 333, + + 307, 307, 324, 307, 307, 160, 333, 307, + 307, 160, 307, 307, 306, 310, 160, 160, + 160, 160, 160, 160, 160, 324, 324, 160, + 160, 160, 160, 160, 160, 160, 90, 160, + + 90, 90, 334, 334, 160, 160, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 160, 301, 301, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 160, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 160, 160, 160, 160, 324, 307, + + 307, 306, 306, 306, 160, 160, 307, 307, + 307, 160, 307, 307, 307, 310, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 324, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 335, 335, 160, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 160, + 160, 160, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 160, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 160, 336, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 160, + 160, 160, 337, 160, 160, 160, 160, 338, + 335, 335, 285, 285, 285, 160, 285, 160, + 335, 335, 335, 335, 335, 335, 335, 338, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 335, 335, 339, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, + 340, 341, 340, 340, 341, 341, 341, 341, + 342, 342, 343, 160, 160, 160, 160, 12, + + 340, 340, 340, 340, 340, 340, 344, 341, + 345, 345, 345, 345, 341, 341, 341, 199, + 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 346, 346, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 340, 340, 160, 340, 160, 160, 340, + 340, 160, 340, 160, 160, 340, 160, 160, + 160, 160, 160, 160, 340, 340, 340, 340, + 160, 340, 340, 340, 340, 340, 340, 340, + + 160, 340, 340, 340, 160, 340, 160, 340, + 160, 160, 340, 340, 160, 340, 340, 340, + 340, 341, 340, 340, 341, 341, 341, 341, + 347, 347, 160, 341, 341, 340, 160, 160, + + 340, 340, 340, 340, 340, 160, 344, 160, + 348, 348, 348, 348, 341, 341, 160, 160, + 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 160, 160, 340, 340, 160, 160, + + 349, 350, 350, 350, 351, 352, 351, 351, + 353, 351, 351, 354, 353, 355, 355, 355, + 355, 355, 353, 356, 357, 356, 356, 356, + 206, 206, 356, 356, 356, 356, 356, 356, + + 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 369, 206, 356, 206, + 356, 370, 371, 372, 371, 372, 373, 373, + + 349, 349, 349, 349, 349, 349, 349, 349, + 160, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, + + 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 336, 160, 160, 160, 160, 160, + 160, 374, 375, 376, 377, 376, 376, 376, + 376, 376, 375, 375, 375, 375, 376, 378, + + 375, 376, 207, 207, 379, 354, 207, 207, + 349, 349, 349, 349, 160, 160, 160, 160, + 376, 376, 376, 376, 376, 376, 285, 376, + 160, 376, 376, 376, 376, 376, 376, 376, + + 376, 376, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 285, 285, + 285, 376, 376, 376, 376, 376, 376, 376, + 285, 376, 285, 285, 285, 160, 380, 380, + + 381, 381, 381, 381, 381, 381, 147, 381, + 381, 381, 381, 381, 381, 160, 160, 381, + 382, 382, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + + 383, 383, 160, 383, 383, 383, 383, 383, + 160, 383, 383, 160, 384, 385, 385, 385, + 385, 384, 385, 160, 160, 160, 385, 386, + 384, 387, 160, 160, 160, 160, 160, 160, + + 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 398, 339, 339, 339, 339, + 383, 383, 383, 383, 383, 383, 384, 384, + 385, 385, 160, 160, 160, 160, 160, 160, + + 399, 399, 399, 399, 399, 399, 399, 399, + 399, 399, 399, 399, 399, 399, 399, 399, + 399, 399, 399, 399, 399, 399, 399, 399, + 399, 399, 399, 399, 399, 399, 399, 399, + + 399, 399, 399, 399, 399, 399, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 400, + 400, 323, 323, 199, 401, 160, 160, 160, + + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 160, 160, 160, 160, 160, 402, + + 403, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, + + 403, 403, 403, 160, 160, 160, 160, 160, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 160, + 336, 160, 336, 336, 336, 336, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 160, + + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 160, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 160, 336, 336, 336, 336, 160, 160, + 336, 336, 336, 336, 336, 336, 336, 323, + + 336, 336, 336, 336, 336, 336, 336, 323, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 160, 160, 160, 160, 153, + + 405, 406, 407, 339, 339, 339, 339, 407, + 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 160, 160, 160, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 339, 407, 336, + 336, 336, 336, 336, 336, 336, 336, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 419, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 420, 421, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 406, 406, 406, 422, 422, + 422, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 160, 400, 400, + 400, 400, 423, 423, 424, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 423, 423, 424, 425, 425, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 423, 423, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 160, 400, 400, + 400, 160, 423, 423, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 426, 426, 384, 385, + 385, 385, 385, 385, 385, 385, 384, 384, + + 384, 384, 384, 384, 384, 384, 385, 384, + 384, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 387, 385, 406, 406, 427, 428, + 406, 339, 406, 429, 383, 430, 160, 160, + + 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 160, 160, 160, 160, 160, 160, + 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 160, 160, 160, 160, 160, 160, + + 432, 432, 433, 434, 433, 433, 435, 432, + 433, 434, 432, 285, 285, 285, 436, 160, + 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 137, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 336, + 160, 160, 160, 160, 160, 160, 160, 160, + + 336, 336, 336, 336, 336, 336, 336, 336, + 336, 437, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 160, 160, 160, + + 326, 326, 326, 327, 327, 327, 327, 326, + 326, 438, 438, 438, 160, 160, 160, 160, + 327, 327, 326, 327, 327, 327, 327, 327, + 327, 439, 149, 150, 160, 160, 160, 160, + + 239, 160, 160, 160, 440, 440, 441, 442, + 443, 444, 445, 446, 447, 448, 449, 450, + 451, 451, 451, 451, 451, 451, 451, 451, + 451, 451, 451, 451, 451, 451, 451, 451, + + 451, 451, 451, 451, 451, 451, 451, 451, + 451, 451, 451, 451, 451, 451, 160, 160, + 451, 451, 451, 451, 451, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, + + 452, 452, 452, 452, 452, 452, 452, 452, + 452, 452, 160, 160, 160, 160, 160, 160, + 453, 453, 453, 453, 453, 453, 453, 453, + 453, 453, 453, 453, 453, 453, 453, 453, + + 453, 452, 452, 452, 452, 452, 452, 452, + 453, 453, 160, 160, 160, 160, 160, 160, + 329, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 160, 160, 160, 160, 463, 463, + + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 153, + 152, 464, 464, 464, 160, 160, 465, 466, + + 334, 334, 334, 334, 467, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 468, 467, 334, 334, + 334, 334, 334, 467, 334, 467, 467, 467, + + 467, 467, 334, 467, 469, 322, 322, 322, + 322, 322, 322, 322, 160, 160, 160, 160, + 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 480, 481, 481, 480, 480, + + 481, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 298, 299, 298, 298, 298, + 298, 298, 298, 298, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 160, 160, 160, + + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, + + 483, 483, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 484, 103, 103, 103, 103, 485, 103, 103, + + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 484, 484, 484, 484, 484, + + 484, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 484, + + 153, 153, 152, 153, 298, 298, 298, 298, + 298, 298, 299, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 298, 299, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 486, 487, + 488, 489, 490, 491, 160, 160, 160, 160, + + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 160, 160, 160, 160, 160, 160, + + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + 492, 492, 492, 492, 492, 492, 160, 160, + 493, 493, 493, 493, 493, 493, 160, 160, + + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + + 492, 492, 492, 492, 492, 492, 160, 160, + 493, 493, 493, 493, 493, 493, 160, 160, + 494, 492, 495, 492, 496, 492, 497, 492, + 160, 493, 160, 493, 160, 493, 160, 493, + + 492, 492, 492, 492, 492, 492, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, + 498, 498, 499, 499, 499, 499, 500, 500, + 501, 501, 502, 502, 503, 503, 160, 160, + + 504, 505, 506, 507, 508, 509, 510, 511, + 512, 513, 514, 515, 516, 517, 518, 519, + 520, 521, 522, 523, 524, 525, 526, 527, + 528, 529, 530, 531, 532, 533, 534, 535, + + 536, 537, 538, 539, 540, 541, 542, 543, + 544, 545, 546, 547, 548, 549, 550, 551, + 492, 492, 552, 553, 554, 160, 555, 556, + 493, 493, 557, 557, 558, 42, 559, 42, + + 42, 42, 560, 561, 562, 160, 563, 564, + 565, 565, 565, 565, 566, 42, 42, 42, + 492, 492, 567, 568, 160, 160, 569, 570, + 493, 493, 571, 571, 160, 42, 42, 42, + + 492, 492, 572, 573, 574, 182, 575, 576, + 493, 493, 577, 577, 578, 42, 42, 42, + 160, 160, 579, 580, 581, 160, 582, 583, + 584, 584, 585, 585, 586, 42, 42, 160, + + 587, 587, 587, 587, 587, 587, 587, 588, + 587, 587, 587, 589, 590, 591, 592, 593, + 594, 595, 594, 594, 596, 597, 14, 14, + 598, 599, 600, 601, 598, 602, 600, 601, + + 14, 14, 14, 14, 603, 603, 603, 604, + 605, 606, 607, 608, 609, 610, 611, 612, + 13, 13, 13, 13, 13, 613, 613, 613, + 14, 598, 602, 14, 614, 614, 14, 43, + + 43, 14, 14, 14, 615, 16, 17, 616, + 617, 617, 432, 432, 432, 432, 618, 618, + 618, 618, 185, 619, 620, 621, 622, 618, + 622, 622, 622, 622, 621, 622, 622, 623, + + 624, 625, 625, 625, 160, 160, 160, 160, + 160, 160, 626, 626, 626, 626, 626, 626, + 627, 628, 160, 160, 629, 630, 631, 632, + 633, 634, 635, 635, 36, 16, 17, 50, + + 627, 60, 55, 56, 629, 630, 631, 632, + 633, 634, 635, 635, 36, 16, 17, 160, + 484, 484, 484, 484, 484, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 12, 12, 12, 12, 12, 12, 12, 48, + 12, 12, 12, 636, 637, 429, 429, 429, + 638, 638, 639, 639, 639, 639, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 139, 139, 144, 144, 139, 139, 139, 139, + 144, 144, 144, 139, 139, 273, 273, 273, + + 273, 139, 195, 195, 640, 641, 641, 159, + 642, 159, 641, 643, 299, 299, 299, 299, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 49, 49, 175, 644, 49, 49, 49, 175, + 49, 644, 50, 175, 175, 175, 50, 50, + 175, 175, 175, 50, 49, 175, 645, 49, + 49, 175, 175, 175, 175, 175, 49, 49, + + 49, 49, 49, 49, 175, 49, 646, 49, + 175, 49, 647, 648, 175, 175, 649, 50, + 175, 175, 650, 175, 50, 90, 90, 90, + 90, 131, 651, 239, 103, 628, 652, 652, + + 185, 185, 185, 185, 185, 652, 628, 628, + 628, 628, 653, 185, 418, 301, 654, 160, + 160, 160, 160, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, + + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 656, 656, 656, 656, 656, 656, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 656, + + 657, 657, 657, 99, 109, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 36, 36, 36, 36, 36, 49, 49, 49, + 49, 49, 36, 36, 49, 49, 49, 49, + + 36, 49, 49, 36, 49, 49, 36, 49, + 49, 49, 49, 49, 49, 49, 36, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 36, 36, + 49, 49, 36, 49, 36, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + + 36, 36, 36, 36, 36, 36, 36, 36, + 658, 658, 658, 659, 659, 659, 36, 36, + 36, 36, 18, 54, 36, 660, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 661, 662, 36, 36, + + 36, 36, 36, 663, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 661, 662, 661, 662, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 661, 662, 661, 662, + 661, 662, 661, 662, 36, 36, 661, 662, + 661, 662, 661, 662, 661, 662, 661, 662, + 661, 662, 661, 662, 661, 662, 661, 662, + + 661, 662, 661, 662, 661, 662, 661, 662, + 661, 662, 661, 662, 36, 36, 36, 661, + 662, 661, 662, 36, 36, 36, 36, 36, + 664, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 661, 662, 36, 36, 665, 36, + 666, 667, 36, 667, 36, 36, 36, 36, + 661, 662, 661, 662, 661, 662, 661, 662, + 36, 36, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 661, 662, 661, 662, 668, 36, 36, + 661, 662, 36, 36, 36, 36, 661, 662, + 661, 662, 661, 662, 661, 662, 661, 662, + + 661, 662, 661, 662, 661, 662, 661, 662, + 661, 662, 661, 662, 661, 662, 36, 36, + 661, 662, 669, 669, 669, 185, 670, 670, + 185, 185, 671, 671, 671, 672, 672, 185, + + 49, 651, 49, 49, 49, 49, 49, 49, + 661, 662, 661, 662, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 36, 36, 49, 49, 49, 49, 49, 49, + 49, 16, 17, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 651, 185, 651, 651, 651, + + 651, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 381, 651, 651, + 651, 651, 651, 185, 185, 185, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, + + 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 239, + 239, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 673, 673, 673, 673, + + 673, 673, 301, 301, 301, 301, 301, 301, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 651, 651, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 674, 675, 676, 677, 678, 679, 680, 681, + 682, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 674, 675, 676, 677, + 678, 679, 680, 681, 682, 62, 62, 62, + + 62, 62, 62, 62, 62, 62, 62, 62, + 60, 55, 56, 629, 630, 631, 632, 633, + 634, 683, 683, 683, 683, 683, 683, 683, + 683, 683, 683, 683, 194, 194, 194, 194, + + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, + + 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, + 685, 685, 685, 685, 685, 685, 685, 685, + 685, 685, 685, 685, 685, 685, 685, 685, + + 685, 685, 685, 685, 685, 685, 685, 685, + 685, 685, 686, 687, 687, 687, 687, 687, + 687, 687, 687, 687, 687, 688, 689, 690, + 691, 692, 693, 694, 695, 696, 687, 697, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 653, 653, + 653, 653, 653, 653, 653, 653, 653, 653, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 36, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 36, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 651, 651, 651, 651, 651, 651, 651, 651, + 185, 185, 185, 185, 185, 185, 185, 185, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 239, 239, 653, 653, + 418, 651, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 36, + 651, 651, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 653, 653, 418, 418, + + 653, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 239, 239, 239, 239, 239, 239, + 239, 239, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 160, 160, 160, + + 239, 239, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 405, 418, 418, 418, + 418, 418, 301, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 49, 49, 49, 49, 160, 49, 49, + 49, 49, 160, 160, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 160, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 160, 49, 160, 49, + 49, 49, 49, 160, 160, 160, 49, 160, + 49, 49, 49, 698, 698, 698, 698, 160, + + 160, 49, 699, 699, 49, 49, 49, 49, + 700, 701, 700, 701, 700, 701, 700, 701, + 700, 701, 700, 701, 700, 701, 674, 675, + 676, 677, 678, 679, 680, 681, 682, 62, + + 674, 675, 676, 677, 678, 679, 680, 681, + 682, 62, 674, 675, 676, 677, 678, 679, + 680, 681, 682, 62, 49, 160, 160, 160, + 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 160, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 160, + + 702, 702, 702, 703, 704, 705, 706, 673, + 673, 673, 673, 160, 160, 160, 160, 160, + 185, 185, 185, 185, 185, 707, 708, 185, + 185, 185, 185, 185, 185, 707, 708, 185, + + 185, 185, 707, 708, 707, 708, 700, 701, + 700, 701, 700, 701, 160, 160, 160, 160, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + + 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + + 185, 185, 185, 700, 701, 700, 701, 700, + 701, 700, 701, 700, 701, 709, 710, 711, + 712, 700, 701, 700, 701, 700, 701, 700, + 701, 185, 185, 185, 185, 185, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 713, 185, 185, 185, 185, 185, 185, 185, + + 707, 708, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 707, + 708, 707, 708, 185, 707, 708, 185, 185, + 700, 701, 700, 701, 185, 185, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 714, 185, 185, + 707, 708, 185, 185, 700, 701, 185, 185, + + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 707, 708, 707, 708, 185, + 185, 185, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 707, 708, 185, 185, + + 185, 185, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, + 185, 707, 708, 185, 185, 707, 708, 707, + + 708, 707, 708, 707, 708, 185, 185, 185, + 185, 185, 185, 707, 708, 185, 185, 185, + 185, 707, 708, 707, 708, 707, 708, 707, + 708, 707, 708, 707, 708, 185, 185, 185, + + 185, 707, 708, 185, 185, 185, 707, 708, + 707, 708, 707, 708, 707, 708, 185, 707, + 708, 185, 185, 707, 708, 185, 185, 185, + 185, 185, 185, 707, 708, 707, 708, 707, + + 708, 707, 708, 707, 708, 707, 708, 185, + 185, 185, 185, 185, 185, 707, 708, 707, + 708, 707, 708, 707, 708, 707, 708, 185, + 185, 185, 185, 185, 185, 185, 715, 185, + + 185, 185, 185, 716, 717, 716, 185, 185, + 185, 185, 185, 185, 707, 708, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 707, + 708, 707, 708, 185, 185, 185, 185, 185, + + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 418, 418, + 418, 418, 418, 418, 301, 301, 301, 301, + 301, 301, 301, 160, 160, 160, 160, 160, + + 301, 301, 301, 301, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, + + 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 160, + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, + + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 160, + + 113, 109, 720, 721, 722, 723, 724, 113, + 109, 113, 109, 113, 109, 160, 160, 160, + 160, 160, 160, 160, 725, 113, 109, 725, + 160, 160, 160, 160, 160, 160, 160, 160, + + 105, 106, 105, 106, 105, 106, 105, 106, + 105, 106, 105, 106, 105, 106, 105, 106, + 105, 106, 105, 106, 105, 106, 105, 106, + 105, 106, 105, 106, 105, 106, 105, 106, + + 105, 106, 105, 106, 103, 418, 418, 418, + 418, 418, 418, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 622, 622, 622, 622, 726, 622, 622, + + 727, 727, 727, 727, 727, 727, 727, 727, + 727, 727, 727, 727, 727, 727, 727, 727, + 727, 727, 727, 727, 727, 727, 727, 727, + 727, 727, 727, 727, 727, 727, 727, 727, + + 727, 727, 727, 727, 727, 727, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + + 323, 323, 323, 323, 323, 323, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 401, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 323, 323, 323, 323, 323, 323, 323, 160, + 323, 323, 323, 323, 323, 323, 323, 160, + 323, 323, 323, 323, 323, 323, 323, 160, + 323, 323, 323, 323, 323, 323, 323, 160, + + 728, 728, 729, 730, 729, 730, 728, 728, + 728, 729, 730, 728, 729, 730, 622, 622, + 622, 622, 622, 622, 622, 622, 621, 731, + 160, 160, 160, 160, 729, 730, 160, 160, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 160, 732, 732, 732, 732, 732, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 160, 160, 160, 160, + + 733, 734, 735, 736, 737, 738, 739, 740, + 16, 17, 16, 17, 16, 17, 16, 17, + 16, 17, 737, 737, 16, 17, 16, 17, + 16, 17, 16, 17, 741, 16, 17, 742, + + 737, 740, 740, 740, 740, 740, 740, 740, + 740, 740, 743, 744, 140, 745, 746, 746, + 747, 748, 748, 748, 748, 748, 737, 737, + 749, 749, 749, 750, 751, 752, 732, 737, + + 160, 753, 739, 753, 739, 753, 739, 753, + 739, 753, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + + 739, 739, 739, 753, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + + 739, 739, 739, 753, 739, 753, 739, 753, + 739, 739, 739, 739, 739, 739, 753, 739, + 739, 739, 739, 739, 739, 754, 754, 160, + 160, 755, 755, 756, 756, 757, 757, 758, + + 759, 760, 761, 760, 761, 760, 761, 760, + 761, 760, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + + 761, 761, 761, 760, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, + + 761, 761, 761, 760, 761, 760, 761, 760, + 761, 761, 761, 761, 761, 761, 760, 761, + 761, 761, 761, 761, 761, 760, 760, 761, + 761, 761, 761, 762, 763, 763, 763, 764, + + 160, 160, 160, 160, 160, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 160, 160, 160, + 160, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 765, + + 765, 765, 765, 765, 765, 765, 765, 765, + 765, 765, 765, 765, 765, 765, 765, 160, + 766, 766, 767, 767, 767, 767, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 160, 160, 160, 160, 160, 160, 160, 160, + + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 770, 770, 770, 770, 770, 770, 770, 770, + 770, 770, 770, 770, 770, 770, 770, 770, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 771, 771, 160, + + 767, 767, 767, 767, 767, 767, 767, 767, + 767, 767, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 771, 772, 772, 772, 772, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 772, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 771, 771, 769, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 772, 772, 772, 772, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 772, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 771, 771, 771, 771, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 160, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 771, + 771, 771, 771, 766, 766, 766, 766, 766, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 771, 771, + + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 771, + + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, + + 739, 739, 739, 739, 739, 739, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 160, 160, 160, 160, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 775, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, + + 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 160, 160, 160, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + + 732, 732, 776, 776, 732, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 732, 776, 732, 732, 732, + 732, 732, 732, 732, 732, 732, 732, 732, + + 732, 776, 732, 732, 732, 776, 732, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 777, 777, 777, 777, 777, 777, 777, 777, + 777, 777, 777, 777, 777, 777, 777, 777, + 777, 777, 777, 777, 777, 777, 777, 778, + 778, 778, 778, 160, 160, 160, 160, 160, + + 779, 779, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 323, 323, 780, 323, 323, 323, 781, 323, + 323, 323, 323, 782, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, + + 323, 323, 323, 464, 464, 782, 782, 464, + 418, 418, 418, 418, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 783, 783, 304, 304, + 160, 160, 160, 160, 160, 160, 160, 160, + + 784, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 784, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 784, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 784, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 784, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 784, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 785, 785, 785, 785, + 784, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 784, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, 785, 785, 785, 785, 785, + + 785, 785, 785, 785, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 786, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, + + 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, + + 739, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 160, 160, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 160, 160, 160, 160, 160, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 160, 160, 160, 160, 160, 160, + + 789, 790, 791, 792, 793, 794, 795, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 796, 797, 798, 799, 800, + 160, 160, 160, 160, 160, 801, 802, 231, + + 231, 231, 231, 231, 231, 231, 231, 231, + 231, 635, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 205, + 231, 231, 231, 231, 231, 205, 231, 205, + + 231, 231, 205, 231, 231, 205, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 600, 742, + + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 235, 235, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 235, 235, 235, 235, 235, 235, 235, 235, + 803, 803, 803, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 803, 803, 803, + + 803, 803, 803, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 803, 803, 803, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 804, 239, 235, 235, + + 423, 423, 423, 423, 423, 423, 423, 423, + 423, 423, 423, 423, 423, 423, 423, 423, + 805, 806, 806, 805, 805, 807, 807, 808, + 809, 810, 160, 160, 160, 160, 160, 160, + + 139, 139, 139, 139, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 736, 747, 747, 811, 811, 600, 742, 600, + 742, 600, 742, 600, 742, 600, 742, 600, + + 742, 600, 742, 600, 742, 752, 752, 812, + 813, 736, 736, 736, 736, 811, 811, 811, + 814, 736, 815, 160, 762, 816, 9, 9, + 747, 16, 17, 16, 17, 16, 17, 817, + + 736, 736, 818, 819, 820, 821, 822, 160, + 736, 12, 13, 736, 160, 160, 160, 160, + 243, 243, 243, 286, 243, 235, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 235, 235, 823, + + 160, 9, 736, 817, 12, 13, 736, 736, + 16, 17, 736, 818, 814, 819, 815, 824, + 825, 826, 827, 828, 829, 830, 831, 832, + 833, 834, 816, 762, 835, 822, 836, 9, + + 736, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 39, 736, 41, 838, 811, + + 838, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 39, 822, 41, 822, 700, + + 701, 735, 16, 17, 734, 762, 840, 760, + 760, 760, 760, 760, 760, 760, 760, 760, + 763, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, + + 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 763, 763, + + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 160, + + 160, 160, 90, 90, 90, 90, 90, 90, + 160, 160, 90, 90, 90, 90, 90, 90, + 160, 160, 90, 90, 90, 90, 90, 90, + 160, 160, 90, 90, 90, 160, 160, 160, + + 48, 12, 822, 838, 737, 12, 12, 160, + 49, 36, 36, 36, 36, 49, 49, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 841, 841, 841, 842, 49, 843, 843, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 160, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + + 308, 308, 308, 308, 308, 308, 308, 160, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 160, 308, 308, 160, 308, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 160, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 160, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 160, 160, 160, 160, 160, + + 844, 845, 846, 160, 160, 160, 160, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 160, 160, 160, 848, + 848, 848, 848, 848, 848, 848, 848, 848, + + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 726, 726, 726, + 726, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 726, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 160, + + 851, 851, 851, 851, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, + + 850, 852, 850, 850, 850, 850, 850, 850, + 850, 850, 852, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 844, + + 323, 323, 323, 323, 160, 160, 160, 160, + 323, 323, 323, 323, 323, 323, 323, 323, + 465, 853, 853, 853, 853, 853, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, + + 854, 854, 854, 854, 854, 854, 855, 855, + 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 856, 856, + + 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 857, 857, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 160, 160, + + 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 858, 858, 858, 858, 858, 858, 205, 205, + 858, 205, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, + + 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, 858, 858, 858, 205, 858, + 858, 205, 205, 205, 858, 205, 205, 858, + + 859, 859, 859, 859, 859, 859, 859, 859, + 859, 859, 859, 859, 859, 859, 859, 859, + 859, 859, 859, 859, 859, 859, 860, 860, + 860, 860, 205, 205, 205, 205, 205, 861, + + 862, 782, 782, 782, 205, 782, 782, 205, + 205, 205, 205, 205, 782, 152, 782, 153, + 862, 862, 862, 862, 205, 862, 862, 862, + 205, 862, 862, 862, 862, 862, 862, 862, + + 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 205, 205, 205, 205, + 153, 643, 152, 205, 205, 205, 205, 781, + + 863, 864, 865, 866, 867, 867, 867, 867, + 205, 205, 205, 205, 205, 205, 205, 205, + 868, 868, 868, 868, 868, 868, 868, 868, + 869, 205, 205, 205, 205, 205, 205, 205, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 481, 481, 481, 481, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 160, + 160, 160, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 872, 873, 874, + 874, 874, 871, 871, 871, 875, 872, 872, + 872, 872, 872, 876, 876, 876, 876, 876, + 876, 876, 876, 877, 877, 877, 877, 877, + 877, 877, 877, 871, 871, 878, 878, 878, + 878, 878, 877, 877, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 878, 878, 878, 878, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 871, 871, 871, 871, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 153, 153, 153, 418, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 879, 879, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 879, 879, 879, 879, + 879, 879, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 160, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 160, 880, 880, + 160, 160, 880, 160, 160, 880, 880, 160, + 160, 880, 880, 880, 880, 160, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 160, 881, 160, 881, 881, 881, + 881, 102, 881, 881, 160, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + + 881, 881, 881, 881, 880, 880, 160, 880, + 880, 880, 880, 160, 160, 880, 880, 880, + 880, 880, 880, 880, 880, 160, 880, 880, + 880, 880, 880, 880, 880, 160, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 160, 880, 880, 880, 880, 160, + 880, 880, 880, 880, 880, 160, 880, 160, + 160, 160, 880, 880, 880, 880, 880, 880, + 880, 160, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 103, 103, 160, 160, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 882, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 882, 881, 881, 881, 881, + 881, 881, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 882, 881, 881, 881, 881, + + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 882, 881, 881, + 881, 881, 881, 881, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 882, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 882, + 881, 881, 881, 881, 881, 881, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 882, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 882, 881, 881, 881, 881, 881, 881, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 880, 880, 880, 880, 880, 880, 880, + 880, 882, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 881, 881, 881, 881, 881, + 881, 881, 881, 882, 881, 881, 881, 881, + 881, 881, 883, 725, 160, 160, 884, 885, + 886, 887, 888, 889, 890, 891, 892, 893, + 884, 885, 886, 887, 888, 889, 890, 891, + 892, 893, 884, 885, 886, 887, 888, 889, + 890, 891, 892, 893, 884, 885, 886, 887, + 888, 889, 890, 891, 892, 893, 884, 885, + 886, 887, 888, 889, 890, 891, 892, 893, + + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 894, 894, + + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 876, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 896, 896, + 896, 896, 896, 896, 896, 896, 894, 894, }; #define GET_PROP_INDEX(ucs4) \ @@ -3618,6 +3618,7 @@ static const QUnicodeTables::Properties uc_properties [] = { { 15, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 80, 0, 0, 80, 0, 3, 5}, { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 80, 0, 0, 80, 0, 3, 5}, { 16, 11, 0, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, -80, -80, 0, 0, 3, 4}, + { 16, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -80, -80, 0, 0, 3, 4}, { 30, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, { 3, 19, 17, 0, 0, -1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0}, { 15, 11, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 15, 0, 0, 15, 0, 3, 5}, @@ -4335,13 +4336,13 @@ static inline const QUnicodeTables::Properties *qGetProp(ushort ucs2) return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties* QT_FASTCALL QUnicodeTables::properties(uint ucs4) +Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(uint ucs4) { int index = GET_PROP_INDEX(ucs4); return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties* QT_FASTCALL QUnicodeTables::properties(ushort ucs2) +Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(ushort ucs2) { int index = GET_PROP_INDEX_UCS2(ucs2); return uc_properties + index; @@ -4382,1446 +4383,1446 @@ static const ushort specialCaseMap [] = { static const unsigned short uc_decomposition_trie[] = { // 0 - 0x3400 - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1564, 1580, 1596, 1612, 1628, 1644, - 1660, 1676, 1692, 1708, 1724, 1740, 1756, 1772, - 1548, 1548, 1788, 1804, 1820, 1836, 1852, 1868, - 1884, 1900, 1916, 1932, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1948, 1548, 1964, 1980, 1548, - 1548, 1548, 1548, 1548, 1996, 1548, 1548, 2012, - 2028, 2044, 2060, 2076, 2092, 2108, 1548, 2124, - 2140, 2156, 1548, 2172, 1548, 2188, 1548, 2204, - 1548, 1548, 1548, 1548, 2220, 2236, 2252, 2268, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 2284, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 2300, 1548, 1548, 1548, 1548, 2316, - 1548, 1548, 1548, 1548, 2332, 2348, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 2364, 2380, 1548, 2396, 1548, 1548, - 1548, 1548, 1548, 1548, 2412, 2428, 1548, 1548, - 1548, 1548, 1548, 2444, 1548, 2460, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2476, 2492, 1548, 1548, - 1548, 2508, 1548, 1548, 2524, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2540, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2556, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 2572, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 2588, 1548, 1548, - 1548, 1548, 1548, 2604, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 2620, 1548, 2636, 1548, 1548, - 2652, 1548, 1548, 1548, 2668, 2684, 2700, 2716, - 2732, 2748, 2764, 2780, 1548, 1548, 1548, 1548, - - 1548, 1548, 2796, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 2812, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 2828, 2844, 1548, 2860, 2876, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 2892, 2908, 2924, 2940, 2956, 2972, - 1548, 2988, 3004, 3020, 1548, 1548, 1548, 1548, - 3036, 3052, 3068, 3084, 3100, 3116, 3132, 3148, - 3164, 3180, 3196, 3212, 3228, 3244, 3260, 3276, - 3292, 3308, 3324, 3340, 3356, 3372, 3388, 3404, - 3420, 3436, 3452, 3468, 3484, 3500, 3516, 3532, - - 3548, 3564, 3580, 3596, 3612, 3628, 1548, 3644, - 3660, 3676, 3692, 1548, 1548, 1548, 1548, 1548, - 3708, 3724, 3740, 3756, 3772, 3788, 3804, 3820, - 1548, 3836, 3852, 1548, 3868, 1548, 1548, 1548, - 3884, 1548, 3900, 3916, 3932, 1548, 3948, 3964, - 3980, 1548, 3996, 1548, 1548, 1548, 4012, 1548, - 1548, 1548, 4028, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 4044, 4060, - 4076, 4092, 4108, 4124, 4140, 4156, 4172, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 4188, 1548, 1548, 1548, 1548, 1548, 1548, 4204, - 1548, 1548, 1548, 1548, 1548, 4220, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 4236, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 4252, 1548, 1548, 1548, 1548, 1548, 4268, - 4284, 4300, 4316, 4332, 4348, 4364, 4380, 4396, - 4412, 4428, 4444, 4460, 4476, 4492, 1548, 1548, - - 4508, 1548, 1548, 4524, 4540, 4556, 4572, 4588, - 1548, 4604, 4620, 4636, 4652, 4668, 1548, 4684, - 1548, 1548, 1548, 4700, 4716, 4732, 4748, 4764, - 4780, 4796, 1548, 1548, 1548, 1548, 1548, 1548, - 4812, 4828, 4844, 4860, 4876, 4892, 4908, 4924, - 4940, 4956, 4972, 4988, 5004, 5020, 5036, 5052, - 5068, 5084, 5100, 5116, 5132, 5148, 5164, 5180, - 5196, 5212, 5228, 5244, 5260, 5276, 5292, 5308, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1564, 1580, 1596, 1612, 1628, 1644, + 1660, 1676, 1692, 1708, 1724, 1740, 1756, 1772, + 1548, 1548, 1788, 1804, 1820, 1836, 1852, 1868, + 1884, 1900, 1916, 1932, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1948, 1548, 1964, 1980, 1548, + 1548, 1548, 1548, 1548, 1996, 1548, 1548, 2012, + 2028, 2044, 2060, 2076, 2092, 2108, 1548, 2124, + 2140, 2156, 1548, 2172, 1548, 2188, 1548, 2204, + 1548, 1548, 1548, 1548, 2220, 2236, 2252, 2268, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 2284, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 2300, 1548, 1548, 1548, 1548, 2316, + 1548, 1548, 1548, 1548, 2332, 2348, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 2364, 2380, 1548, 2396, 1548, 1548, + 1548, 1548, 1548, 1548, 2412, 2428, 1548, 1548, + 1548, 1548, 1548, 2444, 1548, 2460, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2476, 2492, 1548, 1548, + 1548, 2508, 1548, 1548, 2524, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2540, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2556, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 2572, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 2588, 1548, 1548, + 1548, 1548, 1548, 2604, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 2620, 1548, 2636, 1548, 1548, + 2652, 1548, 1548, 1548, 2668, 2684, 2700, 2716, + 2732, 2748, 2764, 2780, 1548, 1548, 1548, 1548, + + 1548, 1548, 2796, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 2812, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 2828, 2844, 1548, 2860, 2876, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 2892, 2908, 2924, 2940, 2956, 2972, + 1548, 2988, 3004, 3020, 1548, 1548, 1548, 1548, + 3036, 3052, 3068, 3084, 3100, 3116, 3132, 3148, + 3164, 3180, 3196, 3212, 3228, 3244, 3260, 3276, + 3292, 3308, 3324, 3340, 3356, 3372, 3388, 3404, + 3420, 3436, 3452, 3468, 3484, 3500, 3516, 3532, + + 3548, 3564, 3580, 3596, 3612, 3628, 1548, 3644, + 3660, 3676, 3692, 1548, 1548, 1548, 1548, 1548, + 3708, 3724, 3740, 3756, 3772, 3788, 3804, 3820, + 1548, 3836, 3852, 1548, 3868, 1548, 1548, 1548, + 3884, 1548, 3900, 3916, 3932, 1548, 3948, 3964, + 3980, 1548, 3996, 1548, 1548, 1548, 4012, 1548, + 1548, 1548, 4028, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 4044, 4060, + 4076, 4092, 4108, 4124, 4140, 4156, 4172, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 4188, 1548, 1548, 1548, 1548, 1548, 1548, 4204, + 1548, 1548, 1548, 1548, 1548, 4220, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 4236, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, + 1548, 4252, 1548, 1548, 1548, 1548, 1548, 4268, + 4284, 4300, 4316, 4332, 4348, 4364, 4380, 4396, + 4412, 4428, 4444, 4460, 4476, 4492, 1548, 1548, + + 4508, 1548, 1548, 4524, 4540, 4556, 4572, 4588, + 1548, 4604, 4620, 4636, 4652, 4668, 1548, 4684, + 1548, 1548, 1548, 4700, 4716, 4732, 4748, 4764, + 4780, 4796, 1548, 1548, 1548, 1548, 1548, 1548, + 4812, 4828, 4844, 4860, 4876, 4892, 4908, 4924, + 4940, 4956, 4972, 4988, 5004, 5020, 5036, 5052, + 5068, 5084, 5100, 5116, 5132, 5148, 5164, 5180, + 5196, 5212, 5228, 5244, 5260, 5276, 5292, 5308, // 0x3400 - 0x30000 - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - - 5324, 5324, 5324, 5324, 5324, 5580, 5836, 6092, - 6348, 6604, 6860, 7116, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 7372, 5324, 5324, - 7628, 7884, 8140, 8396, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, - - 5324, 5324, 5324, 5324, 8652, 8908, 9164, 5324, - 5324, 5324, 5324, 5324, - - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x2, 0xffff, 0x5, 0xffff, 0xffff, 0xffff, 0xffff, 0x7, - - 0xffff, 0xffff, 0xa, 0xc, 0xe, 0x11, 0xffff, 0xffff, - 0x13, 0x16, 0x18, 0xffff, 0x1a, 0x1e, 0x22, 0xffff, - - 0x26, 0x29, 0x2c, 0x2f, 0x32, 0x35, 0xffff, 0x38, - 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d, 0x50, - - 0xffff, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x62, 0xffff, - 0xffff, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0xffff, 0xffff, - - 0x74, 0x77, 0x7a, 0x7d, 0x80, 0x83, 0xffff, 0x86, - 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9b, 0x9e, - - 0xffff, 0xa1, 0xa4, 0xa7, 0xaa, 0xad, 0xb0, 0xffff, - 0xffff, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xffff, 0xc2, - - 0xc5, 0xc8, 0xcb, 0xce, 0xd1, 0xd4, 0xd7, 0xda, - 0xdd, 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef, 0xf2, - - 0xffff, 0xffff, 0xf5, 0xf8, 0xfb, 0xfe, 0x101, 0x104, - 0x107, 0x10a, 0x10d, 0x110, 0x113, 0x116, 0x119, 0x11c, - - 0x11f, 0x122, 0x125, 0x128, 0x12b, 0x12e, 0xffff, 0xffff, - 0x131, 0x134, 0x137, 0x13a, 0x13d, 0x140, 0x143, 0x146, - - 0x149, 0xffff, 0x14c, 0x14f, 0x152, 0x155, 0x158, 0x15b, - 0xffff, 0x15e, 0x161, 0x164, 0x167, 0x16a, 0x16d, 0x170, - - 0x173, 0xffff, 0xffff, 0x176, 0x179, 0x17c, 0x17f, 0x182, - 0x185, 0x188, 0xffff, 0xffff, 0x18b, 0x18e, 0x191, 0x194, - - 0x197, 0x19a, 0xffff, 0xffff, 0x19d, 0x1a0, 0x1a3, 0x1a6, - 0x1a9, 0x1ac, 0x1af, 0x1b2, 0x1b5, 0x1b8, 0x1bb, 0x1be, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + + 5324, 5324, 5324, 5324, 5324, 5580, 5836, 6092, + 6348, 6604, 6860, 7116, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 7372, 5324, 5324, + 7628, 7884, 8140, 8396, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + 5324, 5324, 5324, 5324, 5324, 5324, 5324, 5324, + + 5324, 5324, 5324, 5324, 8652, 8908, 9164, 5324, + 5324, 5324, 5324, 5324, + + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x2, 0xffff, 0x5, 0xffff, 0xffff, 0xffff, 0xffff, 0x7, + + 0xffff, 0xffff, 0xa, 0xc, 0xe, 0x11, 0xffff, 0xffff, + 0x13, 0x16, 0x18, 0xffff, 0x1a, 0x1e, 0x22, 0xffff, + + 0x26, 0x29, 0x2c, 0x2f, 0x32, 0x35, 0xffff, 0x38, + 0x3b, 0x3e, 0x41, 0x44, 0x47, 0x4a, 0x4d, 0x50, + + 0xffff, 0x53, 0x56, 0x59, 0x5c, 0x5f, 0x62, 0xffff, + 0xffff, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0xffff, 0xffff, + + 0x74, 0x77, 0x7a, 0x7d, 0x80, 0x83, 0xffff, 0x86, + 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9b, 0x9e, + + 0xffff, 0xa1, 0xa4, 0xa7, 0xaa, 0xad, 0xb0, 0xffff, + 0xffff, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xffff, 0xc2, + + 0xc5, 0xc8, 0xcb, 0xce, 0xd1, 0xd4, 0xd7, 0xda, + 0xdd, 0xe0, 0xe3, 0xe6, 0xe9, 0xec, 0xef, 0xf2, + + 0xffff, 0xffff, 0xf5, 0xf8, 0xfb, 0xfe, 0x101, 0x104, + 0x107, 0x10a, 0x10d, 0x110, 0x113, 0x116, 0x119, 0x11c, + + 0x11f, 0x122, 0x125, 0x128, 0x12b, 0x12e, 0xffff, 0xffff, + 0x131, 0x134, 0x137, 0x13a, 0x13d, 0x140, 0x143, 0x146, + + 0x149, 0xffff, 0x14c, 0x14f, 0x152, 0x155, 0x158, 0x15b, + 0xffff, 0x15e, 0x161, 0x164, 0x167, 0x16a, 0x16d, 0x170, + + 0x173, 0xffff, 0xffff, 0x176, 0x179, 0x17c, 0x17f, 0x182, + 0x185, 0x188, 0xffff, 0xffff, 0x18b, 0x18e, 0x191, 0x194, + + 0x197, 0x19a, 0xffff, 0xffff, 0x19d, 0x1a0, 0x1a3, 0x1a6, + 0x1a9, 0x1ac, 0x1af, 0x1b2, 0x1b5, 0x1b8, 0x1bb, 0x1be, - 0x1c1, 0x1c4, 0x1c7, 0x1ca, 0x1cd, 0x1d0, 0xffff, 0xffff, - 0x1d3, 0x1d6, 0x1d9, 0x1dc, 0x1df, 0x1e2, 0x1e5, 0x1e8, + 0x1c1, 0x1c4, 0x1c7, 0x1ca, 0x1cd, 0x1d0, 0xffff, 0xffff, + 0x1d3, 0x1d6, 0x1d9, 0x1dc, 0x1df, 0x1e2, 0x1e5, 0x1e8, - 0x1eb, 0x1ee, 0x1f1, 0x1f4, 0x1f7, 0x1fa, 0x1fd, 0x200, - 0x203, 0x206, 0x209, 0x20c, 0x20f, 0x212, 0x215, 0x218, + 0x1eb, 0x1ee, 0x1f1, 0x1f4, 0x1f7, 0x1fa, 0x1fd, 0x200, + 0x203, 0x206, 0x209, 0x20c, 0x20f, 0x212, 0x215, 0x218, - 0x21a, 0x21d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x220, + 0x21a, 0x21d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x220, - 0x223, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x223, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x226, 0x229, 0x22c, 0x22f, - 0x232, 0x235, 0x238, 0x23b, 0x23e, 0x241, 0x244, 0x247, + 0xffff, 0xffff, 0xffff, 0xffff, 0x226, 0x229, 0x22c, 0x22f, + 0x232, 0x235, 0x238, 0x23b, 0x23e, 0x241, 0x244, 0x247, - 0x24a, 0x24d, 0x250, 0x253, 0x256, 0x259, 0x25c, 0x25f, - 0x262, 0x265, 0x268, 0x26b, 0x26e, 0xffff, 0x271, 0x274, + 0x24a, 0x24d, 0x250, 0x253, 0x256, 0x259, 0x25c, 0x25f, + 0x262, 0x265, 0x268, 0x26b, 0x26e, 0xffff, 0x271, 0x274, - 0x277, 0x27a, 0x27d, 0x280, 0xffff, 0xffff, 0x283, 0x286, - 0x289, 0x28c, 0x28f, 0x292, 0x295, 0x298, 0x29b, 0x29e, + 0x277, 0x27a, 0x27d, 0x280, 0xffff, 0xffff, 0x283, 0x286, + 0x289, 0x28c, 0x28f, 0x292, 0x295, 0x298, 0x29b, 0x29e, - 0x2a1, 0x2a4, 0x2a7, 0x2aa, 0x2ad, 0x2b0, 0xffff, 0xffff, - 0x2b3, 0x2b6, 0x2b9, 0x2bc, 0x2bf, 0x2c2, 0x2c5, 0x2c8, + 0x2a1, 0x2a4, 0x2a7, 0x2aa, 0x2ad, 0x2b0, 0xffff, 0xffff, + 0x2b3, 0x2b6, 0x2b9, 0x2bc, 0x2bf, 0x2c2, 0x2c5, 0x2c8, - 0x2cb, 0x2ce, 0x2d1, 0x2d4, 0x2d7, 0x2da, 0x2dd, 0x2e0, - 0x2e3, 0x2e6, 0x2e9, 0x2ec, 0x2ef, 0x2f2, 0x2f5, 0x2f8, + 0x2cb, 0x2ce, 0x2d1, 0x2d4, 0x2d7, 0x2da, 0x2dd, 0x2e0, + 0x2e3, 0x2e6, 0x2e9, 0x2ec, 0x2ef, 0x2f2, 0x2f5, 0x2f8, - 0x2fb, 0x2fe, 0x301, 0x304, 0x307, 0x30a, 0x30d, 0x310, - 0x313, 0x316, 0x319, 0x31c, 0xffff, 0xffff, 0x31f, 0x322, + 0x2fb, 0x2fe, 0x301, 0x304, 0x307, 0x30a, 0x30d, 0x310, + 0x313, 0x316, 0x319, 0x31c, 0xffff, 0xffff, 0x31f, 0x322, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x325, 0x328, - 0x32b, 0x32e, 0x331, 0x334, 0x337, 0x33a, 0x33d, 0x340, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x325, 0x328, + 0x32b, 0x32e, 0x331, 0x334, 0x337, 0x33a, 0x33d, 0x340, - 0x343, 0x346, 0x349, 0x34c, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x343, 0x346, 0x349, 0x34c, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x34f, 0x351, 0x353, 0x355, 0x357, 0x359, 0x35b, 0x35d, - 0x35f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x34f, 0x351, 0x353, 0x355, 0x357, 0x359, 0x35b, 0x35d, + 0x35f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x361, 0x364, 0x367, 0x36a, 0x36d, 0x370, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x361, 0x364, 0x367, 0x36a, 0x36d, 0x370, 0xffff, 0xffff, - 0x373, 0x375, 0x377, 0x379, 0x37b, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x373, 0x375, 0x377, 0x379, 0x37b, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x37d, 0x37f, 0xffff, 0x381, 0x383, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x37d, 0x37f, 0xffff, 0x381, 0x383, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x386, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x388, 0xffff, 0xffff, 0xffff, 0x38b, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x386, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x388, 0xffff, 0xffff, 0xffff, 0x38b, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x38d, 0x390, 0x393, 0x396, - 0x398, 0x39b, 0x39e, 0xffff, 0x3a1, 0xffff, 0x3a4, 0x3a7, + 0xffff, 0xffff, 0xffff, 0xffff, 0x38d, 0x390, 0x393, 0x396, + 0x398, 0x39b, 0x39e, 0xffff, 0x3a1, 0xffff, 0x3a4, 0x3a7, - 0x3aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x3ad, 0x3b0, 0x3b3, 0x3b6, 0x3b9, 0x3bc, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x3ad, 0x3b0, 0x3b3, 0x3b6, 0x3b9, 0x3bc, - 0x3bf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3bf, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x3c2, 0x3c5, 0x3c8, 0x3cb, 0x3ce, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x3c2, 0x3c5, 0x3c8, 0x3cb, 0x3ce, 0xffff, - 0x3d1, 0x3d3, 0x3d5, 0x3d7, 0x3da, 0x3dd, 0x3df, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3d1, 0x3d3, 0x3d5, 0x3d7, 0x3da, 0x3dd, 0x3df, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x3e1, 0x3e3, 0x3e5, 0xffff, 0x3e7, 0x3e9, 0xffff, 0xffff, - 0xffff, 0x3eb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x3e1, 0x3e3, 0x3e5, 0xffff, 0x3e7, 0x3e9, 0xffff, 0xffff, + 0xffff, 0x3eb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x3ed, 0x3f0, 0xffff, 0x3f3, 0xffff, 0xffff, 0xffff, 0x3f6, - 0xffff, 0xffff, 0xffff, 0xffff, 0x3f9, 0x3fc, 0x3ff, 0xffff, + 0x3ed, 0x3f0, 0xffff, 0x3f3, 0xffff, 0xffff, 0xffff, 0x3f6, + 0xffff, 0xffff, 0xffff, 0xffff, 0x3f9, 0x3fc, 0x3ff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x402, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x402, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x405, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x405, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x408, 0x40b, 0xffff, 0x40e, 0xffff, 0xffff, 0xffff, 0x411, - 0xffff, 0xffff, 0xffff, 0xffff, 0x414, 0x417, 0x41a, 0xffff, + 0x408, 0x40b, 0xffff, 0x40e, 0xffff, 0xffff, 0xffff, 0x411, + 0xffff, 0xffff, 0xffff, 0xffff, 0x414, 0x417, 0x41a, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x41d, 0x420, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x41d, 0x420, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x423, 0x426, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x423, 0x426, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x429, 0x42c, 0x42f, 0x432, 0xffff, 0xffff, 0x435, 0x438, - 0xffff, 0xffff, 0x43b, 0x43e, 0x441, 0x444, 0x447, 0x44a, + 0x429, 0x42c, 0x42f, 0x432, 0xffff, 0xffff, 0x435, 0x438, + 0xffff, 0xffff, 0x43b, 0x43e, 0x441, 0x444, 0x447, 0x44a, - 0xffff, 0xffff, 0x44d, 0x450, 0x453, 0x456, 0x459, 0x45c, - 0xffff, 0xffff, 0x45f, 0x462, 0x465, 0x468, 0x46b, 0x46e, + 0xffff, 0xffff, 0x44d, 0x450, 0x453, 0x456, 0x459, 0x45c, + 0xffff, 0xffff, 0x45f, 0x462, 0x465, 0x468, 0x46b, 0x46e, - 0x471, 0x474, 0x477, 0x47a, 0x47d, 0x480, 0xffff, 0xffff, - 0x483, 0x486, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x471, 0x474, 0x477, 0x47a, 0x47d, 0x480, 0xffff, 0xffff, + 0x483, 0x486, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x489, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x489, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x48c, 0x48f, 0x492, 0x495, 0x498, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x48c, 0x48f, 0x492, 0x495, 0x498, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x49b, 0x49e, 0x4a1, - 0x4a4, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x49b, 0x49e, 0x4a1, + 0x4a4, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x4a7, 0xffff, 0x4aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4a7, 0xffff, 0x4aa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x4ad, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x4ad, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x4b0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x4b0, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x4b3, 0xffff, 0xffff, 0x4b6, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x4b3, 0xffff, 0xffff, 0x4b6, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x4b9, 0x4bc, 0x4bf, 0x4c2, 0x4c5, 0x4c8, 0x4cb, 0x4ce, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4b9, 0x4bc, 0x4bf, 0x4c2, 0x4c5, 0x4c8, 0x4cb, 0x4ce, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x4d1, 0x4d4, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x4d1, 0x4d4, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x4d7, 0x4da, 0xffff, 0x4dd, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x4d7, 0x4da, 0xffff, 0x4dd, - 0xffff, 0xffff, 0xffff, 0x4e0, 0xffff, 0xffff, 0x4e3, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x4e0, 0xffff, 0xffff, 0x4e3, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x4e6, 0x4e9, 0x4ec, 0xffff, 0xffff, 0x4ef, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x4e6, 0x4e9, 0x4ec, 0xffff, 0xffff, 0x4ef, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x4f2, 0xffff, 0xffff, 0x4f5, 0x4f8, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x4f2, 0xffff, 0xffff, 0x4f5, 0x4f8, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x4fb, 0x4fe, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x4fb, 0x4fe, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x501, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x501, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x504, 0x507, 0x50a, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x504, 0x507, 0x50a, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x50d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x50d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x510, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x513, - 0x516, 0xffff, 0x519, 0x51c, 0xffff, 0xffff, 0xffff, 0xffff, + 0x510, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x513, + 0x516, 0xffff, 0x519, 0x51c, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x51f, 0x522, 0x525, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x51f, 0x522, 0x525, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x528, 0xffff, 0x52b, 0x52e, 0x531, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x528, 0xffff, 0x52b, 0x52e, 0x531, 0xffff, - 0xffff, 0xffff, 0xffff, 0x534, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x534, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x537, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x537, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x53a, 0x53d, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x53a, 0x53d, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x540, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x540, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x542, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x545, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x542, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x545, 0xffff, 0xffff, - 0xffff, 0xffff, 0x548, 0xffff, 0xffff, 0xffff, 0xffff, 0x54b, - 0xffff, 0xffff, 0xffff, 0xffff, 0x54e, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x548, 0xffff, 0xffff, 0xffff, 0xffff, 0x54b, + 0xffff, 0xffff, 0xffff, 0xffff, 0x54e, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x551, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x551, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x554, 0xffff, 0x557, 0x55a, 0x55d, - 0x560, 0x563, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x554, 0xffff, 0x557, 0x55a, 0x55d, + 0x560, 0x563, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x566, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x566, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x569, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x56c, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x569, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x56c, 0xffff, 0xffff, - 0xffff, 0xffff, 0x56f, 0xffff, 0xffff, 0xffff, 0xffff, 0x572, - 0xffff, 0xffff, 0xffff, 0xffff, 0x575, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x56f, 0xffff, 0xffff, 0xffff, 0xffff, 0x572, + 0xffff, 0xffff, 0xffff, 0xffff, 0x575, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x578, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x578, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x57b, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x57b, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x57e, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x57e, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x580, 0xffff, - 0x583, 0xffff, 0x586, 0xffff, 0x589, 0xffff, 0x58c, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x580, 0xffff, + 0x583, 0xffff, 0x586, 0xffff, 0x589, 0xffff, 0x58c, 0xffff, - 0xffff, 0xffff, 0x58f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x58f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x592, 0xffff, 0x595, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x592, 0xffff, 0x595, 0xffff, 0xffff, - 0x598, 0x59b, 0xffff, 0x59e, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x598, 0x59b, 0xffff, 0x59e, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x5a1, 0x5a3, 0x5a5, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x5a1, 0x5a3, 0x5a5, 0xffff, - 0x5a7, 0x5a9, 0x5ab, 0x5ad, 0x5af, 0x5b1, 0x5b3, 0x5b5, - 0x5b7, 0x5b9, 0x5bb, 0xffff, 0x5bd, 0x5bf, 0x5c1, 0x5c3, + 0x5a7, 0x5a9, 0x5ab, 0x5ad, 0x5af, 0x5b1, 0x5b3, 0x5b5, + 0x5b7, 0x5b9, 0x5bb, 0xffff, 0x5bd, 0x5bf, 0x5c1, 0x5c3, - 0x5c5, 0x5c7, 0x5c9, 0x5cb, 0x5cd, 0x5cf, 0x5d1, 0x5d3, - 0x5d5, 0x5d7, 0x5d9, 0x5db, 0x5dd, 0x5df, 0xffff, 0x5e1, + 0x5c5, 0x5c7, 0x5c9, 0x5cb, 0x5cd, 0x5cf, 0x5d1, 0x5d3, + 0x5d5, 0x5d7, 0x5d9, 0x5db, 0x5dd, 0x5df, 0xffff, 0x5e1, - 0x5e3, 0x5e5, 0x5e7, 0x5e9, 0x5eb, 0x5ed, 0x5ef, 0x5f1, - 0x5f3, 0x5f5, 0x5f7, 0x5f9, 0x5fb, 0x5fd, 0x5ff, 0x601, + 0x5e3, 0x5e5, 0x5e7, 0x5e9, 0x5eb, 0x5ed, 0x5ef, 0x5f1, + 0x5f3, 0x5f5, 0x5f7, 0x5f9, 0x5fb, 0x5fd, 0x5ff, 0x601, - 0x603, 0x605, 0x607, 0x609, 0x60b, 0x60d, 0x60f, 0x611, - 0x613, 0x615, 0x617, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x603, 0x605, 0x607, 0x609, 0x60b, 0x60d, 0x60f, 0x611, + 0x613, 0x615, 0x617, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x619, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x619, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x61b, 0x61d, 0x61f, 0x621, 0x623, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x61b, 0x61d, 0x61f, 0x621, 0x623, - 0x625, 0x627, 0x629, 0x62b, 0x62d, 0x62f, 0x631, 0x633, - 0x635, 0x637, 0x639, 0x63b, 0x63d, 0x63f, 0x641, 0x643, + 0x625, 0x627, 0x629, 0x62b, 0x62d, 0x62f, 0x631, 0x633, + 0x635, 0x637, 0x639, 0x63b, 0x63d, 0x63f, 0x641, 0x643, - 0x645, 0x647, 0x649, 0x64b, 0x64d, 0x64f, 0x651, 0x653, - 0x655, 0x657, 0x659, 0x65b, 0x65d, 0x65f, 0x661, 0x663, + 0x645, 0x647, 0x649, 0x64b, 0x64d, 0x64f, 0x651, 0x653, + 0x655, 0x657, 0x659, 0x65b, 0x65d, 0x65f, 0x661, 0x663, - 0x665, 0x668, 0x66b, 0x66e, 0x671, 0x674, 0x677, 0x67a, - 0x67d, 0x680, 0x683, 0x686, 0x689, 0x68c, 0x68f, 0x692, + 0x665, 0x668, 0x66b, 0x66e, 0x671, 0x674, 0x677, 0x67a, + 0x67d, 0x680, 0x683, 0x686, 0x689, 0x68c, 0x68f, 0x692, - 0x695, 0x698, 0x69b, 0x69e, 0x6a1, 0x6a4, 0x6a7, 0x6aa, - 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6bc, 0x6bf, 0x6c2, + 0x695, 0x698, 0x69b, 0x69e, 0x6a1, 0x6a4, 0x6a7, 0x6aa, + 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6bc, 0x6bf, 0x6c2, - 0x6c5, 0x6c8, 0x6cb, 0x6ce, 0x6d1, 0x6d4, 0x6d7, 0x6da, - 0x6dd, 0x6e0, 0x6e3, 0x6e6, 0x6e9, 0x6ec, 0x6ef, 0x6f2, + 0x6c5, 0x6c8, 0x6cb, 0x6ce, 0x6d1, 0x6d4, 0x6d7, 0x6da, + 0x6dd, 0x6e0, 0x6e3, 0x6e6, 0x6e9, 0x6ec, 0x6ef, 0x6f2, - 0x6f5, 0x6f8, 0x6fb, 0x6fe, 0x701, 0x704, 0x707, 0x70a, - 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71c, 0x71f, 0x722, + 0x6f5, 0x6f8, 0x6fb, 0x6fe, 0x701, 0x704, 0x707, 0x70a, + 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71c, 0x71f, 0x722, - 0x725, 0x728, 0x72b, 0x72e, 0x731, 0x734, 0x737, 0x73a, - 0x73d, 0x740, 0x743, 0x746, 0x749, 0x74c, 0x74f, 0x752, + 0x725, 0x728, 0x72b, 0x72e, 0x731, 0x734, 0x737, 0x73a, + 0x73d, 0x740, 0x743, 0x746, 0x749, 0x74c, 0x74f, 0x752, - 0x755, 0x758, 0x75b, 0x75e, 0x761, 0x764, 0x767, 0x76a, - 0x76d, 0x770, 0x773, 0x776, 0x779, 0x77c, 0x77f, 0x782, + 0x755, 0x758, 0x75b, 0x75e, 0x761, 0x764, 0x767, 0x76a, + 0x76d, 0x770, 0x773, 0x776, 0x779, 0x77c, 0x77f, 0x782, - 0x785, 0x788, 0x78b, 0x78e, 0x791, 0x794, 0x797, 0x79a, - 0x79d, 0x7a0, 0x7a3, 0x7a6, 0x7a9, 0x7ac, 0x7af, 0x7b2, + 0x785, 0x788, 0x78b, 0x78e, 0x791, 0x794, 0x797, 0x79a, + 0x79d, 0x7a0, 0x7a3, 0x7a6, 0x7a9, 0x7ac, 0x7af, 0x7b2, - 0x7b5, 0x7b8, 0x7bb, 0x7be, 0x7c1, 0x7c4, 0x7c7, 0x7ca, - 0x7cd, 0x7d0, 0x7d3, 0x7d6, 0x7d9, 0x7dc, 0x7df, 0x7e2, + 0x7b5, 0x7b8, 0x7bb, 0x7be, 0x7c1, 0x7c4, 0x7c7, 0x7ca, + 0x7cd, 0x7d0, 0x7d3, 0x7d6, 0x7d9, 0x7dc, 0x7df, 0x7e2, - 0x7e5, 0x7e8, 0x7eb, 0x7ee, 0x7f1, 0x7f4, 0x7f7, 0x7fa, - 0x7fd, 0x800, 0x803, 0x806, 0x809, 0x80c, 0x80f, 0x812, + 0x7e5, 0x7e8, 0x7eb, 0x7ee, 0x7f1, 0x7f4, 0x7f7, 0x7fa, + 0x7fd, 0x800, 0x803, 0x806, 0x809, 0x80c, 0x80f, 0x812, - 0x815, 0x818, 0x81b, 0x81e, 0x821, 0x824, 0x827, 0x82a, - 0x82d, 0x830, 0x833, 0x836, 0xffff, 0xffff, 0xffff, 0xffff, + 0x815, 0x818, 0x81b, 0x81e, 0x821, 0x824, 0x827, 0x82a, + 0x82d, 0x830, 0x833, 0x836, 0xffff, 0xffff, 0xffff, 0xffff, - 0x839, 0x83c, 0x83f, 0x842, 0x845, 0x848, 0x84b, 0x84e, - 0x851, 0x854, 0x857, 0x85a, 0x85d, 0x860, 0x863, 0x866, + 0x839, 0x83c, 0x83f, 0x842, 0x845, 0x848, 0x84b, 0x84e, + 0x851, 0x854, 0x857, 0x85a, 0x85d, 0x860, 0x863, 0x866, - 0x869, 0x86c, 0x86f, 0x872, 0x875, 0x878, 0x87b, 0x87e, - 0x881, 0x884, 0x887, 0x88a, 0x88d, 0x890, 0x893, 0x896, + 0x869, 0x86c, 0x86f, 0x872, 0x875, 0x878, 0x87b, 0x87e, + 0x881, 0x884, 0x887, 0x88a, 0x88d, 0x890, 0x893, 0x896, - 0x899, 0x89c, 0x89f, 0x8a2, 0x8a5, 0x8a8, 0x8ab, 0x8ae, - 0x8b1, 0x8b4, 0x8b7, 0x8ba, 0x8bd, 0x8c0, 0x8c3, 0x8c6, + 0x899, 0x89c, 0x89f, 0x8a2, 0x8a5, 0x8a8, 0x8ab, 0x8ae, + 0x8b1, 0x8b4, 0x8b7, 0x8ba, 0x8bd, 0x8c0, 0x8c3, 0x8c6, - 0x8c9, 0x8cc, 0x8cf, 0x8d2, 0x8d5, 0x8d8, 0x8db, 0x8de, - 0x8e1, 0x8e4, 0x8e7, 0x8ea, 0x8ed, 0x8f0, 0x8f3, 0x8f6, + 0x8c9, 0x8cc, 0x8cf, 0x8d2, 0x8d5, 0x8d8, 0x8db, 0x8de, + 0x8e1, 0x8e4, 0x8e7, 0x8ea, 0x8ed, 0x8f0, 0x8f3, 0x8f6, - 0x8f9, 0x8fc, 0x8ff, 0x902, 0x905, 0x908, 0x90b, 0x90e, - 0x911, 0x914, 0x917, 0x91a, 0x91d, 0x920, 0x923, 0x926, + 0x8f9, 0x8fc, 0x8ff, 0x902, 0x905, 0x908, 0x90b, 0x90e, + 0x911, 0x914, 0x917, 0x91a, 0x91d, 0x920, 0x923, 0x926, - 0x929, 0x92c, 0x92f, 0x932, 0x935, 0x938, 0x93b, 0x93e, - 0x941, 0x944, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x929, 0x92c, 0x92f, 0x932, 0x935, 0x938, 0x93b, 0x93e, + 0x941, 0x944, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x947, 0x94a, 0x94d, 0x950, 0x953, 0x956, 0x959, 0x95c, - 0x95f, 0x962, 0x965, 0x968, 0x96b, 0x96e, 0x971, 0x974, + 0x947, 0x94a, 0x94d, 0x950, 0x953, 0x956, 0x959, 0x95c, + 0x95f, 0x962, 0x965, 0x968, 0x96b, 0x96e, 0x971, 0x974, - 0x977, 0x97a, 0x97d, 0x980, 0x983, 0x986, 0xffff, 0xffff, - 0x989, 0x98c, 0x98f, 0x992, 0x995, 0x998, 0xffff, 0xffff, + 0x977, 0x97a, 0x97d, 0x980, 0x983, 0x986, 0xffff, 0xffff, + 0x989, 0x98c, 0x98f, 0x992, 0x995, 0x998, 0xffff, 0xffff, - 0x99b, 0x99e, 0x9a1, 0x9a4, 0x9a7, 0x9aa, 0x9ad, 0x9b0, - 0x9b3, 0x9b6, 0x9b9, 0x9bc, 0x9bf, 0x9c2, 0x9c5, 0x9c8, + 0x99b, 0x99e, 0x9a1, 0x9a4, 0x9a7, 0x9aa, 0x9ad, 0x9b0, + 0x9b3, 0x9b6, 0x9b9, 0x9bc, 0x9bf, 0x9c2, 0x9c5, 0x9c8, - 0x9cb, 0x9ce, 0x9d1, 0x9d4, 0x9d7, 0x9da, 0x9dd, 0x9e0, - 0x9e3, 0x9e6, 0x9e9, 0x9ec, 0x9ef, 0x9f2, 0x9f5, 0x9f8, + 0x9cb, 0x9ce, 0x9d1, 0x9d4, 0x9d7, 0x9da, 0x9dd, 0x9e0, + 0x9e3, 0x9e6, 0x9e9, 0x9ec, 0x9ef, 0x9f2, 0x9f5, 0x9f8, - 0x9fb, 0x9fe, 0xa01, 0xa04, 0xa07, 0xa0a, 0xffff, 0xffff, - 0xa0d, 0xa10, 0xa13, 0xa16, 0xa19, 0xa1c, 0xffff, 0xffff, + 0x9fb, 0x9fe, 0xa01, 0xa04, 0xa07, 0xa0a, 0xffff, 0xffff, + 0xa0d, 0xa10, 0xa13, 0xa16, 0xa19, 0xa1c, 0xffff, 0xffff, - 0xa1f, 0xa22, 0xa25, 0xa28, 0xa2b, 0xa2e, 0xa31, 0xa34, - 0xffff, 0xa37, 0xffff, 0xa3a, 0xffff, 0xa3d, 0xffff, 0xa40, + 0xa1f, 0xa22, 0xa25, 0xa28, 0xa2b, 0xa2e, 0xa31, 0xa34, + 0xffff, 0xa37, 0xffff, 0xa3a, 0xffff, 0xa3d, 0xffff, 0xa40, - 0xa43, 0xa46, 0xa49, 0xa4c, 0xa4f, 0xa52, 0xa55, 0xa58, - 0xa5b, 0xa5e, 0xa61, 0xa64, 0xa67, 0xa6a, 0xa6d, 0xa70, + 0xa43, 0xa46, 0xa49, 0xa4c, 0xa4f, 0xa52, 0xa55, 0xa58, + 0xa5b, 0xa5e, 0xa61, 0xa64, 0xa67, 0xa6a, 0xa6d, 0xa70, - 0xa73, 0xa76, 0xa78, 0xa7b, 0xa7d, 0xa80, 0xa82, 0xa85, - 0xa87, 0xa8a, 0xa8c, 0xa8f, 0xa91, 0xa94, 0xffff, 0xffff, + 0xa73, 0xa76, 0xa78, 0xa7b, 0xa7d, 0xa80, 0xa82, 0xa85, + 0xa87, 0xa8a, 0xa8c, 0xa8f, 0xa91, 0xa94, 0xffff, 0xffff, - 0xa96, 0xa99, 0xa9c, 0xa9f, 0xaa2, 0xaa5, 0xaa8, 0xaab, - 0xaae, 0xab1, 0xab4, 0xab7, 0xaba, 0xabd, 0xac0, 0xac3, + 0xa96, 0xa99, 0xa9c, 0xa9f, 0xaa2, 0xaa5, 0xaa8, 0xaab, + 0xaae, 0xab1, 0xab4, 0xab7, 0xaba, 0xabd, 0xac0, 0xac3, - 0xac6, 0xac9, 0xacc, 0xacf, 0xad2, 0xad5, 0xad8, 0xadb, - 0xade, 0xae1, 0xae4, 0xae7, 0xaea, 0xaed, 0xaf0, 0xaf3, + 0xac6, 0xac9, 0xacc, 0xacf, 0xad2, 0xad5, 0xad8, 0xadb, + 0xade, 0xae1, 0xae4, 0xae7, 0xaea, 0xaed, 0xaf0, 0xaf3, - 0xaf6, 0xaf9, 0xafc, 0xaff, 0xb02, 0xb05, 0xb08, 0xb0b, - 0xb0e, 0xb11, 0xb14, 0xb17, 0xb1a, 0xb1d, 0xb20, 0xb23, + 0xaf6, 0xaf9, 0xafc, 0xaff, 0xb02, 0xb05, 0xb08, 0xb0b, + 0xb0e, 0xb11, 0xb14, 0xb17, 0xb1a, 0xb1d, 0xb20, 0xb23, - 0xb26, 0xb29, 0xb2c, 0xb2f, 0xb32, 0xffff, 0xb35, 0xb38, - 0xb3b, 0xb3e, 0xb41, 0xb44, 0xb46, 0xb49, 0xb4c, 0xb4e, + 0xb26, 0xb29, 0xb2c, 0xb2f, 0xb32, 0xffff, 0xb35, 0xb38, + 0xb3b, 0xb3e, 0xb41, 0xb44, 0xb46, 0xb49, 0xb4c, 0xb4e, - 0xb51, 0xb54, 0xb57, 0xb5a, 0xb5d, 0xffff, 0xb60, 0xb63, - 0xb66, 0xb69, 0xb6b, 0xb6e, 0xb70, 0xb73, 0xb76, 0xb79, + 0xb51, 0xb54, 0xb57, 0xb5a, 0xb5d, 0xffff, 0xb60, 0xb63, + 0xb66, 0xb69, 0xb6b, 0xb6e, 0xb70, 0xb73, 0xb76, 0xb79, - 0xb7c, 0xb7f, 0xb82, 0xb85, 0xffff, 0xffff, 0xb87, 0xb8a, - 0xb8d, 0xb90, 0xb93, 0xb96, 0xffff, 0xb98, 0xb9b, 0xb9e, + 0xb7c, 0xb7f, 0xb82, 0xb85, 0xffff, 0xffff, 0xb87, 0xb8a, + 0xb8d, 0xb90, 0xb93, 0xb96, 0xffff, 0xb98, 0xb9b, 0xb9e, - 0xba1, 0xba4, 0xba7, 0xbaa, 0xbac, 0xbaf, 0xbb2, 0xbb5, - 0xbb8, 0xbbb, 0xbbe, 0xbc1, 0xbc3, 0xbc6, 0xbc9, 0xbcb, + 0xba1, 0xba4, 0xba7, 0xbaa, 0xbac, 0xbaf, 0xbb2, 0xbb5, + 0xbb8, 0xbbb, 0xbbe, 0xbc1, 0xbc3, 0xbc6, 0xbc9, 0xbcb, - 0xffff, 0xffff, 0xbcd, 0xbd0, 0xbd3, 0xffff, 0xbd6, 0xbd9, - 0xbdc, 0xbdf, 0xbe1, 0xbe4, 0xbe6, 0xbe9, 0xbeb, 0xffff, + 0xffff, 0xffff, 0xbcd, 0xbd0, 0xbd3, 0xffff, 0xbd6, 0xbd9, + 0xbdc, 0xbdf, 0xbe1, 0xbe4, 0xbe6, 0xbe9, 0xbeb, 0xffff, - 0xbee, 0xbf0, 0xbf2, 0xbf4, 0xbf6, 0xbf8, 0xbfa, 0xbfc, - 0xbfe, 0xc00, 0xc02, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xbee, 0xbf0, 0xbf2, 0xbf4, 0xbf6, 0xbf8, 0xbfa, 0xbfc, + 0xbfe, 0xc00, 0xc02, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xc04, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc06, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xc04, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc06, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xc09, 0xc0b, 0xc0e, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc12, + 0xffff, 0xffff, 0xffff, 0xffff, 0xc09, 0xc0b, 0xc0e, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc12, - 0xffff, 0xffff, 0xffff, 0xc14, 0xc17, 0xffff, 0xc1b, 0xc1e, - 0xffff, 0xffff, 0xffff, 0xffff, 0xc22, 0xffff, 0xc25, 0xffff, + 0xffff, 0xffff, 0xffff, 0xc14, 0xc17, 0xffff, 0xc1b, 0xc1e, + 0xffff, 0xffff, 0xffff, 0xffff, 0xc22, 0xffff, 0xc25, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc28, - 0xc2b, 0xc2e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc28, + 0xc2b, 0xc2e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc31, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc36, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc31, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xc36, - 0xc38, 0xc3a, 0xffff, 0xffff, 0xc3c, 0xc3e, 0xc40, 0xc42, - 0xc44, 0xc46, 0xc48, 0xc4a, 0xc4c, 0xc4e, 0xc50, 0xc52, + 0xc38, 0xc3a, 0xffff, 0xffff, 0xc3c, 0xc3e, 0xc40, 0xc42, + 0xc44, 0xc46, 0xc48, 0xc4a, 0xc4c, 0xc4e, 0xc50, 0xc52, - 0xc54, 0xc56, 0xc58, 0xc5a, 0xc5c, 0xc5e, 0xc60, 0xc62, - 0xc64, 0xc66, 0xc68, 0xc6a, 0xc6c, 0xc6e, 0xc70, 0xffff, + 0xc54, 0xc56, 0xc58, 0xc5a, 0xc5c, 0xc5e, 0xc60, 0xc62, + 0xc64, 0xc66, 0xc68, 0xc6a, 0xc6c, 0xc6e, 0xc70, 0xffff, - 0xc72, 0xc74, 0xc76, 0xc78, 0xc7a, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xc72, 0xc74, 0xc76, 0xc78, 0xc7a, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xc7c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xc7c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xc7f, 0xc83, 0xc87, 0xc89, 0xffff, 0xc8c, 0xc90, 0xc94, - 0xffff, 0xc96, 0xc99, 0xc9b, 0xc9d, 0xc9f, 0xca1, 0xca3, + 0xc7f, 0xc83, 0xc87, 0xc89, 0xffff, 0xc8c, 0xc90, 0xc94, + 0xffff, 0xc96, 0xc99, 0xc9b, 0xc9d, 0xc9f, 0xca1, 0xca3, - 0xca5, 0xca7, 0xca9, 0xcab, 0xffff, 0xcad, 0xcaf, 0xffff, - 0xffff, 0xcb2, 0xcb4, 0xcb6, 0xcb8, 0xcba, 0xffff, 0xffff, + 0xca5, 0xca7, 0xca9, 0xcab, 0xffff, 0xcad, 0xcaf, 0xffff, + 0xffff, 0xcb2, 0xcb4, 0xcb6, 0xcb8, 0xcba, 0xffff, 0xffff, - 0xcbc, 0xcbf, 0xcc3, 0xffff, 0xcc6, 0xffff, 0xcc8, 0xffff, - 0xcca, 0xffff, 0xccc, 0xcce, 0xcd0, 0xcd2, 0xffff, 0xcd4, + 0xcbc, 0xcbf, 0xcc3, 0xffff, 0xcc6, 0xffff, 0xcc8, 0xffff, + 0xcca, 0xffff, 0xccc, 0xcce, 0xcd0, 0xcd2, 0xffff, 0xcd4, - 0xcd6, 0xcd8, 0xffff, 0xcda, 0xcdc, 0xcde, 0xce0, 0xce2, - 0xce4, 0xce6, 0xffff, 0xce8, 0xcec, 0xcee, 0xcf0, 0xcf2, + 0xcd6, 0xcd8, 0xffff, 0xcda, 0xcdc, 0xcde, 0xce0, 0xce2, + 0xce4, 0xce6, 0xffff, 0xce8, 0xcec, 0xcee, 0xcf0, 0xcf2, - 0xcf4, 0xffff, 0xffff, 0xffff, 0xffff, 0xcf6, 0xcf8, 0xcfa, - 0xcfc, 0xcfe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xcf4, 0xffff, 0xffff, 0xffff, 0xffff, 0xcf6, 0xcf8, 0xcfa, + 0xcfc, 0xcfe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10, - 0xd14, 0xd18, 0xd1c, 0xd20, 0xd24, 0xd28, 0xd2c, 0xd30, + 0xffff, 0xffff, 0xffff, 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10, + 0xd14, 0xd18, 0xd1c, 0xd20, 0xd24, 0xd28, 0xd2c, 0xd30, - 0xd33, 0xd35, 0xd38, 0xd3c, 0xd3f, 0xd41, 0xd44, 0xd48, - 0xd4d, 0xd50, 0xd52, 0xd55, 0xd59, 0xd5b, 0xd5d, 0xd5f, + 0xd33, 0xd35, 0xd38, 0xd3c, 0xd3f, 0xd41, 0xd44, 0xd48, + 0xd4d, 0xd50, 0xd52, 0xd55, 0xd59, 0xd5b, 0xd5d, 0xd5f, - 0xd61, 0xd63, 0xd66, 0xd6a, 0xd6d, 0xd6f, 0xd72, 0xd76, - 0xd7b, 0xd7e, 0xd80, 0xd83, 0xd87, 0xd89, 0xd8b, 0xd8d, + 0xd61, 0xd63, 0xd66, 0xd6a, 0xd6d, 0xd6f, 0xd72, 0xd76, + 0xd7b, 0xd7e, 0xd80, 0xd83, 0xd87, 0xd89, 0xd8b, 0xd8d, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xd8f, 0xd92, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xd8f, 0xd92, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd95, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd95, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd98, 0xd9b, 0xd9e, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd98, 0xd9b, 0xd9e, - 0xffff, 0xffff, 0xffff, 0xffff, 0xda1, 0xffff, 0xffff, 0xffff, - 0xffff, 0xda4, 0xffff, 0xffff, 0xda7, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xda1, 0xffff, 0xffff, 0xffff, + 0xffff, 0xda4, 0xffff, 0xffff, 0xda7, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xdaa, 0xffff, 0xdad, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xdb0, 0xdb3, 0xffff, 0xdb7, + 0xffff, 0xffff, 0xffff, 0xffff, 0xdaa, 0xffff, 0xdad, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xdb0, 0xdb3, 0xffff, 0xdb7, - 0xdba, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xdba, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xdbe, 0xffff, 0xffff, 0xdc1, 0xffff, 0xffff, 0xdc4, - 0xffff, 0xdc7, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xdbe, 0xffff, 0xffff, 0xdc1, 0xffff, 0xffff, 0xdc4, + 0xffff, 0xdc7, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xdca, 0xffff, 0xdcd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xdd0, 0xdd3, 0xdd6, + 0xdca, 0xffff, 0xdcd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xdd0, 0xdd3, 0xdd6, - 0xdd9, 0xddc, 0xffff, 0xffff, 0xddf, 0xde2, 0xffff, 0xffff, - 0xde5, 0xde8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xdd9, 0xddc, 0xffff, 0xffff, 0xddf, 0xde2, 0xffff, 0xffff, + 0xde5, 0xde8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xdeb, 0xdee, 0xffff, 0xffff, 0xdf1, 0xdf4, 0xffff, 0xffff, - 0xdf7, 0xdfa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xdeb, 0xdee, 0xffff, 0xffff, 0xdf1, 0xdf4, 0xffff, 0xffff, + 0xdf7, 0xdfa, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xdfd, 0xe00, 0xe03, 0xe06, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xdfd, 0xe00, 0xe03, 0xe06, - 0xe09, 0xe0c, 0xe0f, 0xe12, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xe15, 0xe18, 0xe1b, 0xe1e, 0xffff, 0xffff, + 0xe09, 0xe0c, 0xe0f, 0xe12, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xe15, 0xe18, 0xe1b, 0xe1e, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xe21, 0xe23, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xe21, 0xe23, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xe25, 0xe27, 0xe29, 0xe2b, 0xe2d, 0xe2f, 0xe31, 0xe33, - 0xe35, 0xe37, 0xe3a, 0xe3d, 0xe40, 0xe43, 0xe46, 0xe49, + 0xe25, 0xe27, 0xe29, 0xe2b, 0xe2d, 0xe2f, 0xe31, 0xe33, + 0xe35, 0xe37, 0xe3a, 0xe3d, 0xe40, 0xe43, 0xe46, 0xe49, - 0xe4c, 0xe4f, 0xe52, 0xe55, 0xe58, 0xe5c, 0xe60, 0xe64, - 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe81, 0xe86, + 0xe4c, 0xe4f, 0xe52, 0xe55, 0xe58, 0xe5c, 0xe60, 0xe64, + 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe81, 0xe86, - 0xe8b, 0xe90, 0xe95, 0xe9a, 0xe9f, 0xea4, 0xea9, 0xeae, - 0xeb3, 0xeb6, 0xeb9, 0xebc, 0xebf, 0xec2, 0xec5, 0xec8, + 0xe8b, 0xe90, 0xe95, 0xe9a, 0xe9f, 0xea4, 0xea9, 0xeae, + 0xeb3, 0xeb6, 0xeb9, 0xebc, 0xebf, 0xec2, 0xec5, 0xec8, - 0xecb, 0xece, 0xed2, 0xed6, 0xeda, 0xede, 0xee2, 0xee6, - 0xeea, 0xeee, 0xef2, 0xef6, 0xefa, 0xefe, 0xf02, 0xf06, + 0xecb, 0xece, 0xed2, 0xed6, 0xeda, 0xede, 0xee2, 0xee6, + 0xeea, 0xeee, 0xef2, 0xef6, 0xefa, 0xefe, 0xf02, 0xf06, - 0xf0a, 0xf0e, 0xf12, 0xf16, 0xf1a, 0xf1e, 0xf22, 0xf26, - 0xf2a, 0xf2e, 0xf32, 0xf36, 0xf3a, 0xf3e, 0xf42, 0xf46, + 0xf0a, 0xf0e, 0xf12, 0xf16, 0xf1a, 0xf1e, 0xf22, 0xf26, + 0xf2a, 0xf2e, 0xf32, 0xf36, 0xf3a, 0xf3e, 0xf42, 0xf46, - 0xf4a, 0xf4e, 0xf52, 0xf56, 0xf5a, 0xf5e, 0xf62, 0xf64, - 0xf66, 0xf68, 0xf6a, 0xf6c, 0xf6e, 0xf70, 0xf72, 0xf74, + 0xf4a, 0xf4e, 0xf52, 0xf56, 0xf5a, 0xf5e, 0xf62, 0xf64, + 0xf66, 0xf68, 0xf6a, 0xf6c, 0xf6e, 0xf70, 0xf72, 0xf74, - 0xf76, 0xf78, 0xf7a, 0xf7c, 0xf7e, 0xf80, 0xf82, 0xf84, - 0xf86, 0xf88, 0xf8a, 0xf8c, 0xf8e, 0xf90, 0xf92, 0xf94, + 0xf76, 0xf78, 0xf7a, 0xf7c, 0xf7e, 0xf80, 0xf82, 0xf84, + 0xf86, 0xf88, 0xf8a, 0xf8c, 0xf8e, 0xf90, 0xf92, 0xf94, - 0xf96, 0xf98, 0xf9a, 0xf9c, 0xf9e, 0xfa0, 0xfa2, 0xfa4, - 0xfa6, 0xfa8, 0xfaa, 0xfac, 0xfae, 0xfb0, 0xfb2, 0xfb4, + 0xf96, 0xf98, 0xf9a, 0xf9c, 0xf9e, 0xfa0, 0xfa2, 0xfa4, + 0xfa6, 0xfa8, 0xfaa, 0xfac, 0xfae, 0xfb0, 0xfb2, 0xfb4, - 0xfb6, 0xfb8, 0xfba, 0xfbc, 0xfbe, 0xfc0, 0xfc2, 0xfc4, - 0xfc6, 0xfc8, 0xfca, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xfb6, 0xfb8, 0xfba, 0xfbc, 0xfbe, 0xfc0, 0xfc2, 0xfc4, + 0xfc6, 0xfc8, 0xfca, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xfcc, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xfcc, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xfd1, 0xfd5, 0xfd8, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xfd1, 0xfd5, 0xfd8, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xfdc, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xfdc, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfdf, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfdf, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfe1, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xfe1, - 0xffff, 0xffff, 0xffff, 0xfe3, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xfe3, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xfe5, 0xfe7, 0xfe9, 0xfeb, 0xfed, 0xfef, 0xff1, 0xff3, - 0xff5, 0xff7, 0xff9, 0xffb, 0xffd, 0xfff, 0x1001, 0x1003, + 0xfe5, 0xfe7, 0xfe9, 0xfeb, 0xfed, 0xfef, 0xff1, 0xff3, + 0xff5, 0xff7, 0xff9, 0xffb, 0xffd, 0xfff, 0x1001, 0x1003, - 0x1005, 0x1007, 0x1009, 0x100b, 0x100d, 0x100f, 0x1011, 0x1013, - 0x1015, 0x1017, 0x1019, 0x101b, 0x101d, 0x101f, 0x1021, 0x1023, + 0x1005, 0x1007, 0x1009, 0x100b, 0x100d, 0x100f, 0x1011, 0x1013, + 0x1015, 0x1017, 0x1019, 0x101b, 0x101d, 0x101f, 0x1021, 0x1023, - 0x1025, 0x1027, 0x1029, 0x102b, 0x102d, 0x102f, 0x1031, 0x1033, - 0x1035, 0x1037, 0x1039, 0x103b, 0x103d, 0x103f, 0x1041, 0x1043, + 0x1025, 0x1027, 0x1029, 0x102b, 0x102d, 0x102f, 0x1031, 0x1033, + 0x1035, 0x1037, 0x1039, 0x103b, 0x103d, 0x103f, 0x1041, 0x1043, - 0x1045, 0x1047, 0x1049, 0x104b, 0x104d, 0x104f, 0x1051, 0x1053, - 0x1055, 0x1057, 0x1059, 0x105b, 0x105d, 0x105f, 0x1061, 0x1063, + 0x1045, 0x1047, 0x1049, 0x104b, 0x104d, 0x104f, 0x1051, 0x1053, + 0x1055, 0x1057, 0x1059, 0x105b, 0x105d, 0x105f, 0x1061, 0x1063, - 0x1065, 0x1067, 0x1069, 0x106b, 0x106d, 0x106f, 0x1071, 0x1073, - 0x1075, 0x1077, 0x1079, 0x107b, 0x107d, 0x107f, 0x1081, 0x1083, + 0x1065, 0x1067, 0x1069, 0x106b, 0x106d, 0x106f, 0x1071, 0x1073, + 0x1075, 0x1077, 0x1079, 0x107b, 0x107d, 0x107f, 0x1081, 0x1083, - 0x1085, 0x1087, 0x1089, 0x108b, 0x108d, 0x108f, 0x1091, 0x1093, - 0x1095, 0x1097, 0x1099, 0x109b, 0x109d, 0x109f, 0x10a1, 0x10a3, + 0x1085, 0x1087, 0x1089, 0x108b, 0x108d, 0x108f, 0x1091, 0x1093, + 0x1095, 0x1097, 0x1099, 0x109b, 0x109d, 0x109f, 0x10a1, 0x10a3, - 0x10a5, 0x10a7, 0x10a9, 0x10ab, 0x10ad, 0x10af, 0x10b1, 0x10b3, - 0x10b5, 0x10b7, 0x10b9, 0x10bb, 0x10bd, 0x10bf, 0x10c1, 0x10c3, + 0x10a5, 0x10a7, 0x10a9, 0x10ab, 0x10ad, 0x10af, 0x10b1, 0x10b3, + 0x10b5, 0x10b7, 0x10b9, 0x10bb, 0x10bd, 0x10bf, 0x10c1, 0x10c3, - 0x10c5, 0x10c7, 0x10c9, 0x10cb, 0x10cd, 0x10cf, 0x10d1, 0x10d3, - 0x10d5, 0x10d7, 0x10d9, 0x10db, 0x10dd, 0x10df, 0x10e1, 0x10e3, + 0x10c5, 0x10c7, 0x10c9, 0x10cb, 0x10cd, 0x10cf, 0x10d1, 0x10d3, + 0x10d5, 0x10d7, 0x10d9, 0x10db, 0x10dd, 0x10df, 0x10e1, 0x10e3, - 0x10e5, 0x10e7, 0x10e9, 0x10eb, 0x10ed, 0x10ef, 0x10f1, 0x10f3, - 0x10f5, 0x10f7, 0x10f9, 0x10fb, 0x10fd, 0x10ff, 0x1101, 0x1103, + 0x10e5, 0x10e7, 0x10e9, 0x10eb, 0x10ed, 0x10ef, 0x10f1, 0x10f3, + 0x10f5, 0x10f7, 0x10f9, 0x10fb, 0x10fd, 0x10ff, 0x1101, 0x1103, - 0x1105, 0x1107, 0x1109, 0x110b, 0x110d, 0x110f, 0x1111, 0x1113, - 0x1115, 0x1117, 0x1119, 0x111b, 0x111d, 0x111f, 0x1121, 0x1123, + 0x1105, 0x1107, 0x1109, 0x110b, 0x110d, 0x110f, 0x1111, 0x1113, + 0x1115, 0x1117, 0x1119, 0x111b, 0x111d, 0x111f, 0x1121, 0x1123, - 0x1125, 0x1127, 0x1129, 0x112b, 0x112d, 0x112f, 0x1131, 0x1133, - 0x1135, 0x1137, 0x1139, 0x113b, 0x113d, 0x113f, 0x1141, 0x1143, + 0x1125, 0x1127, 0x1129, 0x112b, 0x112d, 0x112f, 0x1131, 0x1133, + 0x1135, 0x1137, 0x1139, 0x113b, 0x113d, 0x113f, 0x1141, 0x1143, - 0x1145, 0x1147, 0x1149, 0x114b, 0x114d, 0x114f, 0x1151, 0x1153, - 0x1155, 0x1157, 0x1159, 0x115b, 0x115d, 0x115f, 0x1161, 0x1163, + 0x1145, 0x1147, 0x1149, 0x114b, 0x114d, 0x114f, 0x1151, 0x1153, + 0x1155, 0x1157, 0x1159, 0x115b, 0x115d, 0x115f, 0x1161, 0x1163, - 0x1165, 0x1167, 0x1169, 0x116b, 0x116d, 0x116f, 0x1171, 0x1173, - 0x1175, 0x1177, 0x1179, 0x117b, 0x117d, 0x117f, 0x1181, 0x1183, + 0x1165, 0x1167, 0x1169, 0x116b, 0x116d, 0x116f, 0x1171, 0x1173, + 0x1175, 0x1177, 0x1179, 0x117b, 0x117d, 0x117f, 0x1181, 0x1183, - 0x1185, 0x1187, 0x1189, 0x118b, 0x118d, 0x118f, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1185, 0x1187, 0x1189, 0x118b, 0x118d, 0x118f, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x1191, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1191, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1193, 0xffff, - 0x1195, 0x1197, 0x1199, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1193, 0xffff, + 0x1195, 0x1197, 0x1199, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x119b, 0xffff, 0x119e, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x119b, 0xffff, 0x119e, 0xffff, - 0x11a1, 0xffff, 0x11a4, 0xffff, 0x11a7, 0xffff, 0x11aa, 0xffff, - 0x11ad, 0xffff, 0x11b0, 0xffff, 0x11b3, 0xffff, 0x11b6, 0xffff, + 0x11a1, 0xffff, 0x11a4, 0xffff, 0x11a7, 0xffff, 0x11aa, 0xffff, + 0x11ad, 0xffff, 0x11b0, 0xffff, 0x11b3, 0xffff, 0x11b6, 0xffff, - 0x11b9, 0xffff, 0x11bc, 0xffff, 0xffff, 0x11bf, 0xffff, 0x11c2, - 0xffff, 0x11c5, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x11b9, 0xffff, 0x11bc, 0xffff, 0xffff, 0x11bf, 0xffff, 0x11c2, + 0xffff, 0x11c5, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x11c8, 0x11cb, 0xffff, 0x11ce, 0x11d1, 0xffff, 0x11d4, 0x11d7, - 0xffff, 0x11da, 0x11dd, 0xffff, 0x11e0, 0x11e3, 0xffff, 0xffff, + 0x11c8, 0x11cb, 0xffff, 0x11ce, 0x11d1, 0xffff, 0x11d4, 0x11d7, + 0xffff, 0x11da, 0x11dd, 0xffff, 0x11e0, 0x11e3, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x11e6, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x11e9, 0x11ec, 0xffff, 0x11ef, 0x11f2, + 0xffff, 0xffff, 0xffff, 0xffff, 0x11e6, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x11e9, 0x11ec, 0xffff, 0x11ef, 0x11f2, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x11f5, 0xffff, 0x11f8, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x11f5, 0xffff, 0x11f8, 0xffff, - 0x11fb, 0xffff, 0x11fe, 0xffff, 0x1201, 0xffff, 0x1204, 0xffff, - 0x1207, 0xffff, 0x120a, 0xffff, 0x120d, 0xffff, 0x1210, 0xffff, + 0x11fb, 0xffff, 0x11fe, 0xffff, 0x1201, 0xffff, 0x1204, 0xffff, + 0x1207, 0xffff, 0x120a, 0xffff, 0x120d, 0xffff, 0x1210, 0xffff, - 0x1213, 0xffff, 0x1216, 0xffff, 0xffff, 0x1219, 0xffff, 0x121c, - 0xffff, 0x121f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1213, 0xffff, 0x1216, 0xffff, 0xffff, 0x1219, 0xffff, 0x121c, + 0xffff, 0x121f, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x1222, 0x1225, 0xffff, 0x1228, 0x122b, 0xffff, 0x122e, 0x1231, - 0xffff, 0x1234, 0x1237, 0xffff, 0x123a, 0x123d, 0xffff, 0xffff, + 0x1222, 0x1225, 0xffff, 0x1228, 0x122b, 0xffff, 0x122e, 0x1231, + 0xffff, 0x1234, 0x1237, 0xffff, 0x123a, 0x123d, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x1240, 0xffff, 0xffff, 0x1243, - 0x1246, 0x1249, 0x124c, 0xffff, 0xffff, 0xffff, 0x124f, 0x1252, + 0xffff, 0xffff, 0xffff, 0xffff, 0x1240, 0xffff, 0xffff, 0x1243, + 0x1246, 0x1249, 0x124c, 0xffff, 0xffff, 0xffff, 0x124f, 0x1252, - 0xffff, 0x1255, 0x1257, 0x1259, 0x125b, 0x125d, 0x125f, 0x1261, - 0x1263, 0x1265, 0x1267, 0x1269, 0x126b, 0x126d, 0x126f, 0x1271, + 0xffff, 0x1255, 0x1257, 0x1259, 0x125b, 0x125d, 0x125f, 0x1261, + 0x1263, 0x1265, 0x1267, 0x1269, 0x126b, 0x126d, 0x126f, 0x1271, - 0x1273, 0x1275, 0x1277, 0x1279, 0x127b, 0x127d, 0x127f, 0x1281, - 0x1283, 0x1285, 0x1287, 0x1289, 0x128b, 0x128d, 0x128f, 0x1291, + 0x1273, 0x1275, 0x1277, 0x1279, 0x127b, 0x127d, 0x127f, 0x1281, + 0x1283, 0x1285, 0x1287, 0x1289, 0x128b, 0x128d, 0x128f, 0x1291, - 0x1293, 0x1295, 0x1297, 0x1299, 0x129b, 0x129d, 0x129f, 0x12a1, - 0x12a3, 0x12a5, 0x12a7, 0x12a9, 0x12ab, 0x12ad, 0x12af, 0x12b1, + 0x1293, 0x1295, 0x1297, 0x1299, 0x129b, 0x129d, 0x129f, 0x12a1, + 0x12a3, 0x12a5, 0x12a7, 0x12a9, 0x12ab, 0x12ad, 0x12af, 0x12b1, - 0x12b3, 0x12b5, 0x12b7, 0x12b9, 0x12bb, 0x12bd, 0x12bf, 0x12c1, - 0x12c3, 0x12c5, 0x12c7, 0x12c9, 0x12cb, 0x12cd, 0x12cf, 0x12d1, + 0x12b3, 0x12b5, 0x12b7, 0x12b9, 0x12bb, 0x12bd, 0x12bf, 0x12c1, + 0x12c3, 0x12c5, 0x12c7, 0x12c9, 0x12cb, 0x12cd, 0x12cf, 0x12d1, - 0x12d3, 0x12d5, 0x12d7, 0x12d9, 0x12db, 0x12dd, 0x12df, 0x12e1, - 0x12e3, 0x12e5, 0x12e7, 0x12e9, 0x12eb, 0x12ed, 0x12ef, 0x12f1, + 0x12d3, 0x12d5, 0x12d7, 0x12d9, 0x12db, 0x12dd, 0x12df, 0x12e1, + 0x12e3, 0x12e5, 0x12e7, 0x12e9, 0x12eb, 0x12ed, 0x12ef, 0x12f1, - 0x12f3, 0x12f5, 0x12f7, 0x12f9, 0x12fb, 0x12fd, 0x12ff, 0x1301, - 0x1303, 0x1305, 0x1307, 0x1309, 0x130b, 0x130d, 0x130f, 0xffff, + 0x12f3, 0x12f5, 0x12f7, 0x12f9, 0x12fb, 0x12fd, 0x12ff, 0x1301, + 0x1303, 0x1305, 0x1307, 0x1309, 0x130b, 0x130d, 0x130f, 0xffff, - 0xffff, 0xffff, 0x1311, 0x1313, 0x1315, 0x1317, 0x1319, 0x131b, - 0x131d, 0x131f, 0x1321, 0x1323, 0x1325, 0x1327, 0x1329, 0x132b, + 0xffff, 0xffff, 0x1311, 0x1313, 0x1315, 0x1317, 0x1319, 0x131b, + 0x131d, 0x131f, 0x1321, 0x1323, 0x1325, 0x1327, 0x1329, 0x132b, - 0x132d, 0x1331, 0x1335, 0x1339, 0x133d, 0x1341, 0x1345, 0x1349, - 0x134d, 0x1351, 0x1355, 0x1359, 0x135d, 0x1361, 0x1365, 0x136a, + 0x132d, 0x1331, 0x1335, 0x1339, 0x133d, 0x1341, 0x1345, 0x1349, + 0x134d, 0x1351, 0x1355, 0x1359, 0x135d, 0x1361, 0x1365, 0x136a, - 0x136f, 0x1374, 0x1379, 0x137e, 0x1383, 0x1388, 0x138d, 0x1392, - 0x1397, 0x139c, 0x13a1, 0x13a6, 0x13ab, 0x13b0, 0x13b8, 0xffff, + 0x136f, 0x1374, 0x1379, 0x137e, 0x1383, 0x1388, 0x138d, 0x1392, + 0x1397, 0x139c, 0x13a1, 0x13a6, 0x13ab, 0x13b0, 0x13b8, 0xffff, - 0x13bf, 0x13c3, 0x13c7, 0x13cb, 0x13cf, 0x13d3, 0x13d7, 0x13db, - 0x13df, 0x13e3, 0x13e7, 0x13eb, 0x13ef, 0x13f3, 0x13f7, 0x13fb, + 0x13bf, 0x13c3, 0x13c7, 0x13cb, 0x13cf, 0x13d3, 0x13d7, 0x13db, + 0x13df, 0x13e3, 0x13e7, 0x13eb, 0x13ef, 0x13f3, 0x13f7, 0x13fb, - 0x13ff, 0x1403, 0x1407, 0x140b, 0x140f, 0x1413, 0x1417, 0x141b, - 0x141f, 0x1423, 0x1427, 0x142b, 0x142f, 0x1433, 0x1437, 0x143b, + 0x13ff, 0x1403, 0x1407, 0x140b, 0x140f, 0x1413, 0x1417, 0x141b, + 0x141f, 0x1423, 0x1427, 0x142b, 0x142f, 0x1433, 0x1437, 0x143b, - 0x143f, 0x1443, 0x1447, 0x144b, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x143f, 0x1443, 0x1447, 0x144b, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x144f, 0x1453, 0x1456, 0x1459, 0x145c, 0x145f, 0x1462, 0x1465, - 0x1468, 0x146b, 0x146e, 0x1471, 0x1474, 0x1477, 0x147a, 0x147d, + 0x144f, 0x1453, 0x1456, 0x1459, 0x145c, 0x145f, 0x1462, 0x1465, + 0x1468, 0x146b, 0x146e, 0x1471, 0x1474, 0x1477, 0x147a, 0x147d, - 0x1480, 0x1482, 0x1484, 0x1486, 0x1488, 0x148a, 0x148c, 0x148e, - 0x1490, 0x1492, 0x1494, 0x1496, 0x1498, 0x149a, 0x149c, 0x149f, + 0x1480, 0x1482, 0x1484, 0x1486, 0x1488, 0x148a, 0x148c, 0x148e, + 0x1490, 0x1492, 0x1494, 0x1496, 0x1498, 0x149a, 0x149c, 0x149f, - 0x14a2, 0x14a5, 0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7, - 0x14ba, 0x14bd, 0x14c0, 0x14c3, 0x14c6, 0x14cc, 0x14d1, 0xffff, + 0x14a2, 0x14a5, 0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7, + 0x14ba, 0x14bd, 0x14c0, 0x14c3, 0x14c6, 0x14cc, 0x14d1, 0xffff, - 0x14d4, 0x14d6, 0x14d8, 0x14da, 0x14dc, 0x14de, 0x14e0, 0x14e2, - 0x14e4, 0x14e6, 0x14e8, 0x14ea, 0x14ec, 0x14ee, 0x14f0, 0x14f2, + 0x14d4, 0x14d6, 0x14d8, 0x14da, 0x14dc, 0x14de, 0x14e0, 0x14e2, + 0x14e4, 0x14e6, 0x14e8, 0x14ea, 0x14ec, 0x14ee, 0x14f0, 0x14f2, - 0x14f4, 0x14f6, 0x14f8, 0x14fa, 0x14fc, 0x14fe, 0x1500, 0x1502, - 0x1504, 0x1506, 0x1508, 0x150a, 0x150c, 0x150e, 0x1510, 0x1512, + 0x14f4, 0x14f6, 0x14f8, 0x14fa, 0x14fc, 0x14fe, 0x1500, 0x1502, + 0x1504, 0x1506, 0x1508, 0x150a, 0x150c, 0x150e, 0x1510, 0x1512, - 0x1514, 0x1516, 0x1518, 0x151a, 0x151c, 0x151e, 0x1520, 0x1522, - 0x1524, 0x1526, 0x1528, 0x152a, 0x152c, 0x152e, 0x1530, 0x1532, + 0x1514, 0x1516, 0x1518, 0x151a, 0x151c, 0x151e, 0x1520, 0x1522, + 0x1524, 0x1526, 0x1528, 0x152a, 0x152c, 0x152e, 0x1530, 0x1532, - 0x1534, 0x1536, 0x1539, 0x153c, 0x153f, 0x1542, 0x1545, 0x1548, - 0x154b, 0x154e, 0x1551, 0x1554, 0x1557, 0x155a, 0x155d, 0x1560, + 0x1534, 0x1536, 0x1539, 0x153c, 0x153f, 0x1542, 0x1545, 0x1548, + 0x154b, 0x154e, 0x1551, 0x1554, 0x1557, 0x155a, 0x155d, 0x1560, - 0x1563, 0x1566, 0x1569, 0x156c, 0x156f, 0x1572, 0x1575, 0x1578, - 0x157b, 0x157e, 0x1582, 0x1586, 0x158a, 0x158d, 0x1591, 0x1594, + 0x1563, 0x1566, 0x1569, 0x156c, 0x156f, 0x1572, 0x1575, 0x1578, + 0x157b, 0x157e, 0x1582, 0x1586, 0x158a, 0x158d, 0x1591, 0x1594, - 0x1598, 0x159a, 0x159c, 0x159e, 0x15a0, 0x15a2, 0x15a4, 0x15a6, - 0x15a8, 0x15aa, 0x15ac, 0x15ae, 0x15b0, 0x15b2, 0x15b4, 0x15b6, + 0x1598, 0x159a, 0x159c, 0x159e, 0x15a0, 0x15a2, 0x15a4, 0x15a6, + 0x15a8, 0x15aa, 0x15ac, 0x15ae, 0x15b0, 0x15b2, 0x15b4, 0x15b6, - 0x15b8, 0x15ba, 0x15bc, 0x15be, 0x15c0, 0x15c2, 0x15c4, 0x15c6, - 0x15c8, 0x15ca, 0x15cc, 0x15ce, 0x15d0, 0x15d2, 0x15d4, 0x15d6, + 0x15b8, 0x15ba, 0x15bc, 0x15be, 0x15c0, 0x15c2, 0x15c4, 0x15c6, + 0x15c8, 0x15ca, 0x15cc, 0x15ce, 0x15d0, 0x15d2, 0x15d4, 0x15d6, - 0x15d8, 0x15da, 0x15dc, 0x15de, 0x15e0, 0x15e2, 0x15e4, 0x15e6, - 0x15e8, 0x15ea, 0x15ec, 0x15ee, 0x15f0, 0x15f2, 0x15f4, 0xffff, + 0x15d8, 0x15da, 0x15dc, 0x15de, 0x15e0, 0x15e2, 0x15e4, 0x15e6, + 0x15e8, 0x15ea, 0x15ec, 0x15ee, 0x15f0, 0x15f2, 0x15f4, 0xffff, - 0x15f6, 0x15fb, 0x1600, 0x1605, 0x1609, 0x160e, 0x1612, 0x1616, - 0x161c, 0x1621, 0x1625, 0x1629, 0x162d, 0x1632, 0x1637, 0x163b, + 0x15f6, 0x15fb, 0x1600, 0x1605, 0x1609, 0x160e, 0x1612, 0x1616, + 0x161c, 0x1621, 0x1625, 0x1629, 0x162d, 0x1632, 0x1637, 0x163b, - 0x163f, 0x1642, 0x1646, 0x164b, 0x1650, 0x1653, 0x1659, 0x1660, - 0x1666, 0x166a, 0x1670, 0x1676, 0x167b, 0x167f, 0x1683, 0x1687, - - 0x168c, 0x1692, 0x1697, 0x169b, 0x169f, 0x16a3, 0x16a6, 0x16a9, - 0x16ac, 0x16af, 0x16b3, 0x16b7, 0x16bd, 0x16c1, 0x16c6, 0x16cc, - - 0x16d0, 0x16d3, 0x16d6, 0x16dc, 0x16e1, 0x16e7, 0x16eb, 0x16f1, - 0x16f4, 0x16f8, 0x16fc, 0x1700, 0x1704, 0x1708, 0x170d, 0x1711, - - 0x1714, 0x1718, 0x171c, 0x1720, 0x1725, 0x1729, 0x172d, 0x1731, - 0x1737, 0x173c, 0x173f, 0x1745, 0x1748, 0x174d, 0x1752, 0x1756, - - 0x175a, 0x175e, 0x1763, 0x1766, 0x176a, 0x176f, 0x1772, 0x1778, - 0x177c, 0x177f, 0x1782, 0x1785, 0x1788, 0x178b, 0x178e, 0x1791, - - 0x1794, 0x1797, 0x179a, 0x179e, 0x17a2, 0x17a6, 0x17aa, 0x17ae, - 0x17b2, 0x17b6, 0x17ba, 0x17be, 0x17c2, 0x17c6, 0x17ca, 0x17ce, - - 0x17d2, 0x17d6, 0x17da, 0x17dd, 0x17e0, 0x17e4, 0x17e7, 0x17ea, - 0x17ed, 0x17f1, 0x17f5, 0x17f8, 0x17fb, 0x17fe, 0x1801, 0x1804, - - 0x1809, 0x180c, 0x180f, 0x1812, 0x1815, 0x1818, 0x181b, 0x181e, - 0x1821, 0x1825, 0x182a, 0x182d, 0x1830, 0x1833, 0x1836, 0x1839, - - 0x183c, 0x183f, 0x1843, 0x1847, 0x184b, 0x184f, 0x1852, 0x1855, - 0x1858, 0x185b, 0x185e, 0x1861, 0x1864, 0x1867, 0x186a, 0x186d, - - 0x1871, 0x1875, 0x1878, 0x187c, 0x1880, 0x1884, 0x1887, 0x188b, - 0x188f, 0x1894, 0x1897, 0x189b, 0x189f, 0x18a3, 0x18a7, 0x18ad, - - 0x18b4, 0x18b7, 0x18ba, 0x18bd, 0x18c0, 0x18c3, 0x18c6, 0x18c9, - 0x18cc, 0x18cf, 0x18d2, 0x18d5, 0x18d8, 0x18db, 0x18de, 0x18e1, - - 0x18e4, 0x18e7, 0x18ea, 0x18ef, 0x18f2, 0x18f5, 0x18f8, 0x18fd, - 0x1901, 0x1904, 0x1907, 0x190a, 0x190d, 0x1910, 0x1913, 0x1916, - - 0x1919, 0x191c, 0x191f, 0x1923, 0x1926, 0x1929, 0x192d, 0x1931, - 0x1934, 0x1939, 0x193d, 0x1940, 0x1943, 0x1946, 0x1949, 0x194d, - - 0x1951, 0x1954, 0x1957, 0x195a, 0x195d, 0x1960, 0x1963, 0x1966, - 0x1969, 0x196c, 0x1970, 0x1974, 0x1978, 0x197c, 0x1980, 0x1984, - - 0x1988, 0x198c, 0x1990, 0x1994, 0x1998, 0x199c, 0x19a0, 0x19a4, - 0x19a8, 0x19ac, 0x19b0, 0x19b4, 0x19b8, 0x19bc, 0x19c0, 0x19c4, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x19c8, 0x19ca, 0x19cc, 0x19ce, 0x19d0, 0x19d2, 0x19d4, 0x19d6, - 0x19d8, 0x19da, 0x19dc, 0x19de, 0x19e0, 0x19e2, 0x19e4, 0x19e6, - 0x19e8, 0x19ea, 0x19ec, 0x19ee, 0x19f0, 0x19f2, 0x19f4, 0x19f6, - 0x19f8, 0x19fa, 0x19fc, 0x19fe, 0x1a00, 0x1a02, 0x1a04, 0x1a06, - 0x1a08, 0x1a0a, 0x1a0c, 0x1a0e, 0x1a10, 0x1a12, 0x1a14, 0x1a16, - 0x1a18, 0x1a1a, 0x1a1c, 0x1a1e, 0x1a20, 0x1a22, 0x1a24, 0x1a26, - 0x1a28, 0x1a2a, 0x1a2c, 0x1a2e, 0x1a30, 0x1a32, 0x1a34, 0x1a36, - 0x1a38, 0x1a3a, 0x1a3c, 0x1a3e, 0x1a40, 0x1a42, 0x1a44, 0x1a46, - 0x1a48, 0x1a4a, 0x1a4c, 0x1a4e, 0x1a50, 0x1a52, 0x1a54, 0x1a56, - 0x1a58, 0x1a5a, 0x1a5c, 0x1a5e, 0x1a60, 0x1a62, 0x1a64, 0x1a66, - 0x1a68, 0x1a6a, 0x1a6c, 0x1a6e, 0x1a70, 0x1a72, 0x1a74, 0x1a76, - 0x1a78, 0x1a7a, 0x1a7c, 0x1a7e, 0x1a80, 0x1a82, 0x1a84, 0x1a86, - 0x1a88, 0x1a8a, 0x1a8c, 0x1a8e, 0x1a90, 0x1a92, 0x1a94, 0x1a96, - 0x1a98, 0x1a9a, 0x1a9c, 0x1a9e, 0x1aa0, 0x1aa2, 0x1aa4, 0x1aa6, - 0x1aa8, 0x1aaa, 0x1aac, 0x1aae, 0x1ab0, 0x1ab2, 0x1ab4, 0x1ab6, - 0x1ab8, 0x1aba, 0x1abc, 0x1abe, 0x1ac0, 0x1ac2, 0x1ac4, 0x1ac6, - 0x1ac8, 0x1aca, 0x1acc, 0x1ace, 0x1ad0, 0x1ad2, 0x1ad4, 0x1ad6, - 0x1ad8, 0x1ada, 0x1adc, 0x1ade, 0x1ae0, 0x1ae2, 0x1ae4, 0x1ae6, - 0x1ae8, 0x1aea, 0x1aec, 0x1aee, 0x1af0, 0x1af2, 0x1af4, 0x1af6, - 0x1af8, 0x1afa, 0x1afc, 0x1afe, 0x1b00, 0x1b02, 0x1b04, 0x1b06, - 0x1b08, 0x1b0a, 0x1b0c, 0x1b0e, 0x1b10, 0x1b12, 0x1b14, 0x1b16, - 0x1b18, 0x1b1a, 0x1b1c, 0x1b1e, 0x1b20, 0x1b22, 0x1b24, 0x1b26, - 0x1b28, 0x1b2a, 0x1b2c, 0x1b2e, 0x1b30, 0x1b32, 0x1b34, 0x1b36, - 0x1b38, 0x1b3a, 0x1b3c, 0x1b3e, 0x1b40, 0x1b42, 0x1b44, 0x1b46, - 0x1b48, 0x1b4a, 0x1b4c, 0x1b4e, 0x1b50, 0x1b52, 0x1b54, 0x1b56, - 0x1b58, 0x1b5a, 0x1b5c, 0x1b5e, 0x1b60, 0x1b62, 0x1b64, 0x1b66, - 0x1b68, 0x1b6a, 0x1b6c, 0x1b6e, 0x1b70, 0x1b72, 0x1b74, 0x1b76, - 0x1b78, 0x1b7a, 0x1b7c, 0x1b7e, 0x1b80, 0x1b82, 0x1b84, 0x1b86, - 0x1b88, 0x1b8a, 0x1b8c, 0x1b8e, 0x1b90, 0x1b92, 0x1b94, 0x1b96, - 0x1b98, 0x1b9a, 0x1b9c, 0x1b9e, 0x1ba0, 0x1ba2, 0x1ba4, 0x1ba6, - 0x1ba8, 0x1baa, 0x1bac, 0x1bae, 0x1bb0, 0x1bb2, 0x1bb4, 0x1bb6, - 0x1bb8, 0x1bba, 0x1bbc, 0x1bbe, 0x1bc0, 0x1bc2, 0x1bc4, 0x1bc6, - - 0x1bc8, 0x1bca, 0x1bcc, 0x1bce, 0x1bd0, 0x1bd2, 0x1bd4, 0x1bd6, - 0x1bd8, 0x1bda, 0x1bdc, 0x1bde, 0x1be0, 0x1be2, 0xffff, 0xffff, - 0x1be4, 0xffff, 0x1be6, 0xffff, 0xffff, 0x1be8, 0x1bea, 0x1bec, - 0x1bee, 0x1bf0, 0x1bf2, 0x1bf4, 0x1bf6, 0x1bf8, 0x1bfa, 0xffff, - 0x1bfc, 0xffff, 0x1bfe, 0xffff, 0xffff, 0x1c00, 0x1c02, 0xffff, - 0xffff, 0xffff, 0x1c04, 0x1c06, 0x1c08, 0x1c0a, 0xffff, 0xffff, - 0x1c0c, 0x1c0e, 0x1c10, 0x1c12, 0x1c14, 0x1c16, 0x1c18, 0x1c1a, - 0x1c1c, 0x1c1e, 0x1c20, 0x1c22, 0x1c24, 0x1c26, 0x1c28, 0x1c2a, - 0x1c2c, 0x1c2e, 0x1c30, 0x1c32, 0x1c34, 0x1c36, 0x1c38, 0x1c3a, - 0x1c3c, 0x1c3e, 0x1c40, 0x1c42, 0x1c44, 0x1c46, 0x1c48, 0x1c4a, - 0x1c4c, 0x1c4e, 0x1c50, 0x1c52, 0x1c54, 0x1c56, 0x1c58, 0x1c5a, - 0x1c5c, 0x1c5e, 0x1c60, 0x1c62, 0x1c64, 0x1c66, 0x1c68, 0x1c6a, - 0x1c6c, 0x1c6e, 0x1c70, 0x1c72, 0x1c74, 0x1c76, 0x1c78, 0x1c7a, - 0x1c7c, 0x1c7e, 0x1c80, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x1c82, 0x1c84, 0x1c86, 0x1c88, 0x1c8a, 0x1c8c, 0x1c8e, 0x1c90, - 0x1c92, 0x1c94, 0x1c96, 0x1c98, 0x1c9a, 0x1c9c, 0x1c9e, 0x1ca0, - 0x1ca2, 0x1ca4, 0x1ca6, 0x1ca8, 0x1caa, 0x1cac, 0x1cae, 0x1cb0, - 0x1cb2, 0x1cb4, 0x1cb6, 0x1cb8, 0x1cba, 0x1cbc, 0x1cbe, 0x1cc0, - 0x1cc2, 0x1cc4, 0x1cc6, 0x1cc8, 0x1cca, 0x1ccc, 0x1cce, 0x1cd0, - 0x1cd2, 0x1cd4, 0x1cd6, 0x1cd8, 0x1cda, 0x1cdc, 0x1cde, 0x1ce0, - 0x1ce2, 0x1ce4, 0x1ce6, 0x1ce8, 0x1cea, 0x1cec, 0x1cee, 0x1cf0, - 0x1cf2, 0x1cf4, 0x1cf6, 0x1cf8, 0x1cfa, 0x1cfc, 0x1cfe, 0x1d00, - 0x1d02, 0x1d04, 0x1d06, 0x1d08, 0x1d0a, 0x1d0c, 0x1d0e, 0x1d10, - 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, 0x1d20, - 0x1d22, 0x1d24, 0x1d26, 0x1d28, 0x1d2a, 0x1d2c, 0x1d2e, 0x1d30, - 0x1d32, 0x1d34, 0x1d36, 0x1d38, 0x1d3a, 0x1d3c, 0x1d3e, 0x1d40, - 0x1d43, 0x1d46, 0x1d49, 0x1d4b, 0x1d4d, 0x1d4f, 0x1d52, 0x1d55, - 0x1d58, 0x1d5a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x1d5c, 0x1d5f, 0x1d62, 0x1d65, 0x1d69, 0x1d6d, 0x1d70, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x1d73, 0x1d76, 0x1d79, 0x1d7c, 0x1d7f, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1d82, 0xffff, 0x1d85, - 0x1d88, 0x1d8a, 0x1d8c, 0x1d8e, 0x1d90, 0x1d92, 0x1d94, 0x1d96, - 0x1d98, 0x1d9a, 0x1d9c, 0x1d9f, 0x1da2, 0x1da5, 0x1da8, 0x1dab, - 0x1dae, 0x1db1, 0x1db4, 0x1db7, 0x1dba, 0x1dbd, 0x1dc0, 0xffff, - 0x1dc3, 0x1dc6, 0x1dc9, 0x1dcc, 0x1dcf, 0xffff, 0x1dd2, 0xffff, - 0x1dd5, 0x1dd8, 0xffff, 0x1ddb, 0x1dde, 0xffff, 0x1de1, 0x1de4, - 0x1de7, 0x1dea, 0x1ded, 0x1df0, 0x1df3, 0x1df6, 0x1df9, 0x1dfc, - 0x1dff, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, - 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, - 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, - 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, - 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, - 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, - 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, - 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d, - 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d, - 0x1e8f, 0x1e91, 0x1e93, 0x1e95, 0x1e97, 0x1e99, 0x1e9b, 0x1e9d, - 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, - 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, - 0x1ebf, 0x1ec1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, - 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, - 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, - 0x1eed, 0x1eef, 0x1ef1, 0x1ef4, 0x1ef7, 0x1efa, 0x1efd, 0x1f00, - 0x1f03, 0x1f06, 0x1f09, 0x1f0c, 0x1f0f, 0x1f12, 0x1f15, 0x1f18, - 0x1f1b, 0x1f1e, 0x1f21, 0x1f24, 0x1f27, 0x1f29, 0x1f2b, 0x1f2d, - - 0x1f2f, 0x1f32, 0x1f35, 0x1f38, 0x1f3b, 0x1f3e, 0x1f41, 0x1f44, - 0x1f47, 0x1f4a, 0x1f4d, 0x1f50, 0x1f53, 0x1f56, 0x1f59, 0x1f5c, - 0x1f5f, 0x1f62, 0x1f65, 0x1f68, 0x1f6b, 0x1f6e, 0x1f71, 0x1f74, - 0x1f77, 0x1f7a, 0x1f7d, 0x1f80, 0x1f83, 0x1f86, 0x1f89, 0x1f8c, - 0x1f8f, 0x1f92, 0x1f95, 0x1f98, 0x1f9b, 0x1f9e, 0x1fa1, 0x1fa4, - 0x1fa7, 0x1faa, 0x1fad, 0x1fb0, 0x1fb3, 0x1fb6, 0x1fb9, 0x1fbc, - 0x1fbf, 0x1fc2, 0x1fc5, 0x1fc8, 0x1fcb, 0x1fce, 0x1fd1, 0x1fd4, - 0x1fd7, 0x1fda, 0x1fdd, 0x1fe0, 0x1fe3, 0x1fe6, 0x1fe9, 0x1fec, - 0x1fef, 0x1ff2, 0x1ff5, 0x1ff8, 0x1ffb, 0x1ffe, 0x2001, 0x2004, - 0x2007, 0x200a, 0x200d, 0x2010, 0x2013, 0x2016, 0x2019, 0x201c, - 0x201f, 0x2022, 0x2025, 0x2028, 0x202b, 0x202e, 0x2031, 0x2034, - 0x2037, 0x203a, 0x203d, 0x2040, 0x2043, 0x2046, 0x2049, 0x204d, - 0x2051, 0x2055, 0x2059, 0x205d, 0x2061, 0x2064, 0x2067, 0x206a, - 0x206d, 0x2070, 0x2073, 0x2076, 0x2079, 0x207c, 0x207f, 0x2082, - 0x2085, 0x2088, 0x208b, 0x208e, 0x2091, 0x2094, 0x2097, 0x209a, - 0x209d, 0x20a0, 0x20a3, 0x20a6, 0x20a9, 0x20ac, 0x20af, 0x20b2, - 0x20b5, 0x20b8, 0x20bb, 0x20be, 0x20c1, 0x20c4, 0x20c7, 0x20ca, - 0x20cd, 0x20d0, 0x20d3, 0x20d6, 0x20d9, 0x20dc, 0x20df, 0x20e2, - 0x20e5, 0x20e8, 0x20eb, 0x20ee, 0x20f1, 0x20f4, 0x20f7, 0x20fa, - 0x20fd, 0x2100, 0x2103, 0x2106, 0x2109, 0x210c, 0x210f, 0x2112, - 0x2115, 0x2118, 0x211b, 0x211e, 0x2121, 0x2124, 0x2127, 0x212a, - 0x212d, 0x2130, 0x2133, 0x2136, 0x2139, 0x213c, 0x213f, 0x2142, - 0x2145, 0x2148, 0x214b, 0x214e, 0x2151, 0x2154, 0x2157, 0x215a, - 0x215d, 0x2160, 0x2163, 0x2166, 0x2169, 0x216c, 0x216f, 0x2172, - 0x2175, 0x2178, 0x217b, 0x217e, 0x2181, 0x2184, 0x2187, 0x218a, - 0x218d, 0x2190, 0x2193, 0x2196, 0x2199, 0x219c, 0x219f, 0x21a2, - 0x21a5, 0x21a8, 0x21ab, 0x21ae, 0x21b1, 0x21b4, 0x21b7, 0x21ba, - 0x21bd, 0x21c0, 0x21c3, 0x21c6, 0x21c9, 0x21cc, 0x21cf, 0x21d2, - 0x21d5, 0x21d8, 0x21db, 0x21de, 0x21e1, 0x21e4, 0x21e7, 0x21ea, - 0x21ed, 0x21f0, 0x21f3, 0x21f6, 0x21f9, 0x21fc, 0x21ff, 0x2202, - 0x2205, 0x2208, 0x220b, 0x220f, 0x2213, 0x2217, 0x221a, 0x221d, - 0x2220, 0x2223, 0x2226, 0x2229, 0x222c, 0x222f, 0x2232, 0x2235, - - 0x2238, 0x223b, 0x223e, 0x2241, 0x2244, 0x2247, 0x224a, 0x224d, - 0x2250, 0x2253, 0x2256, 0x2259, 0x225c, 0x225f, 0x2262, 0x2265, - 0x2268, 0x226b, 0x226e, 0x2271, 0x2274, 0x2277, 0x227a, 0x227d, - 0x2280, 0x2283, 0x2286, 0x2289, 0x228c, 0x228f, 0x2292, 0x2295, - 0x2298, 0x229b, 0x229e, 0x22a1, 0x22a4, 0x22a7, 0x22aa, 0x22ad, - 0x22b0, 0x22b3, 0x22b6, 0x22b9, 0x22bc, 0x22bf, 0x22c2, 0x22c5, - 0x22c8, 0x22cb, 0x22ce, 0x22d1, 0x22d4, 0x22d7, 0x22da, 0x22dd, - 0x22e0, 0x22e3, 0x22e6, 0x22e9, 0x22ec, 0x22ef, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x22f2, 0x22f6, 0x22fa, 0x22fe, 0x2302, 0x2306, 0x230a, 0x230e, - 0x2312, 0x2316, 0x231a, 0x231e, 0x2322, 0x2326, 0x232a, 0x232e, - 0x2332, 0x2336, 0x233a, 0x233e, 0x2342, 0x2346, 0x234a, 0x234e, - 0x2352, 0x2356, 0x235a, 0x235e, 0x2362, 0x2366, 0x236a, 0x236e, - 0x2372, 0x2376, 0x237a, 0x237e, 0x2382, 0x2386, 0x238a, 0x238e, - 0x2392, 0x2396, 0x239a, 0x239e, 0x23a2, 0x23a6, 0x23aa, 0x23ae, - 0x23b2, 0x23b6, 0x23ba, 0x23be, 0x23c2, 0x23c6, 0x23ca, 0x23ce, - 0x23d2, 0x23d6, 0x23da, 0x23de, 0x23e2, 0x23e6, 0x23ea, 0x23ee, - 0xffff, 0xffff, 0x23f2, 0x23f6, 0x23fa, 0x23fe, 0x2402, 0x2406, - 0x240a, 0x240e, 0x2412, 0x2416, 0x241a, 0x241e, 0x2422, 0x2426, - 0x242a, 0x242e, 0x2432, 0x2436, 0x243a, 0x243e, 0x2442, 0x2446, - 0x244a, 0x244e, 0x2452, 0x2456, 0x245a, 0x245e, 0x2462, 0x2466, - 0x246a, 0x246e, 0x2472, 0x2476, 0x247a, 0x247e, 0x2482, 0x2486, - 0x248a, 0x248e, 0x2492, 0x2496, 0x249a, 0x249e, 0x24a2, 0x24a6, - 0x24aa, 0x24ae, 0x24b2, 0x24b6, 0x24ba, 0x24be, 0x24c2, 0x24c6, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x24ca, 0x24ce, 0x24d2, 0x24d7, 0x24dc, 0x24e1, 0x24e6, 0x24eb, - 0x24f0, 0x24f5, 0x24f9, 0x250c, 0x2515, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x251a, 0x251c, 0x251e, 0x2520, 0x2522, 0x2524, 0x2526, 0x2528, - 0x252a, 0x252c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x252e, 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, 0x253c, - 0x253e, 0x2540, 0x2542, 0x2544, 0x2546, 0x2548, 0x254a, 0x254c, - 0x254e, 0x2550, 0x2552, 0x2554, 0x2556, 0xffff, 0xffff, 0x2558, - 0x255a, 0x255c, 0x255e, 0x2560, 0x2562, 0x2564, 0x2566, 0x2568, - 0x256a, 0x256c, 0x256e, 0xffff, 0x2570, 0x2572, 0x2574, 0x2576, - 0x2578, 0x257a, 0x257c, 0x257e, 0x2580, 0x2582, 0x2584, 0x2586, - 0x2588, 0x258a, 0x258c, 0x258e, 0x2590, 0x2592, 0x2594, 0xffff, - 0x2596, 0x2598, 0x259a, 0x259c, 0xffff, 0xffff, 0xffff, 0xffff, - 0x259e, 0x25a1, 0x25a4, 0xffff, 0x25a7, 0xffff, 0x25aa, 0x25ad, - 0x25b0, 0x25b3, 0x25b6, 0x25b9, 0x25bc, 0x25bf, 0x25c2, 0x25c5, - 0x25c8, 0x25ca, 0x25cc, 0x25ce, 0x25d0, 0x25d2, 0x25d4, 0x25d6, - 0x25d8, 0x25da, 0x25dc, 0x25de, 0x25e0, 0x25e2, 0x25e4, 0x25e6, - 0x25e8, 0x25ea, 0x25ec, 0x25ee, 0x25f0, 0x25f2, 0x25f4, 0x25f6, - 0x25f8, 0x25fa, 0x25fc, 0x25fe, 0x2600, 0x2602, 0x2604, 0x2606, - 0x2608, 0x260a, 0x260c, 0x260e, 0x2610, 0x2612, 0x2614, 0x2616, - 0x2618, 0x261a, 0x261c, 0x261e, 0x2620, 0x2622, 0x2624, 0x2626, - 0x2628, 0x262a, 0x262c, 0x262e, 0x2630, 0x2632, 0x2634, 0x2636, - 0x2638, 0x263a, 0x263c, 0x263e, 0x2640, 0x2642, 0x2644, 0x2646, - 0x2648, 0x264a, 0x264c, 0x264e, 0x2650, 0x2652, 0x2654, 0x2656, - 0x2658, 0x265a, 0x265c, 0x265e, 0x2660, 0x2662, 0x2664, 0x2666, - 0x2668, 0x266a, 0x266c, 0x266e, 0x2670, 0x2672, 0x2674, 0x2676, - 0x2678, 0x267a, 0x267c, 0x267e, 0x2680, 0x2682, 0x2684, 0x2686, - 0x2688, 0x268a, 0x268c, 0x268e, 0x2690, 0x2692, 0x2694, 0x2696, - 0x2698, 0x269a, 0x269c, 0x269e, 0x26a0, 0x26a2, 0x26a4, 0x26a6, - 0x26a8, 0x26aa, 0x26ac, 0x26ae, 0x26b0, 0x26b2, 0x26b5, 0x26b8, - 0x26bb, 0x26be, 0x26c1, 0x26c4, 0x26c7, 0xffff, 0xffff, 0xffff, - - 0xffff, 0x26ca, 0x26cc, 0x26ce, 0x26d0, 0x26d2, 0x26d4, 0x26d6, - 0x26d8, 0x26da, 0x26dc, 0x26de, 0x26e0, 0x26e2, 0x26e4, 0x26e6, - 0x26e8, 0x26ea, 0x26ec, 0x26ee, 0x26f0, 0x26f2, 0x26f4, 0x26f6, - 0x26f8, 0x26fa, 0x26fc, 0x26fe, 0x2700, 0x2702, 0x2704, 0x2706, - 0x2708, 0x270a, 0x270c, 0x270e, 0x2710, 0x2712, 0x2714, 0x2716, - 0x2718, 0x271a, 0x271c, 0x271e, 0x2720, 0x2722, 0x2724, 0x2726, - 0x2728, 0x272a, 0x272c, 0x272e, 0x2730, 0x2732, 0x2734, 0x2736, - 0x2738, 0x273a, 0x273c, 0x273e, 0x2740, 0x2742, 0x2744, 0x2746, - 0x2748, 0x274a, 0x274c, 0x274e, 0x2750, 0x2752, 0x2754, 0x2756, - 0x2758, 0x275a, 0x275c, 0x275e, 0x2760, 0x2762, 0x2764, 0x2766, - 0x2768, 0x276a, 0x276c, 0x276e, 0x2770, 0x2772, 0x2774, 0x2776, - 0x2778, 0x277a, 0x277c, 0x277e, 0x2780, 0x2782, 0x2784, 0x2786, - 0x2788, 0x278a, 0x278c, 0x278e, 0x2790, 0x2792, 0x2794, 0x2796, - 0x2798, 0x279a, 0x279c, 0x279e, 0x27a0, 0x27a2, 0x27a4, 0x27a6, - 0x27a8, 0x27aa, 0x27ac, 0x27ae, 0x27b0, 0x27b2, 0x27b4, 0x27b6, - 0x27b8, 0x27ba, 0x27bc, 0x27be, 0x27c0, 0x27c2, 0x27c4, 0x27c6, - 0x27c8, 0x27ca, 0x27cc, 0x27ce, 0x27d0, 0x27d2, 0x27d4, 0x27d6, - 0x27d8, 0x27da, 0x27dc, 0x27de, 0x27e0, 0x27e2, 0x27e4, 0x27e6, - 0x27e8, 0x27ea, 0x27ec, 0x27ee, 0x27f0, 0x27f2, 0x27f4, 0x27f6, - 0x27f8, 0x27fa, 0x27fc, 0x27fe, 0x2800, 0x2802, 0x2804, 0x2806, - 0x2808, 0x280a, 0x280c, 0x280e, 0x2810, 0x2812, 0x2814, 0x2816, - 0x2818, 0x281a, 0x281c, 0x281e, 0x2820, 0x2822, 0x2824, 0x2826, - 0x2828, 0x282a, 0x282c, 0x282e, 0x2830, 0x2832, 0x2834, 0x2836, - 0x2838, 0x283a, 0x283c, 0x283e, 0x2840, 0x2842, 0x2844, 0xffff, - 0xffff, 0xffff, 0x2846, 0x2848, 0x284a, 0x284c, 0x284e, 0x2850, - 0xffff, 0xffff, 0x2852, 0x2854, 0x2856, 0x2858, 0x285a, 0x285c, - 0xffff, 0xffff, 0x285e, 0x2860, 0x2862, 0x2864, 0x2866, 0x2868, - 0xffff, 0xffff, 0x286a, 0x286c, 0x286e, 0xffff, 0xffff, 0xffff, - 0x2870, 0x2872, 0x2874, 0x2876, 0x2878, 0x287a, 0x287c, 0xffff, - 0x287e, 0x2880, 0x2882, 0x2884, 0x2886, 0x2888, 0x288a, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x288c, 0x2891, - 0x2896, 0x289b, 0x28a0, 0x28a5, 0x28aa, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x28af, 0x28b4, 0x28b9, 0x28be, 0x28c3, - 0x28c8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x28cd, 0x28cf, 0x28d1, 0x28d3, 0x28d5, 0x28d7, 0x28d9, 0x28db, - 0x28dd, 0x28df, 0x28e1, 0x28e3, 0x28e5, 0x28e7, 0x28e9, 0x28eb, - 0x28ed, 0x28ef, 0x28f1, 0x28f3, 0x28f5, 0x28f7, 0x28f9, 0x28fb, - 0x28fd, 0x28ff, 0x2901, 0x2903, 0x2905, 0x2907, 0x2909, 0x290b, - 0x290d, 0x290f, 0x2911, 0x2913, 0x2915, 0x2917, 0x2919, 0x291b, - 0x291d, 0x291f, 0x2921, 0x2923, 0x2925, 0x2927, 0x2929, 0x292b, - 0x292d, 0x292f, 0x2931, 0x2933, 0x2935, 0x2937, 0x2939, 0x293b, - 0x293d, 0x293f, 0x2941, 0x2943, 0x2945, 0x2947, 0x2949, 0x294b, - 0x294d, 0x294f, 0x2951, 0x2953, 0x2955, 0x2957, 0x2959, 0x295b, - 0x295d, 0x295f, 0x2961, 0x2963, 0x2965, 0x2967, 0x2969, 0x296b, - 0x296d, 0x296f, 0x2971, 0x2973, 0x2975, 0xffff, 0x2977, 0x2979, - 0x297b, 0x297d, 0x297f, 0x2981, 0x2983, 0x2985, 0x2987, 0x2989, - 0x298b, 0x298d, 0x298f, 0x2991, 0x2993, 0x2995, 0x2997, 0x2999, - 0x299b, 0x299d, 0x299f, 0x29a1, 0x29a3, 0x29a5, 0x29a7, 0x29a9, - 0x29ab, 0x29ad, 0x29af, 0x29b1, 0x29b3, 0x29b5, 0x29b7, 0x29b9, - 0x29bb, 0x29bd, 0x29bf, 0x29c1, 0x29c3, 0x29c5, 0x29c7, 0x29c9, - 0x29cb, 0x29cd, 0x29cf, 0x29d1, 0x29d3, 0x29d5, 0x29d7, 0x29d9, - 0x29db, 0x29dd, 0x29df, 0x29e1, 0x29e3, 0x29e5, 0x29e7, 0x29e9, - 0x29eb, 0x29ed, 0x29ef, 0x29f1, 0x29f3, 0x29f5, 0x29f7, 0x29f9, - 0x29fb, 0x29fd, 0x29ff, 0x2a01, 0x2a03, 0xffff, 0x2a05, 0x2a07, - 0xffff, 0xffff, 0x2a09, 0xffff, 0xffff, 0x2a0b, 0x2a0d, 0xffff, - 0xffff, 0x2a0f, 0x2a11, 0x2a13, 0x2a15, 0xffff, 0x2a17, 0x2a19, - 0x2a1b, 0x2a1d, 0x2a1f, 0x2a21, 0x2a23, 0x2a25, 0x2a27, 0x2a29, - 0x2a2b, 0x2a2d, 0xffff, 0x2a2f, 0xffff, 0x2a31, 0x2a33, 0x2a35, - 0x2a37, 0x2a39, 0x2a3b, 0x2a3d, 0xffff, 0x2a3f, 0x2a41, 0x2a43, - 0x2a45, 0x2a47, 0x2a49, 0x2a4b, 0x2a4d, 0x2a4f, 0x2a51, 0x2a53, - 0x2a55, 0x2a57, 0x2a59, 0x2a5b, 0x2a5d, 0x2a5f, 0x2a61, 0x2a63, - 0x2a65, 0x2a67, 0x2a69, 0x2a6b, 0x2a6d, 0x2a6f, 0x2a71, 0x2a73, - 0x2a75, 0x2a77, 0x2a79, 0x2a7b, 0x2a7d, 0x2a7f, 0x2a81, 0x2a83, - 0x2a85, 0x2a87, 0x2a89, 0x2a8b, 0x2a8d, 0x2a8f, 0x2a91, 0x2a93, - 0x2a95, 0x2a97, 0x2a99, 0x2a9b, 0x2a9d, 0x2a9f, 0x2aa1, 0x2aa3, - 0x2aa5, 0x2aa7, 0x2aa9, 0x2aab, 0x2aad, 0x2aaf, 0x2ab1, 0x2ab3, - - 0x2ab5, 0x2ab7, 0x2ab9, 0x2abb, 0x2abd, 0x2abf, 0xffff, 0x2ac1, - 0x2ac3, 0x2ac5, 0x2ac7, 0xffff, 0xffff, 0x2ac9, 0x2acb, 0x2acd, - 0x2acf, 0x2ad1, 0x2ad3, 0x2ad5, 0x2ad7, 0xffff, 0x2ad9, 0x2adb, - 0x2add, 0x2adf, 0x2ae1, 0x2ae3, 0x2ae5, 0xffff, 0x2ae7, 0x2ae9, - 0x2aeb, 0x2aed, 0x2aef, 0x2af1, 0x2af3, 0x2af5, 0x2af7, 0x2af9, - 0x2afb, 0x2afd, 0x2aff, 0x2b01, 0x2b03, 0x2b05, 0x2b07, 0x2b09, - 0x2b0b, 0x2b0d, 0x2b0f, 0x2b11, 0x2b13, 0x2b15, 0x2b17, 0x2b19, - 0x2b1b, 0x2b1d, 0xffff, 0x2b1f, 0x2b21, 0x2b23, 0x2b25, 0xffff, - 0x2b27, 0x2b29, 0x2b2b, 0x2b2d, 0x2b2f, 0xffff, 0x2b31, 0xffff, - 0xffff, 0xffff, 0x2b33, 0x2b35, 0x2b37, 0x2b39, 0x2b3b, 0x2b3d, - 0x2b3f, 0xffff, 0x2b41, 0x2b43, 0x2b45, 0x2b47, 0x2b49, 0x2b4b, - 0x2b4d, 0x2b4f, 0x2b51, 0x2b53, 0x2b55, 0x2b57, 0x2b59, 0x2b5b, - 0x2b5d, 0x2b5f, 0x2b61, 0x2b63, 0x2b65, 0x2b67, 0x2b69, 0x2b6b, - 0x2b6d, 0x2b6f, 0x2b71, 0x2b73, 0x2b75, 0x2b77, 0x2b79, 0x2b7b, - 0x2b7d, 0x2b7f, 0x2b81, 0x2b83, 0x2b85, 0x2b87, 0x2b89, 0x2b8b, - 0x2b8d, 0x2b8f, 0x2b91, 0x2b93, 0x2b95, 0x2b97, 0x2b99, 0x2b9b, - 0x2b9d, 0x2b9f, 0x2ba1, 0x2ba3, 0x2ba5, 0x2ba7, 0x2ba9, 0x2bab, - 0x2bad, 0x2baf, 0x2bb1, 0x2bb3, 0x2bb5, 0x2bb7, 0x2bb9, 0x2bbb, - 0x2bbd, 0x2bbf, 0x2bc1, 0x2bc3, 0x2bc5, 0x2bc7, 0x2bc9, 0x2bcb, - 0x2bcd, 0x2bcf, 0x2bd1, 0x2bd3, 0x2bd5, 0x2bd7, 0x2bd9, 0x2bdb, - 0x2bdd, 0x2bdf, 0x2be1, 0x2be3, 0x2be5, 0x2be7, 0x2be9, 0x2beb, - 0x2bed, 0x2bef, 0x2bf1, 0x2bf3, 0x2bf5, 0x2bf7, 0x2bf9, 0x2bfb, - 0x2bfd, 0x2bff, 0x2c01, 0x2c03, 0x2c05, 0x2c07, 0x2c09, 0x2c0b, - 0x2c0d, 0x2c0f, 0x2c11, 0x2c13, 0x2c15, 0x2c17, 0x2c19, 0x2c1b, - 0x2c1d, 0x2c1f, 0x2c21, 0x2c23, 0x2c25, 0x2c27, 0x2c29, 0x2c2b, - 0x2c2d, 0x2c2f, 0x2c31, 0x2c33, 0x2c35, 0x2c37, 0x2c39, 0x2c3b, - 0x2c3d, 0x2c3f, 0x2c41, 0x2c43, 0x2c45, 0x2c47, 0x2c49, 0x2c4b, - 0x2c4d, 0x2c4f, 0x2c51, 0x2c53, 0x2c55, 0x2c57, 0x2c59, 0x2c5b, - 0x2c5d, 0x2c5f, 0x2c61, 0x2c63, 0x2c65, 0x2c67, 0x2c69, 0x2c6b, - 0x2c6d, 0x2c6f, 0x2c71, 0x2c73, 0x2c75, 0x2c77, 0x2c79, 0x2c7b, - 0x2c7d, 0x2c7f, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, - 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, - - 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, - 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, - 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, - 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, - 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce5, 0x2ce7, 0x2ce9, 0x2ceb, - 0x2ced, 0x2cef, 0x2cf1, 0x2cf3, 0x2cf5, 0x2cf7, 0x2cf9, 0x2cfb, - 0x2cfd, 0x2cff, 0x2d01, 0x2d03, 0x2d05, 0x2d07, 0x2d09, 0x2d0b, - 0x2d0d, 0x2d0f, 0x2d11, 0x2d13, 0x2d15, 0x2d17, 0x2d19, 0x2d1b, - 0x2d1d, 0x2d1f, 0x2d21, 0x2d23, 0x2d25, 0x2d27, 0x2d29, 0x2d2b, - 0x2d2d, 0x2d2f, 0x2d31, 0x2d33, 0x2d35, 0x2d37, 0x2d39, 0x2d3b, - 0x2d3d, 0x2d3f, 0x2d41, 0x2d43, 0x2d45, 0x2d47, 0x2d49, 0x2d4b, - 0x2d4d, 0x2d4f, 0x2d51, 0x2d53, 0x2d55, 0x2d57, 0x2d59, 0x2d5b, - 0x2d5d, 0x2d5f, 0x2d61, 0x2d63, 0x2d65, 0x2d67, 0x2d69, 0x2d6b, - 0x2d6d, 0x2d6f, 0x2d71, 0x2d73, 0x2d75, 0x2d77, 0x2d79, 0x2d7b, - 0x2d7d, 0x2d7f, 0x2d81, 0x2d83, 0x2d85, 0x2d87, 0x2d89, 0x2d8b, - 0x2d8d, 0x2d8f, 0x2d91, 0x2d93, 0x2d95, 0x2d97, 0x2d99, 0x2d9b, - 0x2d9d, 0x2d9f, 0x2da1, 0x2da3, 0x2da5, 0x2da7, 0x2da9, 0x2dab, - 0x2dad, 0x2daf, 0x2db1, 0x2db3, 0x2db5, 0x2db7, 0x2db9, 0x2dbb, - 0x2dbd, 0x2dbf, 0x2dc1, 0x2dc3, 0x2dc5, 0x2dc7, 0x2dc9, 0x2dcb, - 0x2dcd, 0x2dcf, 0x2dd1, 0x2dd3, 0x2dd5, 0x2dd7, 0x2dd9, 0x2ddb, - 0x2ddd, 0x2ddf, 0x2de1, 0x2de3, 0x2de5, 0x2de7, 0xffff, 0xffff, - 0x2de9, 0x2deb, 0x2ded, 0x2def, 0x2df1, 0x2df3, 0x2df5, 0x2df7, - 0x2df9, 0x2dfb, 0x2dfd, 0x2dff, 0x2e01, 0x2e03, 0x2e05, 0x2e07, - 0x2e09, 0x2e0b, 0x2e0d, 0x2e0f, 0x2e11, 0x2e13, 0x2e15, 0x2e17, - 0x2e19, 0x2e1b, 0x2e1d, 0x2e1f, 0x2e21, 0x2e23, 0x2e25, 0x2e27, - 0x2e29, 0x2e2b, 0x2e2d, 0x2e2f, 0x2e31, 0x2e33, 0x2e35, 0x2e37, - 0x2e39, 0x2e3b, 0x2e3d, 0x2e3f, 0x2e41, 0x2e43, 0x2e45, 0x2e47, - 0x2e49, 0x2e4b, 0x2e4d, 0x2e4f, 0x2e51, 0x2e53, 0x2e55, 0x2e57, - 0x2e59, 0x2e5b, 0x2e5d, 0x2e5f, 0x2e61, 0x2e63, 0x2e65, 0x2e67, - 0x2e69, 0x2e6b, 0x2e6d, 0x2e6f, 0x2e71, 0x2e73, 0x2e75, 0x2e77, - 0x2e79, 0x2e7b, 0x2e7d, 0x2e7f, 0x2e81, 0x2e83, 0x2e85, 0x2e87, - 0x2e89, 0x2e8b, 0x2e8d, 0x2e8f, 0x2e91, 0x2e93, 0x2e95, 0x2e97, - - 0x2e99, 0x2e9b, 0x2e9d, 0x2e9f, 0x2ea1, 0x2ea3, 0x2ea5, 0x2ea7, - 0x2ea9, 0x2eab, 0x2ead, 0x2eaf, 0x2eb1, 0x2eb3, 0x2eb5, 0x2eb7, - 0x2eb9, 0x2ebb, 0x2ebd, 0x2ebf, 0x2ec1, 0x2ec3, 0x2ec5, 0x2ec7, - 0x2ec9, 0x2ecb, 0x2ecd, 0x2ecf, 0x2ed1, 0x2ed3, 0x2ed5, 0x2ed7, - 0x2ed9, 0x2edb, 0x2edd, 0x2edf, 0x2ee1, 0x2ee3, 0x2ee5, 0x2ee7, - 0x2ee9, 0x2eeb, 0x2eed, 0x2eef, 0x2ef1, 0x2ef3, 0x2ef5, 0x2ef7, - 0x2ef9, 0x2efb, 0x2efd, 0x2eff, 0x2f01, 0x2f03, 0x2f05, 0x2f07, - 0x2f09, 0x2f0b, 0x2f0d, 0x2f0f, 0x2f11, 0x2f13, 0x2f15, 0x2f17, - 0x2f19, 0x2f1b, 0x2f1d, 0x2f1f, 0x2f21, 0x2f23, 0x2f25, 0x2f27, - 0x2f29, 0x2f2b, 0x2f2d, 0x2f2f, 0x2f31, 0x2f33, 0x2f35, 0x2f37, - 0x2f39, 0x2f3b, 0x2f3d, 0x2f3f, 0x2f41, 0x2f43, 0x2f45, 0x2f47, - 0x2f49, 0x2f4b, 0x2f4d, 0x2f4f, 0x2f51, 0x2f53, 0x2f55, 0x2f57, - 0x2f59, 0x2f5b, 0x2f5d, 0x2f5f, 0x2f61, 0x2f63, 0x2f65, 0x2f67, - 0x2f69, 0x2f6b, 0x2f6d, 0x2f6f, 0x2f71, 0x2f73, 0x2f75, 0x2f77, - 0x2f79, 0x2f7b, 0x2f7d, 0x2f7f, 0x2f81, 0x2f83, 0x2f85, 0x2f87, - 0x2f89, 0x2f8b, 0x2f8d, 0x2f8f, 0x2f91, 0x2f93, 0x2f95, 0x2f97, - 0x2f99, 0x2f9b, 0x2f9d, 0x2f9f, 0x2fa1, 0x2fa3, 0x2fa5, 0x2fa7, - 0x2fa9, 0x2fab, 0x2fad, 0x2faf, 0x2fb1, 0x2fb3, 0x2fb5, 0x2fb7, - 0x2fb9, 0x2fbb, 0x2fbd, 0x2fbf, 0x2fc1, 0x2fc3, 0x2fc5, 0x2fc7, - 0x2fc9, 0x2fcb, 0x2fcd, 0x2fcf, 0x2fd1, 0x2fd3, 0x2fd5, 0x2fd7, - 0x2fd9, 0x2fdb, 0x2fdd, 0x2fdf, 0x2fe1, 0x2fe3, 0x2fe5, 0x2fe7, - 0x2fe9, 0x2feb, 0x2fed, 0x2fef, 0x2ff1, 0x2ff3, 0x2ff5, 0x2ff7, - 0x2ff9, 0x2ffb, 0x2ffd, 0x2fff, 0x3001, 0x3003, 0x3005, 0x3007, - 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3013, 0x3015, 0x3017, - 0x3019, 0x301b, 0x301d, 0x301f, 0x3021, 0x3023, 0x3025, 0x3027, - 0x3029, 0x302b, 0x302d, 0x302f, 0xffff, 0xffff, 0x3031, 0x3033, - 0x3035, 0x3037, 0x3039, 0x303b, 0x303d, 0x303f, 0x3041, 0x3043, - 0x3045, 0x3047, 0x3049, 0x304b, 0x304d, 0x304f, 0x3051, 0x3053, - 0x3055, 0x3057, 0x3059, 0x305b, 0x305d, 0x305f, 0x3061, 0x3063, - 0x3065, 0x3067, 0x3069, 0x306b, 0x306d, 0x306f, 0x3071, 0x3073, - 0x3075, 0x3077, 0x3079, 0x307b, 0x307d, 0x307f, 0x3081, 0x3083, - 0x3085, 0x3087, 0x3089, 0x308b, 0x308d, 0x308f, 0x3091, 0x3093, - - 0x3095, 0x3097, 0x3099, 0x309b, 0x309e, 0x30a0, 0x30a2, 0x30a4, - 0x30a6, 0x30a8, 0x30aa, 0x30ac, 0x30ae, 0x30b0, 0x30b3, 0x30b5, - 0x30b7, 0x30b9, 0x30bb, 0x30be, 0x30c0, 0x30c2, 0x30c4, 0x30c7, - 0x30c9, 0x30cb, 0x30cd, 0x30cf, 0x30d1, 0x30d4, 0x30d6, 0x30d8, - 0x30da, 0x30dc, 0x30de, 0x30e0, 0x30e2, 0x30e4, 0x30e6, 0x30e8, - 0x30ea, 0x30ec, 0x30ee, 0x30f0, 0x30f2, 0x30f4, 0x30f6, 0x30f8, - 0x30fa, 0x30fc, 0x30fe, 0x3100, 0x3102, 0x3105, 0x3107, 0x3109, - 0x310b, 0x310e, 0x3110, 0x3112, 0x3114, 0x3116, 0x3118, 0x311a, - 0x311c, 0x311e, 0x3120, 0x3122, 0x3124, 0x3126, 0x3128, 0x312a, - 0x312c, 0x312e, 0x3130, 0x3132, 0x3134, 0x3136, 0x3138, 0x313a, - 0x313c, 0x313e, 0x3140, 0x3142, 0x3144, 0x3146, 0x3148, 0x314a, - 0x314c, 0x314e, 0x3151, 0x3153, 0x3155, 0x3157, 0x3159, 0x315b, - 0x315d, 0x3160, 0x3163, 0x3165, 0x3167, 0x3169, 0x316b, 0x316d, - 0x316f, 0x3171, 0x3173, 0x3175, 0x3177, 0x317a, 0x317c, 0x317e, - 0x3180, 0x3182, 0x3185, 0x3187, 0x3189, 0x318b, 0x318d, 0x318f, - 0x3191, 0x3193, 0x3195, 0x3197, 0x319a, 0x319c, 0x319f, 0x31a1, - 0x31a3, 0x31a5, 0x31a7, 0x31a9, 0x31ab, 0x31ad, 0x31af, 0x31b1, - 0x31b3, 0x31b5, 0x31b8, 0x31ba, 0x31bc, 0x31be, 0x31c0, 0x31c2, - 0x31c5, 0x31c7, 0x31ca, 0x31cd, 0x31cf, 0x31d1, 0x31d3, 0x31d5, - 0x31d8, 0x31db, 0x31dd, 0x31df, 0x31e1, 0x31e3, 0x31e5, 0x31e7, - 0x31e9, 0x31eb, 0x31ed, 0x31ef, 0x31f1, 0x31f4, 0x31f6, 0x31f8, - 0x31fa, 0x31fc, 0x31fe, 0x3200, 0x3202, 0x3204, 0x3206, 0x3208, - 0x320a, 0x320c, 0x320e, 0x3210, 0x3212, 0x3214, 0x3216, 0x3218, - 0x321a, 0x321d, 0x321f, 0x3221, 0x3223, 0x3225, 0x3227, 0x322a, - 0x322c, 0x322e, 0x3230, 0x3232, 0x3234, 0x3236, 0x3238, 0x323a, - 0x323c, 0x323e, 0x3240, 0x3243, 0x3245, 0x3247, 0x3249, 0x324b, - 0x324d, 0x324f, 0x3251, 0x3253, 0x3255, 0x3257, 0x3259, 0x325b, - 0x325d, 0x325f, 0x3261, 0x3263, 0x3265, 0x3267, 0x326a, 0x326c, - 0x326e, 0x3270, 0x3272, 0x3274, 0x3277, 0x3279, 0x327b, 0x327d, - 0x327f, 0x3281, 0x3283, 0x3285, 0x3287, 0x328a, 0x328c, 0x328e, - 0x3290, 0x3293, 0x3295, 0x3297, 0x3299, 0x329b, 0x329d, 0x329f, - 0x32a2, 0x32a5, 0x32a8, 0x32aa, 0x32ad, 0x32af, 0x32b1, 0x32b3, - - 0x32b5, 0x32b7, 0x32b9, 0x32bb, 0x32bd, 0x32bf, 0x32c1, 0x32c4, - 0x32c6, 0x32c8, 0x32ca, 0x32cc, 0x32ce, 0x32d0, 0x32d3, 0x32d5, - 0x32d7, 0x32da, 0x32dd, 0x32df, 0x32e1, 0x32e3, 0x32e5, 0x32e7, - 0x32e9, 0x32eb, 0x32ed, 0x32ef, 0x32f2, 0x32f4, 0x32f7, 0x32f9, - 0x32fc, 0x32fe, 0x3300, 0x3302, 0x3305, 0x3307, 0x3309, 0x330c, - 0x330f, 0x3311, 0x3313, 0x3315, 0x3317, 0x3319, 0x331b, 0x331d, - 0x331f, 0x3321, 0x3323, 0x3325, 0x3327, 0x3329, 0x332c, 0x332e, - 0x3331, 0x3333, 0x3336, 0x3338, 0x333b, 0x333e, 0x3341, 0x3343, - 0x3345, 0x3347, 0x334a, 0x334d, 0x3350, 0x3353, 0x3355, 0x3357, - 0x3359, 0x335b, 0x335d, 0x335f, 0x3361, 0x3363, 0x3366, 0x3368, - 0x336a, 0x336c, 0x336e, 0x3371, 0x3373, 0x3376, 0x3379, 0x337b, - 0x337d, 0x337f, 0x3381, 0x3383, 0x3385, 0x3388, 0x338b, 0x338e, - 0x3390, 0x3392, 0x3395, 0x3397, 0x3399, 0x339b, 0x339e, 0x33a0, - 0x33a2, 0x33a4, 0x33a6, 0x33a8, 0x33ab, 0x33ad, 0x33af, 0x33b1, - 0x33b3, 0x33b5, 0x33b7, 0x33ba, 0x33bd, 0x33bf, 0x33c2, 0x33c4, - 0x33c7, 0x33c9, 0x33cb, 0x33cd, 0x33d0, 0x33d3, 0x33d5, 0x33d8, - 0x33da, 0x33dd, 0x33df, 0x33e1, 0x33e3, 0x33e5, 0x33e7, 0x33e9, - 0x33ec, 0x33ef, 0x33f2, 0x33f5, 0x33f7, 0x33f9, 0x33fb, 0x33fd, - 0x33ff, 0x3401, 0x3403, 0x3405, 0x3407, 0x3409, 0x340b, 0x340d, - 0x3410, 0x3412, 0x3414, 0x3416, 0x3418, 0x341a, 0x341c, 0x341e, - 0x3420, 0x3422, 0x3424, 0x3426, 0x3428, 0x342b, 0x342e, 0x3431, - 0x3433, 0x3435, 0x3437, 0x3439, 0x343c, 0x343e, 0x3441, 0x3443, - 0x3445, 0x3448, 0x344b, 0x344d, 0x344f, 0x3451, 0x3453, 0x3455, - 0x3457, 0x3459, 0x345b, 0x345d, 0x345f, 0x3461, 0x3463, 0x3465, - 0x3467, 0x3469, 0x346b, 0x346d, 0x346f, 0x3471, 0x3474, 0x3476, - 0x3478, 0x347a, 0x347c, 0x347e, 0x3481, 0x3484, 0x3486, 0x3488, - 0x348a, 0x348c, 0x348e, 0x3490, 0x3493, 0x3495, 0x3497, 0x3499, - 0x349b, 0x349e, 0x34a1, 0x34a3, 0x34a5, 0x34a7, 0x34aa, 0x34ac, - 0x34ae, 0x34b1, 0x34b4, 0x34b6, 0x34b8, 0x34ba, 0x34bd, 0x34bf, - 0x34c1, 0x34c3, 0x34c5, 0x34c7, 0x34c9, 0x34cb, 0x34ce, 0x34d0, - 0x34d2, 0x34d4, 0x34d7, 0x34d9, 0x34db, 0x34dd, 0x34df, 0x34e2, - 0x34e5, 0x34e7, 0x34e9, 0x34eb, 0x34ee, 0x34f0, 0x34f3, 0x34f5, - - 0x34f7, 0x34f9, 0x34fc, 0x34fe, 0x3500, 0x3502, 0x3504, 0x3506, - 0x3508, 0x350a, 0x350d, 0x350f, 0x3511, 0x3513, 0x3515, 0x3517, - 0x3519, 0x351c, 0x351e, 0x3521, 0x3524, 0x3527, 0x3529, 0x352b, - 0x352d, 0x352f, 0x3531, 0x3533, 0x3535, 0x3537, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x163f, 0x1642, 0x1646, 0x164b, 0x1650, 0x1653, 0x1659, 0x1660, + 0x1666, 0x166a, 0x1670, 0x1676, 0x167b, 0x167f, 0x1683, 0x1687, + + 0x168c, 0x1692, 0x1697, 0x169b, 0x169f, 0x16a3, 0x16a6, 0x16a9, + 0x16ac, 0x16af, 0x16b3, 0x16b7, 0x16bd, 0x16c1, 0x16c6, 0x16cc, + + 0x16d0, 0x16d3, 0x16d6, 0x16dc, 0x16e1, 0x16e7, 0x16eb, 0x16f1, + 0x16f4, 0x16f8, 0x16fc, 0x1700, 0x1704, 0x1708, 0x170d, 0x1711, + + 0x1714, 0x1718, 0x171c, 0x1720, 0x1725, 0x1729, 0x172d, 0x1731, + 0x1737, 0x173c, 0x173f, 0x1745, 0x1748, 0x174d, 0x1752, 0x1756, + + 0x175a, 0x175e, 0x1763, 0x1766, 0x176a, 0x176f, 0x1772, 0x1778, + 0x177c, 0x177f, 0x1782, 0x1785, 0x1788, 0x178b, 0x178e, 0x1791, + + 0x1794, 0x1797, 0x179a, 0x179e, 0x17a2, 0x17a6, 0x17aa, 0x17ae, + 0x17b2, 0x17b6, 0x17ba, 0x17be, 0x17c2, 0x17c6, 0x17ca, 0x17ce, + + 0x17d2, 0x17d6, 0x17da, 0x17dd, 0x17e0, 0x17e4, 0x17e7, 0x17ea, + 0x17ed, 0x17f1, 0x17f5, 0x17f8, 0x17fb, 0x17fe, 0x1801, 0x1804, + + 0x1809, 0x180c, 0x180f, 0x1812, 0x1815, 0x1818, 0x181b, 0x181e, + 0x1821, 0x1825, 0x182a, 0x182d, 0x1830, 0x1833, 0x1836, 0x1839, + + 0x183c, 0x183f, 0x1843, 0x1847, 0x184b, 0x184f, 0x1852, 0x1855, + 0x1858, 0x185b, 0x185e, 0x1861, 0x1864, 0x1867, 0x186a, 0x186d, + + 0x1871, 0x1875, 0x1878, 0x187c, 0x1880, 0x1884, 0x1887, 0x188b, + 0x188f, 0x1894, 0x1897, 0x189b, 0x189f, 0x18a3, 0x18a7, 0x18ad, + + 0x18b4, 0x18b7, 0x18ba, 0x18bd, 0x18c0, 0x18c3, 0x18c6, 0x18c9, + 0x18cc, 0x18cf, 0x18d2, 0x18d5, 0x18d8, 0x18db, 0x18de, 0x18e1, + + 0x18e4, 0x18e7, 0x18ea, 0x18ef, 0x18f2, 0x18f5, 0x18f8, 0x18fd, + 0x1901, 0x1904, 0x1907, 0x190a, 0x190d, 0x1910, 0x1913, 0x1916, + + 0x1919, 0x191c, 0x191f, 0x1923, 0x1926, 0x1929, 0x192d, 0x1931, + 0x1934, 0x1939, 0x193d, 0x1940, 0x1943, 0x1946, 0x1949, 0x194d, + + 0x1951, 0x1954, 0x1957, 0x195a, 0x195d, 0x1960, 0x1963, 0x1966, + 0x1969, 0x196c, 0x1970, 0x1974, 0x1978, 0x197c, 0x1980, 0x1984, + + 0x1988, 0x198c, 0x1990, 0x1994, 0x1998, 0x199c, 0x19a0, 0x19a4, + 0x19a8, 0x19ac, 0x19b0, 0x19b4, 0x19b8, 0x19bc, 0x19c0, 0x19c4, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x19c8, 0x19ca, 0x19cc, 0x19ce, 0x19d0, 0x19d2, 0x19d4, 0x19d6, + 0x19d8, 0x19da, 0x19dc, 0x19de, 0x19e0, 0x19e2, 0x19e4, 0x19e6, + 0x19e8, 0x19ea, 0x19ec, 0x19ee, 0x19f0, 0x19f2, 0x19f4, 0x19f6, + 0x19f8, 0x19fa, 0x19fc, 0x19fe, 0x1a00, 0x1a02, 0x1a04, 0x1a06, + 0x1a08, 0x1a0a, 0x1a0c, 0x1a0e, 0x1a10, 0x1a12, 0x1a14, 0x1a16, + 0x1a18, 0x1a1a, 0x1a1c, 0x1a1e, 0x1a20, 0x1a22, 0x1a24, 0x1a26, + 0x1a28, 0x1a2a, 0x1a2c, 0x1a2e, 0x1a30, 0x1a32, 0x1a34, 0x1a36, + 0x1a38, 0x1a3a, 0x1a3c, 0x1a3e, 0x1a40, 0x1a42, 0x1a44, 0x1a46, + 0x1a48, 0x1a4a, 0x1a4c, 0x1a4e, 0x1a50, 0x1a52, 0x1a54, 0x1a56, + 0x1a58, 0x1a5a, 0x1a5c, 0x1a5e, 0x1a60, 0x1a62, 0x1a64, 0x1a66, + 0x1a68, 0x1a6a, 0x1a6c, 0x1a6e, 0x1a70, 0x1a72, 0x1a74, 0x1a76, + 0x1a78, 0x1a7a, 0x1a7c, 0x1a7e, 0x1a80, 0x1a82, 0x1a84, 0x1a86, + 0x1a88, 0x1a8a, 0x1a8c, 0x1a8e, 0x1a90, 0x1a92, 0x1a94, 0x1a96, + 0x1a98, 0x1a9a, 0x1a9c, 0x1a9e, 0x1aa0, 0x1aa2, 0x1aa4, 0x1aa6, + 0x1aa8, 0x1aaa, 0x1aac, 0x1aae, 0x1ab0, 0x1ab2, 0x1ab4, 0x1ab6, + 0x1ab8, 0x1aba, 0x1abc, 0x1abe, 0x1ac0, 0x1ac2, 0x1ac4, 0x1ac6, + 0x1ac8, 0x1aca, 0x1acc, 0x1ace, 0x1ad0, 0x1ad2, 0x1ad4, 0x1ad6, + 0x1ad8, 0x1ada, 0x1adc, 0x1ade, 0x1ae0, 0x1ae2, 0x1ae4, 0x1ae6, + 0x1ae8, 0x1aea, 0x1aec, 0x1aee, 0x1af0, 0x1af2, 0x1af4, 0x1af6, + 0x1af8, 0x1afa, 0x1afc, 0x1afe, 0x1b00, 0x1b02, 0x1b04, 0x1b06, + 0x1b08, 0x1b0a, 0x1b0c, 0x1b0e, 0x1b10, 0x1b12, 0x1b14, 0x1b16, + 0x1b18, 0x1b1a, 0x1b1c, 0x1b1e, 0x1b20, 0x1b22, 0x1b24, 0x1b26, + 0x1b28, 0x1b2a, 0x1b2c, 0x1b2e, 0x1b30, 0x1b32, 0x1b34, 0x1b36, + 0x1b38, 0x1b3a, 0x1b3c, 0x1b3e, 0x1b40, 0x1b42, 0x1b44, 0x1b46, + 0x1b48, 0x1b4a, 0x1b4c, 0x1b4e, 0x1b50, 0x1b52, 0x1b54, 0x1b56, + 0x1b58, 0x1b5a, 0x1b5c, 0x1b5e, 0x1b60, 0x1b62, 0x1b64, 0x1b66, + 0x1b68, 0x1b6a, 0x1b6c, 0x1b6e, 0x1b70, 0x1b72, 0x1b74, 0x1b76, + 0x1b78, 0x1b7a, 0x1b7c, 0x1b7e, 0x1b80, 0x1b82, 0x1b84, 0x1b86, + 0x1b88, 0x1b8a, 0x1b8c, 0x1b8e, 0x1b90, 0x1b92, 0x1b94, 0x1b96, + 0x1b98, 0x1b9a, 0x1b9c, 0x1b9e, 0x1ba0, 0x1ba2, 0x1ba4, 0x1ba6, + 0x1ba8, 0x1baa, 0x1bac, 0x1bae, 0x1bb0, 0x1bb2, 0x1bb4, 0x1bb6, + 0x1bb8, 0x1bba, 0x1bbc, 0x1bbe, 0x1bc0, 0x1bc2, 0x1bc4, 0x1bc6, + + 0x1bc8, 0x1bca, 0x1bcc, 0x1bce, 0x1bd0, 0x1bd2, 0x1bd4, 0x1bd6, + 0x1bd8, 0x1bda, 0x1bdc, 0x1bde, 0x1be0, 0x1be2, 0xffff, 0xffff, + 0x1be4, 0xffff, 0x1be6, 0xffff, 0xffff, 0x1be8, 0x1bea, 0x1bec, + 0x1bee, 0x1bf0, 0x1bf2, 0x1bf4, 0x1bf6, 0x1bf8, 0x1bfa, 0xffff, + 0x1bfc, 0xffff, 0x1bfe, 0xffff, 0xffff, 0x1c00, 0x1c02, 0xffff, + 0xffff, 0xffff, 0x1c04, 0x1c06, 0x1c08, 0x1c0a, 0xffff, 0xffff, + 0x1c0c, 0x1c0e, 0x1c10, 0x1c12, 0x1c14, 0x1c16, 0x1c18, 0x1c1a, + 0x1c1c, 0x1c1e, 0x1c20, 0x1c22, 0x1c24, 0x1c26, 0x1c28, 0x1c2a, + 0x1c2c, 0x1c2e, 0x1c30, 0x1c32, 0x1c34, 0x1c36, 0x1c38, 0x1c3a, + 0x1c3c, 0x1c3e, 0x1c40, 0x1c42, 0x1c44, 0x1c46, 0x1c48, 0x1c4a, + 0x1c4c, 0x1c4e, 0x1c50, 0x1c52, 0x1c54, 0x1c56, 0x1c58, 0x1c5a, + 0x1c5c, 0x1c5e, 0x1c60, 0x1c62, 0x1c64, 0x1c66, 0x1c68, 0x1c6a, + 0x1c6c, 0x1c6e, 0x1c70, 0x1c72, 0x1c74, 0x1c76, 0x1c78, 0x1c7a, + 0x1c7c, 0x1c7e, 0x1c80, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x1c82, 0x1c84, 0x1c86, 0x1c88, 0x1c8a, 0x1c8c, 0x1c8e, 0x1c90, + 0x1c92, 0x1c94, 0x1c96, 0x1c98, 0x1c9a, 0x1c9c, 0x1c9e, 0x1ca0, + 0x1ca2, 0x1ca4, 0x1ca6, 0x1ca8, 0x1caa, 0x1cac, 0x1cae, 0x1cb0, + 0x1cb2, 0x1cb4, 0x1cb6, 0x1cb8, 0x1cba, 0x1cbc, 0x1cbe, 0x1cc0, + 0x1cc2, 0x1cc4, 0x1cc6, 0x1cc8, 0x1cca, 0x1ccc, 0x1cce, 0x1cd0, + 0x1cd2, 0x1cd4, 0x1cd6, 0x1cd8, 0x1cda, 0x1cdc, 0x1cde, 0x1ce0, + 0x1ce2, 0x1ce4, 0x1ce6, 0x1ce8, 0x1cea, 0x1cec, 0x1cee, 0x1cf0, + 0x1cf2, 0x1cf4, 0x1cf6, 0x1cf8, 0x1cfa, 0x1cfc, 0x1cfe, 0x1d00, + 0x1d02, 0x1d04, 0x1d06, 0x1d08, 0x1d0a, 0x1d0c, 0x1d0e, 0x1d10, + 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, 0x1d20, + 0x1d22, 0x1d24, 0x1d26, 0x1d28, 0x1d2a, 0x1d2c, 0x1d2e, 0x1d30, + 0x1d32, 0x1d34, 0x1d36, 0x1d38, 0x1d3a, 0x1d3c, 0x1d3e, 0x1d40, + 0x1d43, 0x1d46, 0x1d49, 0x1d4b, 0x1d4d, 0x1d4f, 0x1d52, 0x1d55, + 0x1d58, 0x1d5a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x1d5c, 0x1d5f, 0x1d62, 0x1d65, 0x1d69, 0x1d6d, 0x1d70, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x1d73, 0x1d76, 0x1d79, 0x1d7c, 0x1d7f, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x1d82, 0xffff, 0x1d85, + 0x1d88, 0x1d8a, 0x1d8c, 0x1d8e, 0x1d90, 0x1d92, 0x1d94, 0x1d96, + 0x1d98, 0x1d9a, 0x1d9c, 0x1d9f, 0x1da2, 0x1da5, 0x1da8, 0x1dab, + 0x1dae, 0x1db1, 0x1db4, 0x1db7, 0x1dba, 0x1dbd, 0x1dc0, 0xffff, + 0x1dc3, 0x1dc6, 0x1dc9, 0x1dcc, 0x1dcf, 0xffff, 0x1dd2, 0xffff, + 0x1dd5, 0x1dd8, 0xffff, 0x1ddb, 0x1dde, 0xffff, 0x1de1, 0x1de4, + 0x1de7, 0x1dea, 0x1ded, 0x1df0, 0x1df3, 0x1df6, 0x1df9, 0x1dfc, + 0x1dff, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, + 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, + 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, + 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, + 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, + 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, + 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, + 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d, + 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d, + 0x1e8f, 0x1e91, 0x1e93, 0x1e95, 0x1e97, 0x1e99, 0x1e9b, 0x1e9d, + 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, + 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, + 0x1ebf, 0x1ec1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, + 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, + 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, + 0x1eed, 0x1eef, 0x1ef1, 0x1ef4, 0x1ef7, 0x1efa, 0x1efd, 0x1f00, + 0x1f03, 0x1f06, 0x1f09, 0x1f0c, 0x1f0f, 0x1f12, 0x1f15, 0x1f18, + 0x1f1b, 0x1f1e, 0x1f21, 0x1f24, 0x1f27, 0x1f29, 0x1f2b, 0x1f2d, + + 0x1f2f, 0x1f32, 0x1f35, 0x1f38, 0x1f3b, 0x1f3e, 0x1f41, 0x1f44, + 0x1f47, 0x1f4a, 0x1f4d, 0x1f50, 0x1f53, 0x1f56, 0x1f59, 0x1f5c, + 0x1f5f, 0x1f62, 0x1f65, 0x1f68, 0x1f6b, 0x1f6e, 0x1f71, 0x1f74, + 0x1f77, 0x1f7a, 0x1f7d, 0x1f80, 0x1f83, 0x1f86, 0x1f89, 0x1f8c, + 0x1f8f, 0x1f92, 0x1f95, 0x1f98, 0x1f9b, 0x1f9e, 0x1fa1, 0x1fa4, + 0x1fa7, 0x1faa, 0x1fad, 0x1fb0, 0x1fb3, 0x1fb6, 0x1fb9, 0x1fbc, + 0x1fbf, 0x1fc2, 0x1fc5, 0x1fc8, 0x1fcb, 0x1fce, 0x1fd1, 0x1fd4, + 0x1fd7, 0x1fda, 0x1fdd, 0x1fe0, 0x1fe3, 0x1fe6, 0x1fe9, 0x1fec, + 0x1fef, 0x1ff2, 0x1ff5, 0x1ff8, 0x1ffb, 0x1ffe, 0x2001, 0x2004, + 0x2007, 0x200a, 0x200d, 0x2010, 0x2013, 0x2016, 0x2019, 0x201c, + 0x201f, 0x2022, 0x2025, 0x2028, 0x202b, 0x202e, 0x2031, 0x2034, + 0x2037, 0x203a, 0x203d, 0x2040, 0x2043, 0x2046, 0x2049, 0x204d, + 0x2051, 0x2055, 0x2059, 0x205d, 0x2061, 0x2064, 0x2067, 0x206a, + 0x206d, 0x2070, 0x2073, 0x2076, 0x2079, 0x207c, 0x207f, 0x2082, + 0x2085, 0x2088, 0x208b, 0x208e, 0x2091, 0x2094, 0x2097, 0x209a, + 0x209d, 0x20a0, 0x20a3, 0x20a6, 0x20a9, 0x20ac, 0x20af, 0x20b2, + 0x20b5, 0x20b8, 0x20bb, 0x20be, 0x20c1, 0x20c4, 0x20c7, 0x20ca, + 0x20cd, 0x20d0, 0x20d3, 0x20d6, 0x20d9, 0x20dc, 0x20df, 0x20e2, + 0x20e5, 0x20e8, 0x20eb, 0x20ee, 0x20f1, 0x20f4, 0x20f7, 0x20fa, + 0x20fd, 0x2100, 0x2103, 0x2106, 0x2109, 0x210c, 0x210f, 0x2112, + 0x2115, 0x2118, 0x211b, 0x211e, 0x2121, 0x2124, 0x2127, 0x212a, + 0x212d, 0x2130, 0x2133, 0x2136, 0x2139, 0x213c, 0x213f, 0x2142, + 0x2145, 0x2148, 0x214b, 0x214e, 0x2151, 0x2154, 0x2157, 0x215a, + 0x215d, 0x2160, 0x2163, 0x2166, 0x2169, 0x216c, 0x216f, 0x2172, + 0x2175, 0x2178, 0x217b, 0x217e, 0x2181, 0x2184, 0x2187, 0x218a, + 0x218d, 0x2190, 0x2193, 0x2196, 0x2199, 0x219c, 0x219f, 0x21a2, + 0x21a5, 0x21a8, 0x21ab, 0x21ae, 0x21b1, 0x21b4, 0x21b7, 0x21ba, + 0x21bd, 0x21c0, 0x21c3, 0x21c6, 0x21c9, 0x21cc, 0x21cf, 0x21d2, + 0x21d5, 0x21d8, 0x21db, 0x21de, 0x21e1, 0x21e4, 0x21e7, 0x21ea, + 0x21ed, 0x21f0, 0x21f3, 0x21f6, 0x21f9, 0x21fc, 0x21ff, 0x2202, + 0x2205, 0x2208, 0x220b, 0x220f, 0x2213, 0x2217, 0x221a, 0x221d, + 0x2220, 0x2223, 0x2226, 0x2229, 0x222c, 0x222f, 0x2232, 0x2235, + + 0x2238, 0x223b, 0x223e, 0x2241, 0x2244, 0x2247, 0x224a, 0x224d, + 0x2250, 0x2253, 0x2256, 0x2259, 0x225c, 0x225f, 0x2262, 0x2265, + 0x2268, 0x226b, 0x226e, 0x2271, 0x2274, 0x2277, 0x227a, 0x227d, + 0x2280, 0x2283, 0x2286, 0x2289, 0x228c, 0x228f, 0x2292, 0x2295, + 0x2298, 0x229b, 0x229e, 0x22a1, 0x22a4, 0x22a7, 0x22aa, 0x22ad, + 0x22b0, 0x22b3, 0x22b6, 0x22b9, 0x22bc, 0x22bf, 0x22c2, 0x22c5, + 0x22c8, 0x22cb, 0x22ce, 0x22d1, 0x22d4, 0x22d7, 0x22da, 0x22dd, + 0x22e0, 0x22e3, 0x22e6, 0x22e9, 0x22ec, 0x22ef, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x22f2, 0x22f6, 0x22fa, 0x22fe, 0x2302, 0x2306, 0x230a, 0x230e, + 0x2312, 0x2316, 0x231a, 0x231e, 0x2322, 0x2326, 0x232a, 0x232e, + 0x2332, 0x2336, 0x233a, 0x233e, 0x2342, 0x2346, 0x234a, 0x234e, + 0x2352, 0x2356, 0x235a, 0x235e, 0x2362, 0x2366, 0x236a, 0x236e, + 0x2372, 0x2376, 0x237a, 0x237e, 0x2382, 0x2386, 0x238a, 0x238e, + 0x2392, 0x2396, 0x239a, 0x239e, 0x23a2, 0x23a6, 0x23aa, 0x23ae, + 0x23b2, 0x23b6, 0x23ba, 0x23be, 0x23c2, 0x23c6, 0x23ca, 0x23ce, + 0x23d2, 0x23d6, 0x23da, 0x23de, 0x23e2, 0x23e6, 0x23ea, 0x23ee, + 0xffff, 0xffff, 0x23f2, 0x23f6, 0x23fa, 0x23fe, 0x2402, 0x2406, + 0x240a, 0x240e, 0x2412, 0x2416, 0x241a, 0x241e, 0x2422, 0x2426, + 0x242a, 0x242e, 0x2432, 0x2436, 0x243a, 0x243e, 0x2442, 0x2446, + 0x244a, 0x244e, 0x2452, 0x2456, 0x245a, 0x245e, 0x2462, 0x2466, + 0x246a, 0x246e, 0x2472, 0x2476, 0x247a, 0x247e, 0x2482, 0x2486, + 0x248a, 0x248e, 0x2492, 0x2496, 0x249a, 0x249e, 0x24a2, 0x24a6, + 0x24aa, 0x24ae, 0x24b2, 0x24b6, 0x24ba, 0x24be, 0x24c2, 0x24c6, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x24ca, 0x24ce, 0x24d2, 0x24d7, 0x24dc, 0x24e1, 0x24e6, 0x24eb, + 0x24f0, 0x24f5, 0x24f9, 0x250c, 0x2515, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x251a, 0x251c, 0x251e, 0x2520, 0x2522, 0x2524, 0x2526, 0x2528, + 0x252a, 0x252c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x252e, 0x2530, 0x2532, 0x2534, 0x2536, 0x2538, 0x253a, 0x253c, + 0x253e, 0x2540, 0x2542, 0x2544, 0x2546, 0x2548, 0x254a, 0x254c, + 0x254e, 0x2550, 0x2552, 0x2554, 0x2556, 0xffff, 0xffff, 0x2558, + 0x255a, 0x255c, 0x255e, 0x2560, 0x2562, 0x2564, 0x2566, 0x2568, + 0x256a, 0x256c, 0x256e, 0xffff, 0x2570, 0x2572, 0x2574, 0x2576, + 0x2578, 0x257a, 0x257c, 0x257e, 0x2580, 0x2582, 0x2584, 0x2586, + 0x2588, 0x258a, 0x258c, 0x258e, 0x2590, 0x2592, 0x2594, 0xffff, + 0x2596, 0x2598, 0x259a, 0x259c, 0xffff, 0xffff, 0xffff, 0xffff, + 0x259e, 0x25a1, 0x25a4, 0xffff, 0x25a7, 0xffff, 0x25aa, 0x25ad, + 0x25b0, 0x25b3, 0x25b6, 0x25b9, 0x25bc, 0x25bf, 0x25c2, 0x25c5, + 0x25c8, 0x25ca, 0x25cc, 0x25ce, 0x25d0, 0x25d2, 0x25d4, 0x25d6, + 0x25d8, 0x25da, 0x25dc, 0x25de, 0x25e0, 0x25e2, 0x25e4, 0x25e6, + 0x25e8, 0x25ea, 0x25ec, 0x25ee, 0x25f0, 0x25f2, 0x25f4, 0x25f6, + 0x25f8, 0x25fa, 0x25fc, 0x25fe, 0x2600, 0x2602, 0x2604, 0x2606, + 0x2608, 0x260a, 0x260c, 0x260e, 0x2610, 0x2612, 0x2614, 0x2616, + 0x2618, 0x261a, 0x261c, 0x261e, 0x2620, 0x2622, 0x2624, 0x2626, + 0x2628, 0x262a, 0x262c, 0x262e, 0x2630, 0x2632, 0x2634, 0x2636, + 0x2638, 0x263a, 0x263c, 0x263e, 0x2640, 0x2642, 0x2644, 0x2646, + 0x2648, 0x264a, 0x264c, 0x264e, 0x2650, 0x2652, 0x2654, 0x2656, + 0x2658, 0x265a, 0x265c, 0x265e, 0x2660, 0x2662, 0x2664, 0x2666, + 0x2668, 0x266a, 0x266c, 0x266e, 0x2670, 0x2672, 0x2674, 0x2676, + 0x2678, 0x267a, 0x267c, 0x267e, 0x2680, 0x2682, 0x2684, 0x2686, + 0x2688, 0x268a, 0x268c, 0x268e, 0x2690, 0x2692, 0x2694, 0x2696, + 0x2698, 0x269a, 0x269c, 0x269e, 0x26a0, 0x26a2, 0x26a4, 0x26a6, + 0x26a8, 0x26aa, 0x26ac, 0x26ae, 0x26b0, 0x26b2, 0x26b5, 0x26b8, + 0x26bb, 0x26be, 0x26c1, 0x26c4, 0x26c7, 0xffff, 0xffff, 0xffff, + + 0xffff, 0x26ca, 0x26cc, 0x26ce, 0x26d0, 0x26d2, 0x26d4, 0x26d6, + 0x26d8, 0x26da, 0x26dc, 0x26de, 0x26e0, 0x26e2, 0x26e4, 0x26e6, + 0x26e8, 0x26ea, 0x26ec, 0x26ee, 0x26f0, 0x26f2, 0x26f4, 0x26f6, + 0x26f8, 0x26fa, 0x26fc, 0x26fe, 0x2700, 0x2702, 0x2704, 0x2706, + 0x2708, 0x270a, 0x270c, 0x270e, 0x2710, 0x2712, 0x2714, 0x2716, + 0x2718, 0x271a, 0x271c, 0x271e, 0x2720, 0x2722, 0x2724, 0x2726, + 0x2728, 0x272a, 0x272c, 0x272e, 0x2730, 0x2732, 0x2734, 0x2736, + 0x2738, 0x273a, 0x273c, 0x273e, 0x2740, 0x2742, 0x2744, 0x2746, + 0x2748, 0x274a, 0x274c, 0x274e, 0x2750, 0x2752, 0x2754, 0x2756, + 0x2758, 0x275a, 0x275c, 0x275e, 0x2760, 0x2762, 0x2764, 0x2766, + 0x2768, 0x276a, 0x276c, 0x276e, 0x2770, 0x2772, 0x2774, 0x2776, + 0x2778, 0x277a, 0x277c, 0x277e, 0x2780, 0x2782, 0x2784, 0x2786, + 0x2788, 0x278a, 0x278c, 0x278e, 0x2790, 0x2792, 0x2794, 0x2796, + 0x2798, 0x279a, 0x279c, 0x279e, 0x27a0, 0x27a2, 0x27a4, 0x27a6, + 0x27a8, 0x27aa, 0x27ac, 0x27ae, 0x27b0, 0x27b2, 0x27b4, 0x27b6, + 0x27b8, 0x27ba, 0x27bc, 0x27be, 0x27c0, 0x27c2, 0x27c4, 0x27c6, + 0x27c8, 0x27ca, 0x27cc, 0x27ce, 0x27d0, 0x27d2, 0x27d4, 0x27d6, + 0x27d8, 0x27da, 0x27dc, 0x27de, 0x27e0, 0x27e2, 0x27e4, 0x27e6, + 0x27e8, 0x27ea, 0x27ec, 0x27ee, 0x27f0, 0x27f2, 0x27f4, 0x27f6, + 0x27f8, 0x27fa, 0x27fc, 0x27fe, 0x2800, 0x2802, 0x2804, 0x2806, + 0x2808, 0x280a, 0x280c, 0x280e, 0x2810, 0x2812, 0x2814, 0x2816, + 0x2818, 0x281a, 0x281c, 0x281e, 0x2820, 0x2822, 0x2824, 0x2826, + 0x2828, 0x282a, 0x282c, 0x282e, 0x2830, 0x2832, 0x2834, 0x2836, + 0x2838, 0x283a, 0x283c, 0x283e, 0x2840, 0x2842, 0x2844, 0xffff, + 0xffff, 0xffff, 0x2846, 0x2848, 0x284a, 0x284c, 0x284e, 0x2850, + 0xffff, 0xffff, 0x2852, 0x2854, 0x2856, 0x2858, 0x285a, 0x285c, + 0xffff, 0xffff, 0x285e, 0x2860, 0x2862, 0x2864, 0x2866, 0x2868, + 0xffff, 0xffff, 0x286a, 0x286c, 0x286e, 0xffff, 0xffff, 0xffff, + 0x2870, 0x2872, 0x2874, 0x2876, 0x2878, 0x287a, 0x287c, 0xffff, + 0x287e, 0x2880, 0x2882, 0x2884, 0x2886, 0x2888, 0x288a, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x288c, 0x2891, + 0x2896, 0x289b, 0x28a0, 0x28a5, 0x28aa, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x28af, 0x28b4, 0x28b9, 0x28be, 0x28c3, + 0x28c8, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x28cd, 0x28cf, 0x28d1, 0x28d3, 0x28d5, 0x28d7, 0x28d9, 0x28db, + 0x28dd, 0x28df, 0x28e1, 0x28e3, 0x28e5, 0x28e7, 0x28e9, 0x28eb, + 0x28ed, 0x28ef, 0x28f1, 0x28f3, 0x28f5, 0x28f7, 0x28f9, 0x28fb, + 0x28fd, 0x28ff, 0x2901, 0x2903, 0x2905, 0x2907, 0x2909, 0x290b, + 0x290d, 0x290f, 0x2911, 0x2913, 0x2915, 0x2917, 0x2919, 0x291b, + 0x291d, 0x291f, 0x2921, 0x2923, 0x2925, 0x2927, 0x2929, 0x292b, + 0x292d, 0x292f, 0x2931, 0x2933, 0x2935, 0x2937, 0x2939, 0x293b, + 0x293d, 0x293f, 0x2941, 0x2943, 0x2945, 0x2947, 0x2949, 0x294b, + 0x294d, 0x294f, 0x2951, 0x2953, 0x2955, 0x2957, 0x2959, 0x295b, + 0x295d, 0x295f, 0x2961, 0x2963, 0x2965, 0x2967, 0x2969, 0x296b, + 0x296d, 0x296f, 0x2971, 0x2973, 0x2975, 0xffff, 0x2977, 0x2979, + 0x297b, 0x297d, 0x297f, 0x2981, 0x2983, 0x2985, 0x2987, 0x2989, + 0x298b, 0x298d, 0x298f, 0x2991, 0x2993, 0x2995, 0x2997, 0x2999, + 0x299b, 0x299d, 0x299f, 0x29a1, 0x29a3, 0x29a5, 0x29a7, 0x29a9, + 0x29ab, 0x29ad, 0x29af, 0x29b1, 0x29b3, 0x29b5, 0x29b7, 0x29b9, + 0x29bb, 0x29bd, 0x29bf, 0x29c1, 0x29c3, 0x29c5, 0x29c7, 0x29c9, + 0x29cb, 0x29cd, 0x29cf, 0x29d1, 0x29d3, 0x29d5, 0x29d7, 0x29d9, + 0x29db, 0x29dd, 0x29df, 0x29e1, 0x29e3, 0x29e5, 0x29e7, 0x29e9, + 0x29eb, 0x29ed, 0x29ef, 0x29f1, 0x29f3, 0x29f5, 0x29f7, 0x29f9, + 0x29fb, 0x29fd, 0x29ff, 0x2a01, 0x2a03, 0xffff, 0x2a05, 0x2a07, + 0xffff, 0xffff, 0x2a09, 0xffff, 0xffff, 0x2a0b, 0x2a0d, 0xffff, + 0xffff, 0x2a0f, 0x2a11, 0x2a13, 0x2a15, 0xffff, 0x2a17, 0x2a19, + 0x2a1b, 0x2a1d, 0x2a1f, 0x2a21, 0x2a23, 0x2a25, 0x2a27, 0x2a29, + 0x2a2b, 0x2a2d, 0xffff, 0x2a2f, 0xffff, 0x2a31, 0x2a33, 0x2a35, + 0x2a37, 0x2a39, 0x2a3b, 0x2a3d, 0xffff, 0x2a3f, 0x2a41, 0x2a43, + 0x2a45, 0x2a47, 0x2a49, 0x2a4b, 0x2a4d, 0x2a4f, 0x2a51, 0x2a53, + 0x2a55, 0x2a57, 0x2a59, 0x2a5b, 0x2a5d, 0x2a5f, 0x2a61, 0x2a63, + 0x2a65, 0x2a67, 0x2a69, 0x2a6b, 0x2a6d, 0x2a6f, 0x2a71, 0x2a73, + 0x2a75, 0x2a77, 0x2a79, 0x2a7b, 0x2a7d, 0x2a7f, 0x2a81, 0x2a83, + 0x2a85, 0x2a87, 0x2a89, 0x2a8b, 0x2a8d, 0x2a8f, 0x2a91, 0x2a93, + 0x2a95, 0x2a97, 0x2a99, 0x2a9b, 0x2a9d, 0x2a9f, 0x2aa1, 0x2aa3, + 0x2aa5, 0x2aa7, 0x2aa9, 0x2aab, 0x2aad, 0x2aaf, 0x2ab1, 0x2ab3, + + 0x2ab5, 0x2ab7, 0x2ab9, 0x2abb, 0x2abd, 0x2abf, 0xffff, 0x2ac1, + 0x2ac3, 0x2ac5, 0x2ac7, 0xffff, 0xffff, 0x2ac9, 0x2acb, 0x2acd, + 0x2acf, 0x2ad1, 0x2ad3, 0x2ad5, 0x2ad7, 0xffff, 0x2ad9, 0x2adb, + 0x2add, 0x2adf, 0x2ae1, 0x2ae3, 0x2ae5, 0xffff, 0x2ae7, 0x2ae9, + 0x2aeb, 0x2aed, 0x2aef, 0x2af1, 0x2af3, 0x2af5, 0x2af7, 0x2af9, + 0x2afb, 0x2afd, 0x2aff, 0x2b01, 0x2b03, 0x2b05, 0x2b07, 0x2b09, + 0x2b0b, 0x2b0d, 0x2b0f, 0x2b11, 0x2b13, 0x2b15, 0x2b17, 0x2b19, + 0x2b1b, 0x2b1d, 0xffff, 0x2b1f, 0x2b21, 0x2b23, 0x2b25, 0xffff, + 0x2b27, 0x2b29, 0x2b2b, 0x2b2d, 0x2b2f, 0xffff, 0x2b31, 0xffff, + 0xffff, 0xffff, 0x2b33, 0x2b35, 0x2b37, 0x2b39, 0x2b3b, 0x2b3d, + 0x2b3f, 0xffff, 0x2b41, 0x2b43, 0x2b45, 0x2b47, 0x2b49, 0x2b4b, + 0x2b4d, 0x2b4f, 0x2b51, 0x2b53, 0x2b55, 0x2b57, 0x2b59, 0x2b5b, + 0x2b5d, 0x2b5f, 0x2b61, 0x2b63, 0x2b65, 0x2b67, 0x2b69, 0x2b6b, + 0x2b6d, 0x2b6f, 0x2b71, 0x2b73, 0x2b75, 0x2b77, 0x2b79, 0x2b7b, + 0x2b7d, 0x2b7f, 0x2b81, 0x2b83, 0x2b85, 0x2b87, 0x2b89, 0x2b8b, + 0x2b8d, 0x2b8f, 0x2b91, 0x2b93, 0x2b95, 0x2b97, 0x2b99, 0x2b9b, + 0x2b9d, 0x2b9f, 0x2ba1, 0x2ba3, 0x2ba5, 0x2ba7, 0x2ba9, 0x2bab, + 0x2bad, 0x2baf, 0x2bb1, 0x2bb3, 0x2bb5, 0x2bb7, 0x2bb9, 0x2bbb, + 0x2bbd, 0x2bbf, 0x2bc1, 0x2bc3, 0x2bc5, 0x2bc7, 0x2bc9, 0x2bcb, + 0x2bcd, 0x2bcf, 0x2bd1, 0x2bd3, 0x2bd5, 0x2bd7, 0x2bd9, 0x2bdb, + 0x2bdd, 0x2bdf, 0x2be1, 0x2be3, 0x2be5, 0x2be7, 0x2be9, 0x2beb, + 0x2bed, 0x2bef, 0x2bf1, 0x2bf3, 0x2bf5, 0x2bf7, 0x2bf9, 0x2bfb, + 0x2bfd, 0x2bff, 0x2c01, 0x2c03, 0x2c05, 0x2c07, 0x2c09, 0x2c0b, + 0x2c0d, 0x2c0f, 0x2c11, 0x2c13, 0x2c15, 0x2c17, 0x2c19, 0x2c1b, + 0x2c1d, 0x2c1f, 0x2c21, 0x2c23, 0x2c25, 0x2c27, 0x2c29, 0x2c2b, + 0x2c2d, 0x2c2f, 0x2c31, 0x2c33, 0x2c35, 0x2c37, 0x2c39, 0x2c3b, + 0x2c3d, 0x2c3f, 0x2c41, 0x2c43, 0x2c45, 0x2c47, 0x2c49, 0x2c4b, + 0x2c4d, 0x2c4f, 0x2c51, 0x2c53, 0x2c55, 0x2c57, 0x2c59, 0x2c5b, + 0x2c5d, 0x2c5f, 0x2c61, 0x2c63, 0x2c65, 0x2c67, 0x2c69, 0x2c6b, + 0x2c6d, 0x2c6f, 0x2c71, 0x2c73, 0x2c75, 0x2c77, 0x2c79, 0x2c7b, + 0x2c7d, 0x2c7f, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, + 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, + + 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, + 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, + 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, + 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, + 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce5, 0x2ce7, 0x2ce9, 0x2ceb, + 0x2ced, 0x2cef, 0x2cf1, 0x2cf3, 0x2cf5, 0x2cf7, 0x2cf9, 0x2cfb, + 0x2cfd, 0x2cff, 0x2d01, 0x2d03, 0x2d05, 0x2d07, 0x2d09, 0x2d0b, + 0x2d0d, 0x2d0f, 0x2d11, 0x2d13, 0x2d15, 0x2d17, 0x2d19, 0x2d1b, + 0x2d1d, 0x2d1f, 0x2d21, 0x2d23, 0x2d25, 0x2d27, 0x2d29, 0x2d2b, + 0x2d2d, 0x2d2f, 0x2d31, 0x2d33, 0x2d35, 0x2d37, 0x2d39, 0x2d3b, + 0x2d3d, 0x2d3f, 0x2d41, 0x2d43, 0x2d45, 0x2d47, 0x2d49, 0x2d4b, + 0x2d4d, 0x2d4f, 0x2d51, 0x2d53, 0x2d55, 0x2d57, 0x2d59, 0x2d5b, + 0x2d5d, 0x2d5f, 0x2d61, 0x2d63, 0x2d65, 0x2d67, 0x2d69, 0x2d6b, + 0x2d6d, 0x2d6f, 0x2d71, 0x2d73, 0x2d75, 0x2d77, 0x2d79, 0x2d7b, + 0x2d7d, 0x2d7f, 0x2d81, 0x2d83, 0x2d85, 0x2d87, 0x2d89, 0x2d8b, + 0x2d8d, 0x2d8f, 0x2d91, 0x2d93, 0x2d95, 0x2d97, 0x2d99, 0x2d9b, + 0x2d9d, 0x2d9f, 0x2da1, 0x2da3, 0x2da5, 0x2da7, 0x2da9, 0x2dab, + 0x2dad, 0x2daf, 0x2db1, 0x2db3, 0x2db5, 0x2db7, 0x2db9, 0x2dbb, + 0x2dbd, 0x2dbf, 0x2dc1, 0x2dc3, 0x2dc5, 0x2dc7, 0x2dc9, 0x2dcb, + 0x2dcd, 0x2dcf, 0x2dd1, 0x2dd3, 0x2dd5, 0x2dd7, 0x2dd9, 0x2ddb, + 0x2ddd, 0x2ddf, 0x2de1, 0x2de3, 0x2de5, 0x2de7, 0xffff, 0xffff, + 0x2de9, 0x2deb, 0x2ded, 0x2def, 0x2df1, 0x2df3, 0x2df5, 0x2df7, + 0x2df9, 0x2dfb, 0x2dfd, 0x2dff, 0x2e01, 0x2e03, 0x2e05, 0x2e07, + 0x2e09, 0x2e0b, 0x2e0d, 0x2e0f, 0x2e11, 0x2e13, 0x2e15, 0x2e17, + 0x2e19, 0x2e1b, 0x2e1d, 0x2e1f, 0x2e21, 0x2e23, 0x2e25, 0x2e27, + 0x2e29, 0x2e2b, 0x2e2d, 0x2e2f, 0x2e31, 0x2e33, 0x2e35, 0x2e37, + 0x2e39, 0x2e3b, 0x2e3d, 0x2e3f, 0x2e41, 0x2e43, 0x2e45, 0x2e47, + 0x2e49, 0x2e4b, 0x2e4d, 0x2e4f, 0x2e51, 0x2e53, 0x2e55, 0x2e57, + 0x2e59, 0x2e5b, 0x2e5d, 0x2e5f, 0x2e61, 0x2e63, 0x2e65, 0x2e67, + 0x2e69, 0x2e6b, 0x2e6d, 0x2e6f, 0x2e71, 0x2e73, 0x2e75, 0x2e77, + 0x2e79, 0x2e7b, 0x2e7d, 0x2e7f, 0x2e81, 0x2e83, 0x2e85, 0x2e87, + 0x2e89, 0x2e8b, 0x2e8d, 0x2e8f, 0x2e91, 0x2e93, 0x2e95, 0x2e97, + + 0x2e99, 0x2e9b, 0x2e9d, 0x2e9f, 0x2ea1, 0x2ea3, 0x2ea5, 0x2ea7, + 0x2ea9, 0x2eab, 0x2ead, 0x2eaf, 0x2eb1, 0x2eb3, 0x2eb5, 0x2eb7, + 0x2eb9, 0x2ebb, 0x2ebd, 0x2ebf, 0x2ec1, 0x2ec3, 0x2ec5, 0x2ec7, + 0x2ec9, 0x2ecb, 0x2ecd, 0x2ecf, 0x2ed1, 0x2ed3, 0x2ed5, 0x2ed7, + 0x2ed9, 0x2edb, 0x2edd, 0x2edf, 0x2ee1, 0x2ee3, 0x2ee5, 0x2ee7, + 0x2ee9, 0x2eeb, 0x2eed, 0x2eef, 0x2ef1, 0x2ef3, 0x2ef5, 0x2ef7, + 0x2ef9, 0x2efb, 0x2efd, 0x2eff, 0x2f01, 0x2f03, 0x2f05, 0x2f07, + 0x2f09, 0x2f0b, 0x2f0d, 0x2f0f, 0x2f11, 0x2f13, 0x2f15, 0x2f17, + 0x2f19, 0x2f1b, 0x2f1d, 0x2f1f, 0x2f21, 0x2f23, 0x2f25, 0x2f27, + 0x2f29, 0x2f2b, 0x2f2d, 0x2f2f, 0x2f31, 0x2f33, 0x2f35, 0x2f37, + 0x2f39, 0x2f3b, 0x2f3d, 0x2f3f, 0x2f41, 0x2f43, 0x2f45, 0x2f47, + 0x2f49, 0x2f4b, 0x2f4d, 0x2f4f, 0x2f51, 0x2f53, 0x2f55, 0x2f57, + 0x2f59, 0x2f5b, 0x2f5d, 0x2f5f, 0x2f61, 0x2f63, 0x2f65, 0x2f67, + 0x2f69, 0x2f6b, 0x2f6d, 0x2f6f, 0x2f71, 0x2f73, 0x2f75, 0x2f77, + 0x2f79, 0x2f7b, 0x2f7d, 0x2f7f, 0x2f81, 0x2f83, 0x2f85, 0x2f87, + 0x2f89, 0x2f8b, 0x2f8d, 0x2f8f, 0x2f91, 0x2f93, 0x2f95, 0x2f97, + 0x2f99, 0x2f9b, 0x2f9d, 0x2f9f, 0x2fa1, 0x2fa3, 0x2fa5, 0x2fa7, + 0x2fa9, 0x2fab, 0x2fad, 0x2faf, 0x2fb1, 0x2fb3, 0x2fb5, 0x2fb7, + 0x2fb9, 0x2fbb, 0x2fbd, 0x2fbf, 0x2fc1, 0x2fc3, 0x2fc5, 0x2fc7, + 0x2fc9, 0x2fcb, 0x2fcd, 0x2fcf, 0x2fd1, 0x2fd3, 0x2fd5, 0x2fd7, + 0x2fd9, 0x2fdb, 0x2fdd, 0x2fdf, 0x2fe1, 0x2fe3, 0x2fe5, 0x2fe7, + 0x2fe9, 0x2feb, 0x2fed, 0x2fef, 0x2ff1, 0x2ff3, 0x2ff5, 0x2ff7, + 0x2ff9, 0x2ffb, 0x2ffd, 0x2fff, 0x3001, 0x3003, 0x3005, 0x3007, + 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3013, 0x3015, 0x3017, + 0x3019, 0x301b, 0x301d, 0x301f, 0x3021, 0x3023, 0x3025, 0x3027, + 0x3029, 0x302b, 0x302d, 0x302f, 0xffff, 0xffff, 0x3031, 0x3033, + 0x3035, 0x3037, 0x3039, 0x303b, 0x303d, 0x303f, 0x3041, 0x3043, + 0x3045, 0x3047, 0x3049, 0x304b, 0x304d, 0x304f, 0x3051, 0x3053, + 0x3055, 0x3057, 0x3059, 0x305b, 0x305d, 0x305f, 0x3061, 0x3063, + 0x3065, 0x3067, 0x3069, 0x306b, 0x306d, 0x306f, 0x3071, 0x3073, + 0x3075, 0x3077, 0x3079, 0x307b, 0x307d, 0x307f, 0x3081, 0x3083, + 0x3085, 0x3087, 0x3089, 0x308b, 0x308d, 0x308f, 0x3091, 0x3093, + + 0x3095, 0x3097, 0x3099, 0x309b, 0x309e, 0x30a0, 0x30a2, 0x30a4, + 0x30a6, 0x30a8, 0x30aa, 0x30ac, 0x30ae, 0x30b0, 0x30b3, 0x30b5, + 0x30b7, 0x30b9, 0x30bb, 0x30be, 0x30c0, 0x30c2, 0x30c4, 0x30c7, + 0x30c9, 0x30cb, 0x30cd, 0x30cf, 0x30d1, 0x30d4, 0x30d6, 0x30d8, + 0x30da, 0x30dc, 0x30de, 0x30e0, 0x30e2, 0x30e4, 0x30e6, 0x30e8, + 0x30ea, 0x30ec, 0x30ee, 0x30f0, 0x30f2, 0x30f4, 0x30f6, 0x30f8, + 0x30fa, 0x30fc, 0x30fe, 0x3100, 0x3102, 0x3105, 0x3107, 0x3109, + 0x310b, 0x310e, 0x3110, 0x3112, 0x3114, 0x3116, 0x3118, 0x311a, + 0x311c, 0x311e, 0x3120, 0x3122, 0x3124, 0x3126, 0x3128, 0x312a, + 0x312c, 0x312e, 0x3130, 0x3132, 0x3134, 0x3136, 0x3138, 0x313a, + 0x313c, 0x313e, 0x3140, 0x3142, 0x3144, 0x3146, 0x3148, 0x314a, + 0x314c, 0x314e, 0x3151, 0x3153, 0x3155, 0x3157, 0x3159, 0x315b, + 0x315d, 0x3160, 0x3163, 0x3165, 0x3167, 0x3169, 0x316b, 0x316d, + 0x316f, 0x3171, 0x3173, 0x3175, 0x3177, 0x317a, 0x317c, 0x317e, + 0x3180, 0x3182, 0x3185, 0x3187, 0x3189, 0x318b, 0x318d, 0x318f, + 0x3191, 0x3193, 0x3195, 0x3197, 0x319a, 0x319c, 0x319f, 0x31a1, + 0x31a3, 0x31a5, 0x31a7, 0x31a9, 0x31ab, 0x31ad, 0x31af, 0x31b1, + 0x31b3, 0x31b5, 0x31b8, 0x31ba, 0x31bc, 0x31be, 0x31c0, 0x31c2, + 0x31c5, 0x31c7, 0x31ca, 0x31cd, 0x31cf, 0x31d1, 0x31d3, 0x31d5, + 0x31d8, 0x31db, 0x31dd, 0x31df, 0x31e1, 0x31e3, 0x31e5, 0x31e7, + 0x31e9, 0x31eb, 0x31ed, 0x31ef, 0x31f1, 0x31f4, 0x31f6, 0x31f8, + 0x31fa, 0x31fc, 0x31fe, 0x3200, 0x3202, 0x3204, 0x3206, 0x3208, + 0x320a, 0x320c, 0x320e, 0x3210, 0x3212, 0x3214, 0x3216, 0x3218, + 0x321a, 0x321d, 0x321f, 0x3221, 0x3223, 0x3225, 0x3227, 0x322a, + 0x322c, 0x322e, 0x3230, 0x3232, 0x3234, 0x3236, 0x3238, 0x323a, + 0x323c, 0x323e, 0x3240, 0x3243, 0x3245, 0x3247, 0x3249, 0x324b, + 0x324d, 0x324f, 0x3251, 0x3253, 0x3255, 0x3257, 0x3259, 0x325b, + 0x325d, 0x325f, 0x3261, 0x3263, 0x3265, 0x3267, 0x326a, 0x326c, + 0x326e, 0x3270, 0x3272, 0x3274, 0x3277, 0x3279, 0x327b, 0x327d, + 0x327f, 0x3281, 0x3283, 0x3285, 0x3287, 0x328a, 0x328c, 0x328e, + 0x3290, 0x3293, 0x3295, 0x3297, 0x3299, 0x329b, 0x329d, 0x329f, + 0x32a2, 0x32a5, 0x32a8, 0x32aa, 0x32ad, 0x32af, 0x32b1, 0x32b3, + + 0x32b5, 0x32b7, 0x32b9, 0x32bb, 0x32bd, 0x32bf, 0x32c1, 0x32c4, + 0x32c6, 0x32c8, 0x32ca, 0x32cc, 0x32ce, 0x32d0, 0x32d3, 0x32d5, + 0x32d7, 0x32da, 0x32dd, 0x32df, 0x32e1, 0x32e3, 0x32e5, 0x32e7, + 0x32e9, 0x32eb, 0x32ed, 0x32ef, 0x32f2, 0x32f4, 0x32f7, 0x32f9, + 0x32fc, 0x32fe, 0x3300, 0x3302, 0x3305, 0x3307, 0x3309, 0x330c, + 0x330f, 0x3311, 0x3313, 0x3315, 0x3317, 0x3319, 0x331b, 0x331d, + 0x331f, 0x3321, 0x3323, 0x3325, 0x3327, 0x3329, 0x332c, 0x332e, + 0x3331, 0x3333, 0x3336, 0x3338, 0x333b, 0x333e, 0x3341, 0x3343, + 0x3345, 0x3347, 0x334a, 0x334d, 0x3350, 0x3353, 0x3355, 0x3357, + 0x3359, 0x335b, 0x335d, 0x335f, 0x3361, 0x3363, 0x3366, 0x3368, + 0x336a, 0x336c, 0x336e, 0x3371, 0x3373, 0x3376, 0x3379, 0x337b, + 0x337d, 0x337f, 0x3381, 0x3383, 0x3385, 0x3388, 0x338b, 0x338e, + 0x3390, 0x3392, 0x3395, 0x3397, 0x3399, 0x339b, 0x339e, 0x33a0, + 0x33a2, 0x33a4, 0x33a6, 0x33a8, 0x33ab, 0x33ad, 0x33af, 0x33b1, + 0x33b3, 0x33b5, 0x33b7, 0x33ba, 0x33bd, 0x33bf, 0x33c2, 0x33c4, + 0x33c7, 0x33c9, 0x33cb, 0x33cd, 0x33d0, 0x33d3, 0x33d5, 0x33d8, + 0x33da, 0x33dd, 0x33df, 0x33e1, 0x33e3, 0x33e5, 0x33e7, 0x33e9, + 0x33ec, 0x33ef, 0x33f2, 0x33f5, 0x33f7, 0x33f9, 0x33fb, 0x33fd, + 0x33ff, 0x3401, 0x3403, 0x3405, 0x3407, 0x3409, 0x340b, 0x340d, + 0x3410, 0x3412, 0x3414, 0x3416, 0x3418, 0x341a, 0x341c, 0x341e, + 0x3420, 0x3422, 0x3424, 0x3426, 0x3428, 0x342b, 0x342e, 0x3431, + 0x3433, 0x3435, 0x3437, 0x3439, 0x343c, 0x343e, 0x3441, 0x3443, + 0x3445, 0x3448, 0x344b, 0x344d, 0x344f, 0x3451, 0x3453, 0x3455, + 0x3457, 0x3459, 0x345b, 0x345d, 0x345f, 0x3461, 0x3463, 0x3465, + 0x3467, 0x3469, 0x346b, 0x346d, 0x346f, 0x3471, 0x3474, 0x3476, + 0x3478, 0x347a, 0x347c, 0x347e, 0x3481, 0x3484, 0x3486, 0x3488, + 0x348a, 0x348c, 0x348e, 0x3490, 0x3493, 0x3495, 0x3497, 0x3499, + 0x349b, 0x349e, 0x34a1, 0x34a3, 0x34a5, 0x34a7, 0x34aa, 0x34ac, + 0x34ae, 0x34b1, 0x34b4, 0x34b6, 0x34b8, 0x34ba, 0x34bd, 0x34bf, + 0x34c1, 0x34c3, 0x34c5, 0x34c7, 0x34c9, 0x34cb, 0x34ce, 0x34d0, + 0x34d2, 0x34d4, 0x34d7, 0x34d9, 0x34db, 0x34dd, 0x34df, 0x34e2, + 0x34e5, 0x34e7, 0x34e9, 0x34eb, 0x34ee, 0x34f0, 0x34f3, 0x34f5, + + 0x34f7, 0x34f9, 0x34fc, 0x34fe, 0x3500, 0x3502, 0x3504, 0x3506, + 0x3508, 0x350a, 0x350d, 0x350f, 0x3511, 0x3513, 0x3515, 0x3517, + 0x3519, 0x351c, 0x351e, 0x3521, 0x3524, 0x3527, 0x3529, 0x352b, + 0x352d, 0x352f, 0x3531, 0x3533, 0x3535, 0x3537, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, }; #define GET_DECOMPOSITION_INDEX(ucs4) \ @@ -5833,2113 +5834,2113 @@ static const unsigned short uc_decomposition_trie[] = { static const unsigned short uc_decomposition_map[] = { - 0x103, 0x20, 0x210, 0x20, 0x308, 0x109, 0x61, 0x210, - 0x20, 0x304, 0x109, 0x32, 0x109, 0x33, 0x210, 0x20, - 0x301, 0x110, 0x3bc, 0x210, 0x20, 0x327, 0x109, 0x31, - 0x109, 0x6f, 0x311, 0x31, 0x2044, 0x34, 0x311, 0x31, - 0x2044, 0x32, 0x311, 0x33, 0x2044, 0x34, 0x201, 0x41, - 0x300, 0x201, 0x41, 0x301, 0x201, 0x41, 0x302, 0x201, - 0x41, 0x303, 0x201, 0x41, 0x308, 0x201, 0x41, 0x30a, - 0x201, 0x43, 0x327, 0x201, 0x45, 0x300, 0x201, 0x45, - 0x301, 0x201, 0x45, 0x302, 0x201, 0x45, 0x308, 0x201, - 0x49, 0x300, 0x201, 0x49, 0x301, 0x201, 0x49, 0x302, - 0x201, 0x49, 0x308, 0x201, 0x4e, 0x303, 0x201, 0x4f, - 0x300, 0x201, 0x4f, 0x301, 0x201, 0x4f, 0x302, 0x201, - 0x4f, 0x303, 0x201, 0x4f, 0x308, 0x201, 0x55, 0x300, - 0x201, 0x55, 0x301, 0x201, 0x55, 0x302, 0x201, 0x55, - 0x308, 0x201, 0x59, 0x301, 0x201, 0x61, 0x300, 0x201, - 0x61, 0x301, 0x201, 0x61, 0x302, 0x201, 0x61, 0x303, - 0x201, 0x61, 0x308, 0x201, 0x61, 0x30a, 0x201, 0x63, - 0x327, 0x201, 0x65, 0x300, 0x201, 0x65, 0x301, 0x201, - 0x65, 0x302, 0x201, 0x65, 0x308, 0x201, 0x69, 0x300, - 0x201, 0x69, 0x301, 0x201, 0x69, 0x302, 0x201, 0x69, - 0x308, 0x201, 0x6e, 0x303, 0x201, 0x6f, 0x300, 0x201, - 0x6f, 0x301, 0x201, 0x6f, 0x302, 0x201, 0x6f, 0x303, - 0x201, 0x6f, 0x308, 0x201, 0x75, 0x300, 0x201, 0x75, - 0x301, 0x201, 0x75, 0x302, 0x201, 0x75, 0x308, 0x201, - 0x79, 0x301, 0x201, 0x79, 0x308, 0x201, 0x41, 0x304, - 0x201, 0x61, 0x304, 0x201, 0x41, 0x306, 0x201, 0x61, - 0x306, 0x201, 0x41, 0x328, 0x201, 0x61, 0x328, 0x201, - 0x43, 0x301, 0x201, 0x63, 0x301, 0x201, 0x43, 0x302, - 0x201, 0x63, 0x302, 0x201, 0x43, 0x307, 0x201, 0x63, - 0x307, 0x201, 0x43, 0x30c, 0x201, 0x63, 0x30c, 0x201, - 0x44, 0x30c, 0x201, 0x64, 0x30c, 0x201, 0x45, 0x304, - 0x201, 0x65, 0x304, 0x201, 0x45, 0x306, 0x201, 0x65, - 0x306, 0x201, 0x45, 0x307, 0x201, 0x65, 0x307, 0x201, - 0x45, 0x328, 0x201, 0x65, 0x328, 0x201, 0x45, 0x30c, - 0x201, 0x65, 0x30c, 0x201, 0x47, 0x302, 0x201, 0x67, - 0x302, 0x201, 0x47, 0x306, 0x201, 0x67, 0x306, 0x201, - 0x47, 0x307, 0x201, 0x67, 0x307, 0x201, 0x47, 0x327, - 0x201, 0x67, 0x327, 0x201, 0x48, 0x302, 0x201, 0x68, - 0x302, 0x201, 0x49, 0x303, 0x201, 0x69, 0x303, 0x201, - 0x49, 0x304, 0x201, 0x69, 0x304, 0x201, 0x49, 0x306, - 0x201, 0x69, 0x306, 0x201, 0x49, 0x328, 0x201, 0x69, - 0x328, 0x201, 0x49, 0x307, 0x210, 0x49, 0x4a, 0x210, - 0x69, 0x6a, 0x201, 0x4a, 0x302, 0x201, 0x6a, 0x302, - 0x201, 0x4b, 0x327, 0x201, 0x6b, 0x327, 0x201, 0x4c, - 0x301, 0x201, 0x6c, 0x301, 0x201, 0x4c, 0x327, 0x201, - 0x6c, 0x327, 0x201, 0x4c, 0x30c, 0x201, 0x6c, 0x30c, - 0x210, 0x4c, 0xb7, 0x210, 0x6c, 0xb7, 0x201, 0x4e, - 0x301, 0x201, 0x6e, 0x301, 0x201, 0x4e, 0x327, 0x201, - 0x6e, 0x327, 0x201, 0x4e, 0x30c, 0x201, 0x6e, 0x30c, - 0x210, 0x2bc, 0x6e, 0x201, 0x4f, 0x304, 0x201, 0x6f, - 0x304, 0x201, 0x4f, 0x306, 0x201, 0x6f, 0x306, 0x201, - 0x4f, 0x30b, 0x201, 0x6f, 0x30b, 0x201, 0x52, 0x301, - 0x201, 0x72, 0x301, 0x201, 0x52, 0x327, 0x201, 0x72, - 0x327, 0x201, 0x52, 0x30c, 0x201, 0x72, 0x30c, 0x201, - 0x53, 0x301, 0x201, 0x73, 0x301, 0x201, 0x53, 0x302, - 0x201, 0x73, 0x302, 0x201, 0x53, 0x327, 0x201, 0x73, - 0x327, 0x201, 0x53, 0x30c, 0x201, 0x73, 0x30c, 0x201, - 0x54, 0x327, 0x201, 0x74, 0x327, 0x201, 0x54, 0x30c, - 0x201, 0x74, 0x30c, 0x201, 0x55, 0x303, 0x201, 0x75, - 0x303, 0x201, 0x55, 0x304, 0x201, 0x75, 0x304, 0x201, - 0x55, 0x306, 0x201, 0x75, 0x306, 0x201, 0x55, 0x30a, - 0x201, 0x75, 0x30a, 0x201, 0x55, 0x30b, 0x201, 0x75, - 0x30b, 0x201, 0x55, 0x328, 0x201, 0x75, 0x328, 0x201, - 0x57, 0x302, 0x201, 0x77, 0x302, 0x201, 0x59, 0x302, - 0x201, 0x79, 0x302, 0x201, 0x59, 0x308, 0x201, 0x5a, - 0x301, 0x201, 0x7a, 0x301, 0x201, 0x5a, 0x307, 0x201, - 0x7a, 0x307, 0x201, 0x5a, 0x30c, 0x201, 0x7a, 0x30c, - 0x110, 0x73, 0x201, 0x4f, 0x31b, 0x201, 0x6f, 0x31b, - 0x201, 0x55, 0x31b, 0x201, 0x75, 0x31b, 0x210, 0x44, - 0x17d, 0x210, 0x44, 0x17e, 0x210, 0x64, 0x17e, 0x210, - 0x4c, 0x4a, 0x210, 0x4c, 0x6a, 0x210, 0x6c, 0x6a, - 0x210, 0x4e, 0x4a, 0x210, 0x4e, 0x6a, 0x210, 0x6e, - 0x6a, 0x201, 0x41, 0x30c, 0x201, 0x61, 0x30c, 0x201, - 0x49, 0x30c, 0x201, 0x69, 0x30c, 0x201, 0x4f, 0x30c, - 0x201, 0x6f, 0x30c, 0x201, 0x55, 0x30c, 0x201, 0x75, - 0x30c, 0x201, 0xdc, 0x304, 0x201, 0xfc, 0x304, 0x201, - 0xdc, 0x301, 0x201, 0xfc, 0x301, 0x201, 0xdc, 0x30c, - 0x201, 0xfc, 0x30c, 0x201, 0xdc, 0x300, 0x201, 0xfc, - 0x300, 0x201, 0xc4, 0x304, 0x201, 0xe4, 0x304, 0x201, - 0x226, 0x304, 0x201, 0x227, 0x304, 0x201, 0xc6, 0x304, - 0x201, 0xe6, 0x304, 0x201, 0x47, 0x30c, 0x201, 0x67, - 0x30c, 0x201, 0x4b, 0x30c, 0x201, 0x6b, 0x30c, 0x201, - 0x4f, 0x328, 0x201, 0x6f, 0x328, 0x201, 0x1ea, 0x304, - 0x201, 0x1eb, 0x304, 0x201, 0x1b7, 0x30c, 0x201, 0x292, - 0x30c, 0x201, 0x6a, 0x30c, 0x210, 0x44, 0x5a, 0x210, - 0x44, 0x7a, 0x210, 0x64, 0x7a, 0x201, 0x47, 0x301, - 0x201, 0x67, 0x301, 0x201, 0x4e, 0x300, 0x201, 0x6e, - 0x300, 0x201, 0xc5, 0x301, 0x201, 0xe5, 0x301, 0x201, - 0xc6, 0x301, 0x201, 0xe6, 0x301, 0x201, 0xd8, 0x301, - 0x201, 0xf8, 0x301, 0x201, 0x41, 0x30f, 0x201, 0x61, - 0x30f, 0x201, 0x41, 0x311, 0x201, 0x61, 0x311, 0x201, - 0x45, 0x30f, 0x201, 0x65, 0x30f, 0x201, 0x45, 0x311, - 0x201, 0x65, 0x311, 0x201, 0x49, 0x30f, 0x201, 0x69, - 0x30f, 0x201, 0x49, 0x311, 0x201, 0x69, 0x311, 0x201, - 0x4f, 0x30f, 0x201, 0x6f, 0x30f, 0x201, 0x4f, 0x311, - 0x201, 0x6f, 0x311, 0x201, 0x52, 0x30f, 0x201, 0x72, - 0x30f, 0x201, 0x52, 0x311, 0x201, 0x72, 0x311, 0x201, - 0x55, 0x30f, 0x201, 0x75, 0x30f, 0x201, 0x55, 0x311, - 0x201, 0x75, 0x311, 0x201, 0x53, 0x326, 0x201, 0x73, - 0x326, 0x201, 0x54, 0x326, 0x201, 0x74, 0x326, 0x201, - 0x48, 0x30c, 0x201, 0x68, 0x30c, 0x201, 0x41, 0x307, - 0x201, 0x61, 0x307, 0x201, 0x45, 0x327, 0x201, 0x65, - 0x327, 0x201, 0xd6, 0x304, 0x201, 0xf6, 0x304, 0x201, - 0xd5, 0x304, 0x201, 0xf5, 0x304, 0x201, 0x4f, 0x307, - 0x201, 0x6f, 0x307, 0x201, 0x22e, 0x304, 0x201, 0x22f, - 0x304, 0x201, 0x59, 0x304, 0x201, 0x79, 0x304, 0x109, - 0x68, 0x109, 0x266, 0x109, 0x6a, 0x109, 0x72, 0x109, - 0x279, 0x109, 0x27b, 0x109, 0x281, 0x109, 0x77, 0x109, - 0x79, 0x210, 0x20, 0x306, 0x210, 0x20, 0x307, 0x210, - 0x20, 0x30a, 0x210, 0x20, 0x328, 0x210, 0x20, 0x303, - 0x210, 0x20, 0x30b, 0x109, 0x263, 0x109, 0x6c, 0x109, - 0x73, 0x109, 0x78, 0x109, 0x295, 0x101, 0x300, 0x101, - 0x301, 0x101, 0x313, 0x201, 0x308, 0x301, 0x101, 0x2b9, - 0x210, 0x20, 0x345, 0x101, 0x3b, 0x210, 0x20, 0x301, - 0x201, 0xa8, 0x301, 0x201, 0x391, 0x301, 0x101, 0xb7, - 0x201, 0x395, 0x301, 0x201, 0x397, 0x301, 0x201, 0x399, - 0x301, 0x201, 0x39f, 0x301, 0x201, 0x3a5, 0x301, 0x201, - 0x3a9, 0x301, 0x201, 0x3ca, 0x301, 0x201, 0x399, 0x308, - 0x201, 0x3a5, 0x308, 0x201, 0x3b1, 0x301, 0x201, 0x3b5, - 0x301, 0x201, 0x3b7, 0x301, 0x201, 0x3b9, 0x301, 0x201, - 0x3cb, 0x301, 0x201, 0x3b9, 0x308, 0x201, 0x3c5, 0x308, - 0x201, 0x3bf, 0x301, 0x201, 0x3c5, 0x301, 0x201, 0x3c9, - 0x301, 0x110, 0x3b2, 0x110, 0x3b8, 0x110, 0x3a5, 0x201, - 0x3d2, 0x301, 0x201, 0x3d2, 0x308, 0x110, 0x3c6, 0x110, - 0x3c0, 0x110, 0x3ba, 0x110, 0x3c1, 0x110, 0x3c2, 0x110, - 0x398, 0x110, 0x3b5, 0x110, 0x3a3, 0x201, 0x415, 0x300, - 0x201, 0x415, 0x308, 0x201, 0x413, 0x301, 0x201, 0x406, - 0x308, 0x201, 0x41a, 0x301, 0x201, 0x418, 0x300, 0x201, - 0x423, 0x306, 0x201, 0x418, 0x306, 0x201, 0x438, 0x306, - 0x201, 0x435, 0x300, 0x201, 0x435, 0x308, 0x201, 0x433, - 0x301, 0x201, 0x456, 0x308, 0x201, 0x43a, 0x301, 0x201, - 0x438, 0x300, 0x201, 0x443, 0x306, 0x201, 0x474, 0x30f, - 0x201, 0x475, 0x30f, 0x201, 0x416, 0x306, 0x201, 0x436, - 0x306, 0x201, 0x410, 0x306, 0x201, 0x430, 0x306, 0x201, - 0x410, 0x308, 0x201, 0x430, 0x308, 0x201, 0x415, 0x306, - 0x201, 0x435, 0x306, 0x201, 0x4d8, 0x308, 0x201, 0x4d9, - 0x308, 0x201, 0x416, 0x308, 0x201, 0x436, 0x308, 0x201, - 0x417, 0x308, 0x201, 0x437, 0x308, 0x201, 0x418, 0x304, - 0x201, 0x438, 0x304, 0x201, 0x418, 0x308, 0x201, 0x438, - 0x308, 0x201, 0x41e, 0x308, 0x201, 0x43e, 0x308, 0x201, - 0x4e8, 0x308, 0x201, 0x4e9, 0x308, 0x201, 0x42d, 0x308, - 0x201, 0x44d, 0x308, 0x201, 0x423, 0x304, 0x201, 0x443, - 0x304, 0x201, 0x423, 0x308, 0x201, 0x443, 0x308, 0x201, - 0x423, 0x30b, 0x201, 0x443, 0x30b, 0x201, 0x427, 0x308, - 0x201, 0x447, 0x308, 0x201, 0x42b, 0x308, 0x201, 0x44b, - 0x308, 0x210, 0x565, 0x582, 0x201, 0x627, 0x653, 0x201, - 0x627, 0x654, 0x201, 0x648, 0x654, 0x201, 0x627, 0x655, - 0x201, 0x64a, 0x654, 0x210, 0x627, 0x674, 0x210, 0x648, - 0x674, 0x210, 0x6c7, 0x674, 0x210, 0x64a, 0x674, 0x201, - 0x6d5, 0x654, 0x201, 0x6c1, 0x654, 0x201, 0x6d2, 0x654, - 0x201, 0x928, 0x93c, 0x201, 0x930, 0x93c, 0x201, 0x933, - 0x93c, 0x201, 0x915, 0x93c, 0x201, 0x916, 0x93c, 0x201, - 0x917, 0x93c, 0x201, 0x91c, 0x93c, 0x201, 0x921, 0x93c, - 0x201, 0x922, 0x93c, 0x201, 0x92b, 0x93c, 0x201, 0x92f, - 0x93c, 0x201, 0x9c7, 0x9be, 0x201, 0x9c7, 0x9d7, 0x201, - 0x9a1, 0x9bc, 0x201, 0x9a2, 0x9bc, 0x201, 0x9af, 0x9bc, - 0x201, 0xa32, 0xa3c, 0x201, 0xa38, 0xa3c, 0x201, 0xa16, - 0xa3c, 0x201, 0xa17, 0xa3c, 0x201, 0xa1c, 0xa3c, 0x201, - 0xa2b, 0xa3c, 0x201, 0xb47, 0xb56, 0x201, 0xb47, 0xb3e, - 0x201, 0xb47, 0xb57, 0x201, 0xb21, 0xb3c, 0x201, 0xb22, - 0xb3c, 0x201, 0xb92, 0xbd7, 0x201, 0xbc6, 0xbbe, 0x201, - 0xbc7, 0xbbe, 0x201, 0xbc6, 0xbd7, 0x201, 0xc46, 0xc56, - 0x201, 0xcbf, 0xcd5, 0x201, 0xcc6, 0xcd5, 0x201, 0xcc6, - 0xcd6, 0x201, 0xcc6, 0xcc2, 0x201, 0xcca, 0xcd5, 0x201, - 0xd46, 0xd3e, 0x201, 0xd47, 0xd3e, 0x201, 0xd46, 0xd57, - 0x201, 0xdd9, 0xdca, 0x201, 0xdd9, 0xdcf, 0x201, 0xddc, - 0xdca, 0x201, 0xdd9, 0xddf, 0x210, 0xe4d, 0xe32, 0x210, - 0xecd, 0xeb2, 0x210, 0xeab, 0xe99, 0x210, 0xeab, 0xea1, - 0x103, 0xf0b, 0x201, 0xf42, 0xfb7, 0x201, 0xf4c, 0xfb7, - 0x201, 0xf51, 0xfb7, 0x201, 0xf56, 0xfb7, 0x201, 0xf5b, - 0xfb7, 0x201, 0xf40, 0xfb5, 0x201, 0xf71, 0xf72, 0x201, - 0xf71, 0xf74, 0x201, 0xfb2, 0xf80, 0x210, 0xfb2, 0xf81, - 0x201, 0xfb3, 0xf80, 0x210, 0xfb3, 0xf81, 0x201, 0xf71, - 0xf80, 0x201, 0xf92, 0xfb7, 0x201, 0xf9c, 0xfb7, 0x201, - 0xfa1, 0xfb7, 0x201, 0xfa6, 0xfb7, 0x201, 0xfab, 0xfb7, - 0x201, 0xf90, 0xfb5, 0x201, 0x1025, 0x102e, 0x109, 0x10dc, - 0x201, 0x1b05, 0x1b35, 0x201, 0x1b07, 0x1b35, 0x201, 0x1b09, - 0x1b35, 0x201, 0x1b0b, 0x1b35, 0x201, 0x1b0d, 0x1b35, 0x201, - 0x1b11, 0x1b35, 0x201, 0x1b3a, 0x1b35, 0x201, 0x1b3c, 0x1b35, - 0x201, 0x1b3e, 0x1b35, 0x201, 0x1b3f, 0x1b35, 0x201, 0x1b42, - 0x1b35, 0x109, 0x41, 0x109, 0xc6, 0x109, 0x42, 0x109, - 0x44, 0x109, 0x45, 0x109, 0x18e, 0x109, 0x47, 0x109, - 0x48, 0x109, 0x49, 0x109, 0x4a, 0x109, 0x4b, 0x109, - 0x4c, 0x109, 0x4d, 0x109, 0x4e, 0x109, 0x4f, 0x109, - 0x222, 0x109, 0x50, 0x109, 0x52, 0x109, 0x54, 0x109, - 0x55, 0x109, 0x57, 0x109, 0x61, 0x109, 0x250, 0x109, - 0x251, 0x109, 0x1d02, 0x109, 0x62, 0x109, 0x64, 0x109, - 0x65, 0x109, 0x259, 0x109, 0x25b, 0x109, 0x25c, 0x109, - 0x67, 0x109, 0x6b, 0x109, 0x6d, 0x109, 0x14b, 0x109, - 0x6f, 0x109, 0x254, 0x109, 0x1d16, 0x109, 0x1d17, 0x109, - 0x70, 0x109, 0x74, 0x109, 0x75, 0x109, 0x1d1d, 0x109, - 0x26f, 0x109, 0x76, 0x109, 0x1d25, 0x109, 0x3b2, 0x109, - 0x3b3, 0x109, 0x3b4, 0x109, 0x3c6, 0x109, 0x3c7, 0x10a, - 0x69, 0x10a, 0x72, 0x10a, 0x75, 0x10a, 0x76, 0x10a, - 0x3b2, 0x10a, 0x3b3, 0x10a, 0x3c1, 0x10a, 0x3c6, 0x10a, - 0x3c7, 0x109, 0x43d, 0x109, 0x252, 0x109, 0x63, 0x109, - 0x255, 0x109, 0xf0, 0x109, 0x25c, 0x109, 0x66, 0x109, - 0x25f, 0x109, 0x261, 0x109, 0x265, 0x109, 0x268, 0x109, - 0x269, 0x109, 0x26a, 0x109, 0x1d7b, 0x109, 0x29d, 0x109, - 0x26d, 0x109, 0x1d85, 0x109, 0x29f, 0x109, 0x271, 0x109, - 0x270, 0x109, 0x272, 0x109, 0x273, 0x109, 0x274, 0x109, - 0x275, 0x109, 0x278, 0x109, 0x282, 0x109, 0x283, 0x109, - 0x1ab, 0x109, 0x289, 0x109, 0x28a, 0x109, 0x1d1c, 0x109, - 0x28b, 0x109, 0x28c, 0x109, 0x7a, 0x109, 0x290, 0x109, - 0x291, 0x109, 0x292, 0x109, 0x3b8, 0x201, 0x41, 0x325, - 0x201, 0x61, 0x325, 0x201, 0x42, 0x307, 0x201, 0x62, - 0x307, 0x201, 0x42, 0x323, 0x201, 0x62, 0x323, 0x201, - 0x42, 0x331, 0x201, 0x62, 0x331, 0x201, 0xc7, 0x301, - 0x201, 0xe7, 0x301, 0x201, 0x44, 0x307, 0x201, 0x64, - 0x307, 0x201, 0x44, 0x323, 0x201, 0x64, 0x323, 0x201, - 0x44, 0x331, 0x201, 0x64, 0x331, 0x201, 0x44, 0x327, - 0x201, 0x64, 0x327, 0x201, 0x44, 0x32d, 0x201, 0x64, - 0x32d, 0x201, 0x112, 0x300, 0x201, 0x113, 0x300, 0x201, - 0x112, 0x301, 0x201, 0x113, 0x301, 0x201, 0x45, 0x32d, - 0x201, 0x65, 0x32d, 0x201, 0x45, 0x330, 0x201, 0x65, - 0x330, 0x201, 0x228, 0x306, 0x201, 0x229, 0x306, 0x201, - 0x46, 0x307, 0x201, 0x66, 0x307, 0x201, 0x47, 0x304, - 0x201, 0x67, 0x304, 0x201, 0x48, 0x307, 0x201, 0x68, - 0x307, 0x201, 0x48, 0x323, 0x201, 0x68, 0x323, 0x201, - 0x48, 0x308, 0x201, 0x68, 0x308, 0x201, 0x48, 0x327, - 0x201, 0x68, 0x327, 0x201, 0x48, 0x32e, 0x201, 0x68, - 0x32e, 0x201, 0x49, 0x330, 0x201, 0x69, 0x330, 0x201, - 0xcf, 0x301, 0x201, 0xef, 0x301, 0x201, 0x4b, 0x301, - 0x201, 0x6b, 0x301, 0x201, 0x4b, 0x323, 0x201, 0x6b, - 0x323, 0x201, 0x4b, 0x331, 0x201, 0x6b, 0x331, 0x201, - 0x4c, 0x323, 0x201, 0x6c, 0x323, 0x201, 0x1e36, 0x304, - 0x201, 0x1e37, 0x304, 0x201, 0x4c, 0x331, 0x201, 0x6c, - 0x331, 0x201, 0x4c, 0x32d, 0x201, 0x6c, 0x32d, 0x201, - 0x4d, 0x301, 0x201, 0x6d, 0x301, 0x201, 0x4d, 0x307, - 0x201, 0x6d, 0x307, 0x201, 0x4d, 0x323, 0x201, 0x6d, - 0x323, 0x201, 0x4e, 0x307, 0x201, 0x6e, 0x307, 0x201, - 0x4e, 0x323, 0x201, 0x6e, 0x323, 0x201, 0x4e, 0x331, - 0x201, 0x6e, 0x331, 0x201, 0x4e, 0x32d, 0x201, 0x6e, - 0x32d, 0x201, 0xd5, 0x301, 0x201, 0xf5, 0x301, 0x201, - 0xd5, 0x308, 0x201, 0xf5, 0x308, 0x201, 0x14c, 0x300, - 0x201, 0x14d, 0x300, 0x201, 0x14c, 0x301, 0x201, 0x14d, - 0x301, 0x201, 0x50, 0x301, 0x201, 0x70, 0x301, 0x201, - 0x50, 0x307, 0x201, 0x70, 0x307, 0x201, 0x52, 0x307, - 0x201, 0x72, 0x307, 0x201, 0x52, 0x323, 0x201, 0x72, - 0x323, 0x201, 0x1e5a, 0x304, 0x201, 0x1e5b, 0x304, 0x201, - 0x52, 0x331, 0x201, 0x72, 0x331, 0x201, 0x53, 0x307, - 0x201, 0x73, 0x307, 0x201, 0x53, 0x323, 0x201, 0x73, - 0x323, 0x201, 0x15a, 0x307, 0x201, 0x15b, 0x307, 0x201, - 0x160, 0x307, 0x201, 0x161, 0x307, 0x201, 0x1e62, 0x307, - 0x201, 0x1e63, 0x307, 0x201, 0x54, 0x307, 0x201, 0x74, - 0x307, 0x201, 0x54, 0x323, 0x201, 0x74, 0x323, 0x201, - 0x54, 0x331, 0x201, 0x74, 0x331, 0x201, 0x54, 0x32d, - 0x201, 0x74, 0x32d, 0x201, 0x55, 0x324, 0x201, 0x75, - 0x324, 0x201, 0x55, 0x330, 0x201, 0x75, 0x330, 0x201, - 0x55, 0x32d, 0x201, 0x75, 0x32d, 0x201, 0x168, 0x301, - 0x201, 0x169, 0x301, 0x201, 0x16a, 0x308, 0x201, 0x16b, - 0x308, 0x201, 0x56, 0x303, 0x201, 0x76, 0x303, 0x201, - 0x56, 0x323, 0x201, 0x76, 0x323, 0x201, 0x57, 0x300, - 0x201, 0x77, 0x300, 0x201, 0x57, 0x301, 0x201, 0x77, - 0x301, 0x201, 0x57, 0x308, 0x201, 0x77, 0x308, 0x201, - 0x57, 0x307, 0x201, 0x77, 0x307, 0x201, 0x57, 0x323, - 0x201, 0x77, 0x323, 0x201, 0x58, 0x307, 0x201, 0x78, - 0x307, 0x201, 0x58, 0x308, 0x201, 0x78, 0x308, 0x201, - 0x59, 0x307, 0x201, 0x79, 0x307, 0x201, 0x5a, 0x302, - 0x201, 0x7a, 0x302, 0x201, 0x5a, 0x323, 0x201, 0x7a, - 0x323, 0x201, 0x5a, 0x331, 0x201, 0x7a, 0x331, 0x201, - 0x68, 0x331, 0x201, 0x74, 0x308, 0x201, 0x77, 0x30a, - 0x201, 0x79, 0x30a, 0x210, 0x61, 0x2be, 0x201, 0x17f, - 0x307, 0x201, 0x41, 0x323, 0x201, 0x61, 0x323, 0x201, - 0x41, 0x309, 0x201, 0x61, 0x309, 0x201, 0xc2, 0x301, - 0x201, 0xe2, 0x301, 0x201, 0xc2, 0x300, 0x201, 0xe2, - 0x300, 0x201, 0xc2, 0x309, 0x201, 0xe2, 0x309, 0x201, - 0xc2, 0x303, 0x201, 0xe2, 0x303, 0x201, 0x1ea0, 0x302, - 0x201, 0x1ea1, 0x302, 0x201, 0x102, 0x301, 0x201, 0x103, - 0x301, 0x201, 0x102, 0x300, 0x201, 0x103, 0x300, 0x201, - 0x102, 0x309, 0x201, 0x103, 0x309, 0x201, 0x102, 0x303, - 0x201, 0x103, 0x303, 0x201, 0x1ea0, 0x306, 0x201, 0x1ea1, - 0x306, 0x201, 0x45, 0x323, 0x201, 0x65, 0x323, 0x201, - 0x45, 0x309, 0x201, 0x65, 0x309, 0x201, 0x45, 0x303, - 0x201, 0x65, 0x303, 0x201, 0xca, 0x301, 0x201, 0xea, - 0x301, 0x201, 0xca, 0x300, 0x201, 0xea, 0x300, 0x201, - 0xca, 0x309, 0x201, 0xea, 0x309, 0x201, 0xca, 0x303, - 0x201, 0xea, 0x303, 0x201, 0x1eb8, 0x302, 0x201, 0x1eb9, - 0x302, 0x201, 0x49, 0x309, 0x201, 0x69, 0x309, 0x201, - 0x49, 0x323, 0x201, 0x69, 0x323, 0x201, 0x4f, 0x323, - 0x201, 0x6f, 0x323, 0x201, 0x4f, 0x309, 0x201, 0x6f, - 0x309, 0x201, 0xd4, 0x301, 0x201, 0xf4, 0x301, 0x201, - 0xd4, 0x300, 0x201, 0xf4, 0x300, 0x201, 0xd4, 0x309, - 0x201, 0xf4, 0x309, 0x201, 0xd4, 0x303, 0x201, 0xf4, - 0x303, 0x201, 0x1ecc, 0x302, 0x201, 0x1ecd, 0x302, 0x201, - 0x1a0, 0x301, 0x201, 0x1a1, 0x301, 0x201, 0x1a0, 0x300, - 0x201, 0x1a1, 0x300, 0x201, 0x1a0, 0x309, 0x201, 0x1a1, - 0x309, 0x201, 0x1a0, 0x303, 0x201, 0x1a1, 0x303, 0x201, - 0x1a0, 0x323, 0x201, 0x1a1, 0x323, 0x201, 0x55, 0x323, - 0x201, 0x75, 0x323, 0x201, 0x55, 0x309, 0x201, 0x75, - 0x309, 0x201, 0x1af, 0x301, 0x201, 0x1b0, 0x301, 0x201, - 0x1af, 0x300, 0x201, 0x1b0, 0x300, 0x201, 0x1af, 0x309, - 0x201, 0x1b0, 0x309, 0x201, 0x1af, 0x303, 0x201, 0x1b0, - 0x303, 0x201, 0x1af, 0x323, 0x201, 0x1b0, 0x323, 0x201, - 0x59, 0x300, 0x201, 0x79, 0x300, 0x201, 0x59, 0x323, - 0x201, 0x79, 0x323, 0x201, 0x59, 0x309, 0x201, 0x79, - 0x309, 0x201, 0x59, 0x303, 0x201, 0x79, 0x303, 0x201, - 0x3b1, 0x313, 0x201, 0x3b1, 0x314, 0x201, 0x1f00, 0x300, - 0x201, 0x1f01, 0x300, 0x201, 0x1f00, 0x301, 0x201, 0x1f01, - 0x301, 0x201, 0x1f00, 0x342, 0x201, 0x1f01, 0x342, 0x201, - 0x391, 0x313, 0x201, 0x391, 0x314, 0x201, 0x1f08, 0x300, - 0x201, 0x1f09, 0x300, 0x201, 0x1f08, 0x301, 0x201, 0x1f09, - 0x301, 0x201, 0x1f08, 0x342, 0x201, 0x1f09, 0x342, 0x201, - 0x3b5, 0x313, 0x201, 0x3b5, 0x314, 0x201, 0x1f10, 0x300, - 0x201, 0x1f11, 0x300, 0x201, 0x1f10, 0x301, 0x201, 0x1f11, - 0x301, 0x201, 0x395, 0x313, 0x201, 0x395, 0x314, 0x201, - 0x1f18, 0x300, 0x201, 0x1f19, 0x300, 0x201, 0x1f18, 0x301, - 0x201, 0x1f19, 0x301, 0x201, 0x3b7, 0x313, 0x201, 0x3b7, - 0x314, 0x201, 0x1f20, 0x300, 0x201, 0x1f21, 0x300, 0x201, - 0x1f20, 0x301, 0x201, 0x1f21, 0x301, 0x201, 0x1f20, 0x342, - 0x201, 0x1f21, 0x342, 0x201, 0x397, 0x313, 0x201, 0x397, - 0x314, 0x201, 0x1f28, 0x300, 0x201, 0x1f29, 0x300, 0x201, - 0x1f28, 0x301, 0x201, 0x1f29, 0x301, 0x201, 0x1f28, 0x342, - 0x201, 0x1f29, 0x342, 0x201, 0x3b9, 0x313, 0x201, 0x3b9, - 0x314, 0x201, 0x1f30, 0x300, 0x201, 0x1f31, 0x300, 0x201, - 0x1f30, 0x301, 0x201, 0x1f31, 0x301, 0x201, 0x1f30, 0x342, - 0x201, 0x1f31, 0x342, 0x201, 0x399, 0x313, 0x201, 0x399, - 0x314, 0x201, 0x1f38, 0x300, 0x201, 0x1f39, 0x300, 0x201, - 0x1f38, 0x301, 0x201, 0x1f39, 0x301, 0x201, 0x1f38, 0x342, - 0x201, 0x1f39, 0x342, 0x201, 0x3bf, 0x313, 0x201, 0x3bf, - 0x314, 0x201, 0x1f40, 0x300, 0x201, 0x1f41, 0x300, 0x201, - 0x1f40, 0x301, 0x201, 0x1f41, 0x301, 0x201, 0x39f, 0x313, - 0x201, 0x39f, 0x314, 0x201, 0x1f48, 0x300, 0x201, 0x1f49, - 0x300, 0x201, 0x1f48, 0x301, 0x201, 0x1f49, 0x301, 0x201, - 0x3c5, 0x313, 0x201, 0x3c5, 0x314, 0x201, 0x1f50, 0x300, - 0x201, 0x1f51, 0x300, 0x201, 0x1f50, 0x301, 0x201, 0x1f51, - 0x301, 0x201, 0x1f50, 0x342, 0x201, 0x1f51, 0x342, 0x201, - 0x3a5, 0x314, 0x201, 0x1f59, 0x300, 0x201, 0x1f59, 0x301, - 0x201, 0x1f59, 0x342, 0x201, 0x3c9, 0x313, 0x201, 0x3c9, - 0x314, 0x201, 0x1f60, 0x300, 0x201, 0x1f61, 0x300, 0x201, - 0x1f60, 0x301, 0x201, 0x1f61, 0x301, 0x201, 0x1f60, 0x342, - 0x201, 0x1f61, 0x342, 0x201, 0x3a9, 0x313, 0x201, 0x3a9, - 0x314, 0x201, 0x1f68, 0x300, 0x201, 0x1f69, 0x300, 0x201, - 0x1f68, 0x301, 0x201, 0x1f69, 0x301, 0x201, 0x1f68, 0x342, - 0x201, 0x1f69, 0x342, 0x201, 0x3b1, 0x300, 0x101, 0x3ac, - 0x201, 0x3b5, 0x300, 0x101, 0x3ad, 0x201, 0x3b7, 0x300, - 0x101, 0x3ae, 0x201, 0x3b9, 0x300, 0x101, 0x3af, 0x201, - 0x3bf, 0x300, 0x101, 0x3cc, 0x201, 0x3c5, 0x300, 0x101, - 0x3cd, 0x201, 0x3c9, 0x300, 0x101, 0x3ce, 0x201, 0x1f00, - 0x345, 0x201, 0x1f01, 0x345, 0x201, 0x1f02, 0x345, 0x201, - 0x1f03, 0x345, 0x201, 0x1f04, 0x345, 0x201, 0x1f05, 0x345, - 0x201, 0x1f06, 0x345, 0x201, 0x1f07, 0x345, 0x201, 0x1f08, - 0x345, 0x201, 0x1f09, 0x345, 0x201, 0x1f0a, 0x345, 0x201, - 0x1f0b, 0x345, 0x201, 0x1f0c, 0x345, 0x201, 0x1f0d, 0x345, - 0x201, 0x1f0e, 0x345, 0x201, 0x1f0f, 0x345, 0x201, 0x1f20, - 0x345, 0x201, 0x1f21, 0x345, 0x201, 0x1f22, 0x345, 0x201, - 0x1f23, 0x345, 0x201, 0x1f24, 0x345, 0x201, 0x1f25, 0x345, - 0x201, 0x1f26, 0x345, 0x201, 0x1f27, 0x345, 0x201, 0x1f28, - 0x345, 0x201, 0x1f29, 0x345, 0x201, 0x1f2a, 0x345, 0x201, - 0x1f2b, 0x345, 0x201, 0x1f2c, 0x345, 0x201, 0x1f2d, 0x345, - 0x201, 0x1f2e, 0x345, 0x201, 0x1f2f, 0x345, 0x201, 0x1f60, - 0x345, 0x201, 0x1f61, 0x345, 0x201, 0x1f62, 0x345, 0x201, - 0x1f63, 0x345, 0x201, 0x1f64, 0x345, 0x201, 0x1f65, 0x345, - 0x201, 0x1f66, 0x345, 0x201, 0x1f67, 0x345, 0x201, 0x1f68, - 0x345, 0x201, 0x1f69, 0x345, 0x201, 0x1f6a, 0x345, 0x201, - 0x1f6b, 0x345, 0x201, 0x1f6c, 0x345, 0x201, 0x1f6d, 0x345, - 0x201, 0x1f6e, 0x345, 0x201, 0x1f6f, 0x345, 0x201, 0x3b1, - 0x306, 0x201, 0x3b1, 0x304, 0x201, 0x1f70, 0x345, 0x201, - 0x3b1, 0x345, 0x201, 0x3ac, 0x345, 0x201, 0x3b1, 0x342, - 0x201, 0x1fb6, 0x345, 0x201, 0x391, 0x306, 0x201, 0x391, - 0x304, 0x201, 0x391, 0x300, 0x101, 0x386, 0x201, 0x391, - 0x345, 0x210, 0x20, 0x313, 0x101, 0x3b9, 0x210, 0x20, - 0x313, 0x210, 0x20, 0x342, 0x201, 0xa8, 0x342, 0x201, - 0x1f74, 0x345, 0x201, 0x3b7, 0x345, 0x201, 0x3ae, 0x345, - 0x201, 0x3b7, 0x342, 0x201, 0x1fc6, 0x345, 0x201, 0x395, - 0x300, 0x101, 0x388, 0x201, 0x397, 0x300, 0x101, 0x389, - 0x201, 0x397, 0x345, 0x201, 0x1fbf, 0x300, 0x201, 0x1fbf, - 0x301, 0x201, 0x1fbf, 0x342, 0x201, 0x3b9, 0x306, 0x201, - 0x3b9, 0x304, 0x201, 0x3ca, 0x300, 0x101, 0x390, 0x201, - 0x3b9, 0x342, 0x201, 0x3ca, 0x342, 0x201, 0x399, 0x306, - 0x201, 0x399, 0x304, 0x201, 0x399, 0x300, 0x101, 0x38a, - 0x201, 0x1ffe, 0x300, 0x201, 0x1ffe, 0x301, 0x201, 0x1ffe, - 0x342, 0x201, 0x3c5, 0x306, 0x201, 0x3c5, 0x304, 0x201, - 0x3cb, 0x300, 0x101, 0x3b0, 0x201, 0x3c1, 0x313, 0x201, - 0x3c1, 0x314, 0x201, 0x3c5, 0x342, 0x201, 0x3cb, 0x342, - 0x201, 0x3a5, 0x306, 0x201, 0x3a5, 0x304, 0x201, 0x3a5, - 0x300, 0x101, 0x38e, 0x201, 0x3a1, 0x314, 0x201, 0xa8, - 0x300, 0x101, 0x385, 0x101, 0x60, 0x201, 0x1f7c, 0x345, - 0x201, 0x3c9, 0x345, 0x201, 0x3ce, 0x345, 0x201, 0x3c9, - 0x342, 0x201, 0x1ff6, 0x345, 0x201, 0x39f, 0x300, 0x101, - 0x38c, 0x201, 0x3a9, 0x300, 0x101, 0x38f, 0x201, 0x3a9, - 0x345, 0x101, 0xb4, 0x210, 0x20, 0x314, 0x101, 0x2002, - 0x101, 0x2003, 0x110, 0x20, 0x110, 0x20, 0x110, 0x20, - 0x110, 0x20, 0x110, 0x20, 0x103, 0x20, 0x110, 0x20, - 0x110, 0x20, 0x110, 0x20, 0x103, 0x2010, 0x210, 0x20, - 0x333, 0x110, 0x2e, 0x210, 0x2e, 0x2e, 0x310, 0x2e, - 0x2e, 0x2e, 0x103, 0x20, 0x210, 0x2032, 0x2032, 0x310, - 0x2032, 0x2032, 0x2032, 0x210, 0x2035, 0x2035, 0x310, 0x2035, - 0x2035, 0x2035, 0x210, 0x21, 0x21, 0x210, 0x20, 0x305, - 0x210, 0x3f, 0x3f, 0x210, 0x3f, 0x21, 0x210, 0x21, - 0x3f, 0x410, 0x2032, 0x2032, 0x2032, 0x2032, 0x110, 0x20, - 0x109, 0x30, 0x109, 0x69, 0x109, 0x34, 0x109, 0x35, - 0x109, 0x36, 0x109, 0x37, 0x109, 0x38, 0x109, 0x39, - 0x109, 0x2b, 0x109, 0x2212, 0x109, 0x3d, 0x109, 0x28, - 0x109, 0x29, 0x109, 0x6e, 0x10a, 0x30, 0x10a, 0x31, - 0x10a, 0x32, 0x10a, 0x33, 0x10a, 0x34, 0x10a, 0x35, - 0x10a, 0x36, 0x10a, 0x37, 0x10a, 0x38, 0x10a, 0x39, - 0x10a, 0x2b, 0x10a, 0x2212, 0x10a, 0x3d, 0x10a, 0x28, - 0x10a, 0x29, 0x10a, 0x61, 0x10a, 0x65, 0x10a, 0x6f, - 0x10a, 0x78, 0x10a, 0x259, 0x210, 0x52, 0x73, 0x310, - 0x61, 0x2f, 0x63, 0x310, 0x61, 0x2f, 0x73, 0x102, - 0x43, 0x210, 0xb0, 0x43, 0x310, 0x63, 0x2f, 0x6f, - 0x310, 0x63, 0x2f, 0x75, 0x110, 0x190, 0x210, 0xb0, - 0x46, 0x102, 0x67, 0x102, 0x48, 0x102, 0x48, 0x102, - 0x48, 0x102, 0x68, 0x102, 0x127, 0x102, 0x49, 0x102, - 0x49, 0x102, 0x4c, 0x102, 0x6c, 0x102, 0x4e, 0x210, - 0x4e, 0x6f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, - 0x102, 0x52, 0x102, 0x52, 0x209, 0x53, 0x4d, 0x310, - 0x54, 0x45, 0x4c, 0x209, 0x54, 0x4d, 0x102, 0x5a, - 0x101, 0x3a9, 0x102, 0x5a, 0x101, 0x4b, 0x101, 0xc5, - 0x102, 0x42, 0x102, 0x43, 0x102, 0x65, 0x102, 0x45, - 0x102, 0x46, 0x102, 0x4d, 0x102, 0x6f, 0x110, 0x5d0, - 0x110, 0x5d1, 0x110, 0x5d2, 0x110, 0x5d3, 0x102, 0x69, - 0x310, 0x46, 0x41, 0x58, 0x102, 0x3c0, 0x102, 0x3b3, - 0x102, 0x393, 0x102, 0x3a0, 0x102, 0x2211, 0x102, 0x44, - 0x102, 0x64, 0x102, 0x65, 0x102, 0x69, 0x102, 0x6a, - 0x311, 0x31, 0x2044, 0x33, 0x311, 0x32, 0x2044, 0x33, - 0x311, 0x31, 0x2044, 0x35, 0x311, 0x32, 0x2044, 0x35, - 0x311, 0x33, 0x2044, 0x35, 0x311, 0x34, 0x2044, 0x35, - 0x311, 0x31, 0x2044, 0x36, 0x311, 0x35, 0x2044, 0x36, - 0x311, 0x31, 0x2044, 0x38, 0x311, 0x33, 0x2044, 0x38, - 0x311, 0x35, 0x2044, 0x38, 0x311, 0x37, 0x2044, 0x38, - 0x211, 0x31, 0x2044, 0x110, 0x49, 0x210, 0x49, 0x49, - 0x310, 0x49, 0x49, 0x49, 0x210, 0x49, 0x56, 0x110, - 0x56, 0x210, 0x56, 0x49, 0x310, 0x56, 0x49, 0x49, - 0x410, 0x56, 0x49, 0x49, 0x49, 0x210, 0x49, 0x58, - 0x110, 0x58, 0x210, 0x58, 0x49, 0x310, 0x58, 0x49, - 0x49, 0x110, 0x4c, 0x110, 0x43, 0x110, 0x44, 0x110, - 0x4d, 0x110, 0x69, 0x210, 0x69, 0x69, 0x310, 0x69, - 0x69, 0x69, 0x210, 0x69, 0x76, 0x110, 0x76, 0x210, - 0x76, 0x69, 0x310, 0x76, 0x69, 0x69, 0x410, 0x76, - 0x69, 0x69, 0x69, 0x210, 0x69, 0x78, 0x110, 0x78, - 0x210, 0x78, 0x69, 0x310, 0x78, 0x69, 0x69, 0x110, - 0x6c, 0x110, 0x63, 0x110, 0x64, 0x110, 0x6d, 0x201, - 0x2190, 0x338, 0x201, 0x2192, 0x338, 0x201, 0x2194, 0x338, - 0x201, 0x21d0, 0x338, 0x201, 0x21d4, 0x338, 0x201, 0x21d2, - 0x338, 0x201, 0x2203, 0x338, 0x201, 0x2208, 0x338, 0x201, - 0x220b, 0x338, 0x201, 0x2223, 0x338, 0x201, 0x2225, 0x338, - 0x210, 0x222b, 0x222b, 0x310, 0x222b, 0x222b, 0x222b, 0x210, - 0x222e, 0x222e, 0x310, 0x222e, 0x222e, 0x222e, 0x201, 0x223c, - 0x338, 0x201, 0x2243, 0x338, 0x201, 0x2245, 0x338, 0x201, - 0x2248, 0x338, 0x201, 0x3d, 0x338, 0x201, 0x2261, 0x338, - 0x201, 0x224d, 0x338, 0x201, 0x3c, 0x338, 0x201, 0x3e, - 0x338, 0x201, 0x2264, 0x338, 0x201, 0x2265, 0x338, 0x201, - 0x2272, 0x338, 0x201, 0x2273, 0x338, 0x201, 0x2276, 0x338, - 0x201, 0x2277, 0x338, 0x201, 0x227a, 0x338, 0x201, 0x227b, - 0x338, 0x201, 0x2282, 0x338, 0x201, 0x2283, 0x338, 0x201, - 0x2286, 0x338, 0x201, 0x2287, 0x338, 0x201, 0x22a2, 0x338, - 0x201, 0x22a8, 0x338, 0x201, 0x22a9, 0x338, 0x201, 0x22ab, - 0x338, 0x201, 0x227c, 0x338, 0x201, 0x227d, 0x338, 0x201, - 0x2291, 0x338, 0x201, 0x2292, 0x338, 0x201, 0x22b2, 0x338, - 0x201, 0x22b3, 0x338, 0x201, 0x22b4, 0x338, 0x201, 0x22b5, - 0x338, 0x101, 0x3008, 0x101, 0x3009, 0x108, 0x31, 0x108, - 0x32, 0x108, 0x33, 0x108, 0x34, 0x108, 0x35, 0x108, - 0x36, 0x108, 0x37, 0x108, 0x38, 0x108, 0x39, 0x208, - 0x31, 0x30, 0x208, 0x31, 0x31, 0x208, 0x31, 0x32, - 0x208, 0x31, 0x33, 0x208, 0x31, 0x34, 0x208, 0x31, - 0x35, 0x208, 0x31, 0x36, 0x208, 0x31, 0x37, 0x208, - 0x31, 0x38, 0x208, 0x31, 0x39, 0x208, 0x32, 0x30, - 0x310, 0x28, 0x31, 0x29, 0x310, 0x28, 0x32, 0x29, - 0x310, 0x28, 0x33, 0x29, 0x310, 0x28, 0x34, 0x29, - 0x310, 0x28, 0x35, 0x29, 0x310, 0x28, 0x36, 0x29, - 0x310, 0x28, 0x37, 0x29, 0x310, 0x28, 0x38, 0x29, - 0x310, 0x28, 0x39, 0x29, 0x410, 0x28, 0x31, 0x30, - 0x29, 0x410, 0x28, 0x31, 0x31, 0x29, 0x410, 0x28, - 0x31, 0x32, 0x29, 0x410, 0x28, 0x31, 0x33, 0x29, - 0x410, 0x28, 0x31, 0x34, 0x29, 0x410, 0x28, 0x31, - 0x35, 0x29, 0x410, 0x28, 0x31, 0x36, 0x29, 0x410, - 0x28, 0x31, 0x37, 0x29, 0x410, 0x28, 0x31, 0x38, - 0x29, 0x410, 0x28, 0x31, 0x39, 0x29, 0x410, 0x28, - 0x32, 0x30, 0x29, 0x210, 0x31, 0x2e, 0x210, 0x32, - 0x2e, 0x210, 0x33, 0x2e, 0x210, 0x34, 0x2e, 0x210, - 0x35, 0x2e, 0x210, 0x36, 0x2e, 0x210, 0x37, 0x2e, - 0x210, 0x38, 0x2e, 0x210, 0x39, 0x2e, 0x310, 0x31, - 0x30, 0x2e, 0x310, 0x31, 0x31, 0x2e, 0x310, 0x31, - 0x32, 0x2e, 0x310, 0x31, 0x33, 0x2e, 0x310, 0x31, - 0x34, 0x2e, 0x310, 0x31, 0x35, 0x2e, 0x310, 0x31, - 0x36, 0x2e, 0x310, 0x31, 0x37, 0x2e, 0x310, 0x31, - 0x38, 0x2e, 0x310, 0x31, 0x39, 0x2e, 0x310, 0x32, - 0x30, 0x2e, 0x310, 0x28, 0x61, 0x29, 0x310, 0x28, - 0x62, 0x29, 0x310, 0x28, 0x63, 0x29, 0x310, 0x28, - 0x64, 0x29, 0x310, 0x28, 0x65, 0x29, 0x310, 0x28, - 0x66, 0x29, 0x310, 0x28, 0x67, 0x29, 0x310, 0x28, - 0x68, 0x29, 0x310, 0x28, 0x69, 0x29, 0x310, 0x28, - 0x6a, 0x29, 0x310, 0x28, 0x6b, 0x29, 0x310, 0x28, - 0x6c, 0x29, 0x310, 0x28, 0x6d, 0x29, 0x310, 0x28, - 0x6e, 0x29, 0x310, 0x28, 0x6f, 0x29, 0x310, 0x28, - 0x70, 0x29, 0x310, 0x28, 0x71, 0x29, 0x310, 0x28, - 0x72, 0x29, 0x310, 0x28, 0x73, 0x29, 0x310, 0x28, - 0x74, 0x29, 0x310, 0x28, 0x75, 0x29, 0x310, 0x28, - 0x76, 0x29, 0x310, 0x28, 0x77, 0x29, 0x310, 0x28, - 0x78, 0x29, 0x310, 0x28, 0x79, 0x29, 0x310, 0x28, - 0x7a, 0x29, 0x108, 0x41, 0x108, 0x42, 0x108, 0x43, - 0x108, 0x44, 0x108, 0x45, 0x108, 0x46, 0x108, 0x47, - 0x108, 0x48, 0x108, 0x49, 0x108, 0x4a, 0x108, 0x4b, - 0x108, 0x4c, 0x108, 0x4d, 0x108, 0x4e, 0x108, 0x4f, - 0x108, 0x50, 0x108, 0x51, 0x108, 0x52, 0x108, 0x53, - 0x108, 0x54, 0x108, 0x55, 0x108, 0x56, 0x108, 0x57, - 0x108, 0x58, 0x108, 0x59, 0x108, 0x5a, 0x108, 0x61, - 0x108, 0x62, 0x108, 0x63, 0x108, 0x64, 0x108, 0x65, - 0x108, 0x66, 0x108, 0x67, 0x108, 0x68, 0x108, 0x69, - 0x108, 0x6a, 0x108, 0x6b, 0x108, 0x6c, 0x108, 0x6d, - 0x108, 0x6e, 0x108, 0x6f, 0x108, 0x70, 0x108, 0x71, - 0x108, 0x72, 0x108, 0x73, 0x108, 0x74, 0x108, 0x75, - 0x108, 0x76, 0x108, 0x77, 0x108, 0x78, 0x108, 0x79, - 0x108, 0x7a, 0x108, 0x30, 0x410, 0x222b, 0x222b, 0x222b, - 0x222b, 0x310, 0x3a, 0x3a, 0x3d, 0x210, 0x3d, 0x3d, - 0x310, 0x3d, 0x3d, 0x3d, 0x201, 0x2add, 0x338, 0x109, - 0x2d61, 0x110, 0x6bcd, 0x110, 0x9f9f, 0x110, 0x4e00, 0x110, - 0x4e28, 0x110, 0x4e36, 0x110, 0x4e3f, 0x110, 0x4e59, 0x110, - 0x4e85, 0x110, 0x4e8c, 0x110, 0x4ea0, 0x110, 0x4eba, 0x110, - 0x513f, 0x110, 0x5165, 0x110, 0x516b, 0x110, 0x5182, 0x110, - 0x5196, 0x110, 0x51ab, 0x110, 0x51e0, 0x110, 0x51f5, 0x110, - 0x5200, 0x110, 0x529b, 0x110, 0x52f9, 0x110, 0x5315, 0x110, - 0x531a, 0x110, 0x5338, 0x110, 0x5341, 0x110, 0x535c, 0x110, - 0x5369, 0x110, 0x5382, 0x110, 0x53b6, 0x110, 0x53c8, 0x110, - 0x53e3, 0x110, 0x56d7, 0x110, 0x571f, 0x110, 0x58eb, 0x110, - 0x5902, 0x110, 0x590a, 0x110, 0x5915, 0x110, 0x5927, 0x110, - 0x5973, 0x110, 0x5b50, 0x110, 0x5b80, 0x110, 0x5bf8, 0x110, - 0x5c0f, 0x110, 0x5c22, 0x110, 0x5c38, 0x110, 0x5c6e, 0x110, - 0x5c71, 0x110, 0x5ddb, 0x110, 0x5de5, 0x110, 0x5df1, 0x110, - 0x5dfe, 0x110, 0x5e72, 0x110, 0x5e7a, 0x110, 0x5e7f, 0x110, - 0x5ef4, 0x110, 0x5efe, 0x110, 0x5f0b, 0x110, 0x5f13, 0x110, - 0x5f50, 0x110, 0x5f61, 0x110, 0x5f73, 0x110, 0x5fc3, 0x110, - 0x6208, 0x110, 0x6236, 0x110, 0x624b, 0x110, 0x652f, 0x110, - 0x6534, 0x110, 0x6587, 0x110, 0x6597, 0x110, 0x65a4, 0x110, - 0x65b9, 0x110, 0x65e0, 0x110, 0x65e5, 0x110, 0x66f0, 0x110, - 0x6708, 0x110, 0x6728, 0x110, 0x6b20, 0x110, 0x6b62, 0x110, - 0x6b79, 0x110, 0x6bb3, 0x110, 0x6bcb, 0x110, 0x6bd4, 0x110, - 0x6bdb, 0x110, 0x6c0f, 0x110, 0x6c14, 0x110, 0x6c34, 0x110, - 0x706b, 0x110, 0x722a, 0x110, 0x7236, 0x110, 0x723b, 0x110, - 0x723f, 0x110, 0x7247, 0x110, 0x7259, 0x110, 0x725b, 0x110, - 0x72ac, 0x110, 0x7384, 0x110, 0x7389, 0x110, 0x74dc, 0x110, - 0x74e6, 0x110, 0x7518, 0x110, 0x751f, 0x110, 0x7528, 0x110, - 0x7530, 0x110, 0x758b, 0x110, 0x7592, 0x110, 0x7676, 0x110, - 0x767d, 0x110, 0x76ae, 0x110, 0x76bf, 0x110, 0x76ee, 0x110, - 0x77db, 0x110, 0x77e2, 0x110, 0x77f3, 0x110, 0x793a, 0x110, - 0x79b8, 0x110, 0x79be, 0x110, 0x7a74, 0x110, 0x7acb, 0x110, - 0x7af9, 0x110, 0x7c73, 0x110, 0x7cf8, 0x110, 0x7f36, 0x110, - 0x7f51, 0x110, 0x7f8a, 0x110, 0x7fbd, 0x110, 0x8001, 0x110, - 0x800c, 0x110, 0x8012, 0x110, 0x8033, 0x110, 0x807f, 0x110, - 0x8089, 0x110, 0x81e3, 0x110, 0x81ea, 0x110, 0x81f3, 0x110, - 0x81fc, 0x110, 0x820c, 0x110, 0x821b, 0x110, 0x821f, 0x110, - 0x826e, 0x110, 0x8272, 0x110, 0x8278, 0x110, 0x864d, 0x110, - 0x866b, 0x110, 0x8840, 0x110, 0x884c, 0x110, 0x8863, 0x110, - 0x897e, 0x110, 0x898b, 0x110, 0x89d2, 0x110, 0x8a00, 0x110, - 0x8c37, 0x110, 0x8c46, 0x110, 0x8c55, 0x110, 0x8c78, 0x110, - 0x8c9d, 0x110, 0x8d64, 0x110, 0x8d70, 0x110, 0x8db3, 0x110, - 0x8eab, 0x110, 0x8eca, 0x110, 0x8f9b, 0x110, 0x8fb0, 0x110, - 0x8fb5, 0x110, 0x9091, 0x110, 0x9149, 0x110, 0x91c6, 0x110, - 0x91cc, 0x110, 0x91d1, 0x110, 0x9577, 0x110, 0x9580, 0x110, - 0x961c, 0x110, 0x96b6, 0x110, 0x96b9, 0x110, 0x96e8, 0x110, - 0x9751, 0x110, 0x975e, 0x110, 0x9762, 0x110, 0x9769, 0x110, - 0x97cb, 0x110, 0x97ed, 0x110, 0x97f3, 0x110, 0x9801, 0x110, - 0x98a8, 0x110, 0x98db, 0x110, 0x98df, 0x110, 0x9996, 0x110, - 0x9999, 0x110, 0x99ac, 0x110, 0x9aa8, 0x110, 0x9ad8, 0x110, - 0x9adf, 0x110, 0x9b25, 0x110, 0x9b2f, 0x110, 0x9b32, 0x110, - 0x9b3c, 0x110, 0x9b5a, 0x110, 0x9ce5, 0x110, 0x9e75, 0x110, - 0x9e7f, 0x110, 0x9ea5, 0x110, 0x9ebb, 0x110, 0x9ec3, 0x110, - 0x9ecd, 0x110, 0x9ed1, 0x110, 0x9ef9, 0x110, 0x9efd, 0x110, - 0x9f0e, 0x110, 0x9f13, 0x110, 0x9f20, 0x110, 0x9f3b, 0x110, - 0x9f4a, 0x110, 0x9f52, 0x110, 0x9f8d, 0x110, 0x9f9c, 0x110, - 0x9fa0, 0x10c, 0x20, 0x110, 0x3012, 0x110, 0x5341, 0x110, - 0x5344, 0x110, 0x5345, 0x201, 0x304b, 0x3099, 0x201, 0x304d, - 0x3099, 0x201, 0x304f, 0x3099, 0x201, 0x3051, 0x3099, 0x201, - 0x3053, 0x3099, 0x201, 0x3055, 0x3099, 0x201, 0x3057, 0x3099, - 0x201, 0x3059, 0x3099, 0x201, 0x305b, 0x3099, 0x201, 0x305d, - 0x3099, 0x201, 0x305f, 0x3099, 0x201, 0x3061, 0x3099, 0x201, - 0x3064, 0x3099, 0x201, 0x3066, 0x3099, 0x201, 0x3068, 0x3099, - 0x201, 0x306f, 0x3099, 0x201, 0x306f, 0x309a, 0x201, 0x3072, - 0x3099, 0x201, 0x3072, 0x309a, 0x201, 0x3075, 0x3099, 0x201, - 0x3075, 0x309a, 0x201, 0x3078, 0x3099, 0x201, 0x3078, 0x309a, - 0x201, 0x307b, 0x3099, 0x201, 0x307b, 0x309a, 0x201, 0x3046, - 0x3099, 0x210, 0x20, 0x3099, 0x210, 0x20, 0x309a, 0x201, - 0x309d, 0x3099, 0x20b, 0x3088, 0x308a, 0x201, 0x30ab, 0x3099, - 0x201, 0x30ad, 0x3099, 0x201, 0x30af, 0x3099, 0x201, 0x30b1, - 0x3099, 0x201, 0x30b3, 0x3099, 0x201, 0x30b5, 0x3099, 0x201, - 0x30b7, 0x3099, 0x201, 0x30b9, 0x3099, 0x201, 0x30bb, 0x3099, - 0x201, 0x30bd, 0x3099, 0x201, 0x30bf, 0x3099, 0x201, 0x30c1, - 0x3099, 0x201, 0x30c4, 0x3099, 0x201, 0x30c6, 0x3099, 0x201, - 0x30c8, 0x3099, 0x201, 0x30cf, 0x3099, 0x201, 0x30cf, 0x309a, - 0x201, 0x30d2, 0x3099, 0x201, 0x30d2, 0x309a, 0x201, 0x30d5, - 0x3099, 0x201, 0x30d5, 0x309a, 0x201, 0x30d8, 0x3099, 0x201, - 0x30d8, 0x309a, 0x201, 0x30db, 0x3099, 0x201, 0x30db, 0x309a, - 0x201, 0x30a6, 0x3099, 0x201, 0x30ef, 0x3099, 0x201, 0x30f0, - 0x3099, 0x201, 0x30f1, 0x3099, 0x201, 0x30f2, 0x3099, 0x201, - 0x30fd, 0x3099, 0x20b, 0x30b3, 0x30c8, 0x110, 0x1100, 0x110, - 0x1101, 0x110, 0x11aa, 0x110, 0x1102, 0x110, 0x11ac, 0x110, - 0x11ad, 0x110, 0x1103, 0x110, 0x1104, 0x110, 0x1105, 0x110, - 0x11b0, 0x110, 0x11b1, 0x110, 0x11b2, 0x110, 0x11b3, 0x110, - 0x11b4, 0x110, 0x11b5, 0x110, 0x111a, 0x110, 0x1106, 0x110, - 0x1107, 0x110, 0x1108, 0x110, 0x1121, 0x110, 0x1109, 0x110, - 0x110a, 0x110, 0x110b, 0x110, 0x110c, 0x110, 0x110d, 0x110, - 0x110e, 0x110, 0x110f, 0x110, 0x1110, 0x110, 0x1111, 0x110, - 0x1112, 0x110, 0x1161, 0x110, 0x1162, 0x110, 0x1163, 0x110, - 0x1164, 0x110, 0x1165, 0x110, 0x1166, 0x110, 0x1167, 0x110, - 0x1168, 0x110, 0x1169, 0x110, 0x116a, 0x110, 0x116b, 0x110, - 0x116c, 0x110, 0x116d, 0x110, 0x116e, 0x110, 0x116f, 0x110, - 0x1170, 0x110, 0x1171, 0x110, 0x1172, 0x110, 0x1173, 0x110, - 0x1174, 0x110, 0x1175, 0x110, 0x1160, 0x110, 0x1114, 0x110, - 0x1115, 0x110, 0x11c7, 0x110, 0x11c8, 0x110, 0x11cc, 0x110, - 0x11ce, 0x110, 0x11d3, 0x110, 0x11d7, 0x110, 0x11d9, 0x110, - 0x111c, 0x110, 0x11dd, 0x110, 0x11df, 0x110, 0x111d, 0x110, - 0x111e, 0x110, 0x1120, 0x110, 0x1122, 0x110, 0x1123, 0x110, - 0x1127, 0x110, 0x1129, 0x110, 0x112b, 0x110, 0x112c, 0x110, - 0x112d, 0x110, 0x112e, 0x110, 0x112f, 0x110, 0x1132, 0x110, - 0x1136, 0x110, 0x1140, 0x110, 0x1147, 0x110, 0x114c, 0x110, - 0x11f1, 0x110, 0x11f2, 0x110, 0x1157, 0x110, 0x1158, 0x110, - 0x1159, 0x110, 0x1184, 0x110, 0x1185, 0x110, 0x1188, 0x110, - 0x1191, 0x110, 0x1192, 0x110, 0x1194, 0x110, 0x119e, 0x110, - 0x11a1, 0x109, 0x4e00, 0x109, 0x4e8c, 0x109, 0x4e09, 0x109, - 0x56db, 0x109, 0x4e0a, 0x109, 0x4e2d, 0x109, 0x4e0b, 0x109, - 0x7532, 0x109, 0x4e59, 0x109, 0x4e19, 0x109, 0x4e01, 0x109, - 0x5929, 0x109, 0x5730, 0x109, 0x4eba, 0x310, 0x28, 0x1100, - 0x29, 0x310, 0x28, 0x1102, 0x29, 0x310, 0x28, 0x1103, - 0x29, 0x310, 0x28, 0x1105, 0x29, 0x310, 0x28, 0x1106, - 0x29, 0x310, 0x28, 0x1107, 0x29, 0x310, 0x28, 0x1109, - 0x29, 0x310, 0x28, 0x110b, 0x29, 0x310, 0x28, 0x110c, - 0x29, 0x310, 0x28, 0x110e, 0x29, 0x310, 0x28, 0x110f, - 0x29, 0x310, 0x28, 0x1110, 0x29, 0x310, 0x28, 0x1111, - 0x29, 0x310, 0x28, 0x1112, 0x29, 0x410, 0x28, 0x1100, - 0x1161, 0x29, 0x410, 0x28, 0x1102, 0x1161, 0x29, 0x410, - 0x28, 0x1103, 0x1161, 0x29, 0x410, 0x28, 0x1105, 0x1161, - 0x29, 0x410, 0x28, 0x1106, 0x1161, 0x29, 0x410, 0x28, - 0x1107, 0x1161, 0x29, 0x410, 0x28, 0x1109, 0x1161, 0x29, - 0x410, 0x28, 0x110b, 0x1161, 0x29, 0x410, 0x28, 0x110c, - 0x1161, 0x29, 0x410, 0x28, 0x110e, 0x1161, 0x29, 0x410, - 0x28, 0x110f, 0x1161, 0x29, 0x410, 0x28, 0x1110, 0x1161, - 0x29, 0x410, 0x28, 0x1111, 0x1161, 0x29, 0x410, 0x28, - 0x1112, 0x1161, 0x29, 0x410, 0x28, 0x110c, 0x116e, 0x29, - 0x710, 0x28, 0x110b, 0x1169, 0x110c, 0x1165, 0x11ab, 0x29, - 0x610, 0x28, 0x110b, 0x1169, 0x1112, 0x116e, 0x29, 0x310, - 0x28, 0x4e00, 0x29, 0x310, 0x28, 0x4e8c, 0x29, 0x310, - 0x28, 0x4e09, 0x29, 0x310, 0x28, 0x56db, 0x29, 0x310, - 0x28, 0x4e94, 0x29, 0x310, 0x28, 0x516d, 0x29, 0x310, - 0x28, 0x4e03, 0x29, 0x310, 0x28, 0x516b, 0x29, 0x310, - 0x28, 0x4e5d, 0x29, 0x310, 0x28, 0x5341, 0x29, 0x310, - 0x28, 0x6708, 0x29, 0x310, 0x28, 0x706b, 0x29, 0x310, - 0x28, 0x6c34, 0x29, 0x310, 0x28, 0x6728, 0x29, 0x310, - 0x28, 0x91d1, 0x29, 0x310, 0x28, 0x571f, 0x29, 0x310, - 0x28, 0x65e5, 0x29, 0x310, 0x28, 0x682a, 0x29, 0x310, - 0x28, 0x6709, 0x29, 0x310, 0x28, 0x793e, 0x29, 0x310, - 0x28, 0x540d, 0x29, 0x310, 0x28, 0x7279, 0x29, 0x310, - 0x28, 0x8ca1, 0x29, 0x310, 0x28, 0x795d, 0x29, 0x310, - 0x28, 0x52b4, 0x29, 0x310, 0x28, 0x4ee3, 0x29, 0x310, - 0x28, 0x547c, 0x29, 0x310, 0x28, 0x5b66, 0x29, 0x310, - 0x28, 0x76e3, 0x29, 0x310, 0x28, 0x4f01, 0x29, 0x310, - 0x28, 0x8cc7, 0x29, 0x310, 0x28, 0x5354, 0x29, 0x310, - 0x28, 0x796d, 0x29, 0x310, 0x28, 0x4f11, 0x29, 0x310, - 0x28, 0x81ea, 0x29, 0x310, 0x28, 0x81f3, 0x29, 0x30f, - 0x50, 0x54, 0x45, 0x208, 0x32, 0x31, 0x208, 0x32, - 0x32, 0x208, 0x32, 0x33, 0x208, 0x32, 0x34, 0x208, - 0x32, 0x35, 0x208, 0x32, 0x36, 0x208, 0x32, 0x37, - 0x208, 0x32, 0x38, 0x208, 0x32, 0x39, 0x208, 0x33, - 0x30, 0x208, 0x33, 0x31, 0x208, 0x33, 0x32, 0x208, - 0x33, 0x33, 0x208, 0x33, 0x34, 0x208, 0x33, 0x35, - 0x108, 0x1100, 0x108, 0x1102, 0x108, 0x1103, 0x108, 0x1105, - 0x108, 0x1106, 0x108, 0x1107, 0x108, 0x1109, 0x108, 0x110b, - 0x108, 0x110c, 0x108, 0x110e, 0x108, 0x110f, 0x108, 0x1110, - 0x108, 0x1111, 0x108, 0x1112, 0x208, 0x1100, 0x1161, 0x208, - 0x1102, 0x1161, 0x208, 0x1103, 0x1161, 0x208, 0x1105, 0x1161, - 0x208, 0x1106, 0x1161, 0x208, 0x1107, 0x1161, 0x208, 0x1109, - 0x1161, 0x208, 0x110b, 0x1161, 0x208, 0x110c, 0x1161, 0x208, - 0x110e, 0x1161, 0x208, 0x110f, 0x1161, 0x208, 0x1110, 0x1161, - 0x208, 0x1111, 0x1161, 0x208, 0x1112, 0x1161, 0x508, 0x110e, - 0x1161, 0x11b7, 0x1100, 0x1169, 0x408, 0x110c, 0x116e, 0x110b, - 0x1174, 0x208, 0x110b, 0x116e, 0x108, 0x4e00, 0x108, 0x4e8c, - 0x108, 0x4e09, 0x108, 0x56db, 0x108, 0x4e94, 0x108, 0x516d, - 0x108, 0x4e03, 0x108, 0x516b, 0x108, 0x4e5d, 0x108, 0x5341, - 0x108, 0x6708, 0x108, 0x706b, 0x108, 0x6c34, 0x108, 0x6728, - 0x108, 0x91d1, 0x108, 0x571f, 0x108, 0x65e5, 0x108, 0x682a, - 0x108, 0x6709, 0x108, 0x793e, 0x108, 0x540d, 0x108, 0x7279, - 0x108, 0x8ca1, 0x108, 0x795d, 0x108, 0x52b4, 0x108, 0x79d8, - 0x108, 0x7537, 0x108, 0x5973, 0x108, 0x9069, 0x108, 0x512a, - 0x108, 0x5370, 0x108, 0x6ce8, 0x108, 0x9805, 0x108, 0x4f11, - 0x108, 0x5199, 0x108, 0x6b63, 0x108, 0x4e0a, 0x108, 0x4e2d, - 0x108, 0x4e0b, 0x108, 0x5de6, 0x108, 0x53f3, 0x108, 0x533b, - 0x108, 0x5b97, 0x108, 0x5b66, 0x108, 0x76e3, 0x108, 0x4f01, - 0x108, 0x8cc7, 0x108, 0x5354, 0x108, 0x591c, 0x208, 0x33, - 0x36, 0x208, 0x33, 0x37, 0x208, 0x33, 0x38, 0x208, - 0x33, 0x39, 0x208, 0x34, 0x30, 0x208, 0x34, 0x31, - 0x208, 0x34, 0x32, 0x208, 0x34, 0x33, 0x208, 0x34, - 0x34, 0x208, 0x34, 0x35, 0x208, 0x34, 0x36, 0x208, - 0x34, 0x37, 0x208, 0x34, 0x38, 0x208, 0x34, 0x39, - 0x208, 0x35, 0x30, 0x210, 0x31, 0x6708, 0x210, 0x32, - 0x6708, 0x210, 0x33, 0x6708, 0x210, 0x34, 0x6708, 0x210, - 0x35, 0x6708, 0x210, 0x36, 0x6708, 0x210, 0x37, 0x6708, - 0x210, 0x38, 0x6708, 0x210, 0x39, 0x6708, 0x310, 0x31, - 0x30, 0x6708, 0x310, 0x31, 0x31, 0x6708, 0x310, 0x31, - 0x32, 0x6708, 0x20f, 0x48, 0x67, 0x30f, 0x65, 0x72, - 0x67, 0x20f, 0x65, 0x56, 0x30f, 0x4c, 0x54, 0x44, - 0x108, 0x30a2, 0x108, 0x30a4, 0x108, 0x30a6, 0x108, 0x30a8, - 0x108, 0x30aa, 0x108, 0x30ab, 0x108, 0x30ad, 0x108, 0x30af, - 0x108, 0x30b1, 0x108, 0x30b3, 0x108, 0x30b5, 0x108, 0x30b7, - 0x108, 0x30b9, 0x108, 0x30bb, 0x108, 0x30bd, 0x108, 0x30bf, - 0x108, 0x30c1, 0x108, 0x30c4, 0x108, 0x30c6, 0x108, 0x30c8, - 0x108, 0x30ca, 0x108, 0x30cb, 0x108, 0x30cc, 0x108, 0x30cd, - 0x108, 0x30ce, 0x108, 0x30cf, 0x108, 0x30d2, 0x108, 0x30d5, - 0x108, 0x30d8, 0x108, 0x30db, 0x108, 0x30de, 0x108, 0x30df, - 0x108, 0x30e0, 0x108, 0x30e1, 0x108, 0x30e2, 0x108, 0x30e4, - 0x108, 0x30e6, 0x108, 0x30e8, 0x108, 0x30e9, 0x108, 0x30ea, - 0x108, 0x30eb, 0x108, 0x30ec, 0x108, 0x30ed, 0x108, 0x30ef, - 0x108, 0x30f0, 0x108, 0x30f1, 0x108, 0x30f2, 0x40f, 0x30a2, - 0x30d1, 0x30fc, 0x30c8, 0x40f, 0x30a2, 0x30eb, 0x30d5, 0x30a1, - 0x40f, 0x30a2, 0x30f3, 0x30da, 0x30a2, 0x30f, 0x30a2, 0x30fc, - 0x30eb, 0x40f, 0x30a4, 0x30cb, 0x30f3, 0x30b0, 0x30f, 0x30a4, - 0x30f3, 0x30c1, 0x30f, 0x30a6, 0x30a9, 0x30f3, 0x50f, 0x30a8, - 0x30b9, 0x30af, 0x30fc, 0x30c9, 0x40f, 0x30a8, 0x30fc, 0x30ab, - 0x30fc, 0x30f, 0x30aa, 0x30f3, 0x30b9, 0x30f, 0x30aa, 0x30fc, - 0x30e0, 0x30f, 0x30ab, 0x30a4, 0x30ea, 0x40f, 0x30ab, 0x30e9, - 0x30c3, 0x30c8, 0x40f, 0x30ab, 0x30ed, 0x30ea, 0x30fc, 0x30f, - 0x30ac, 0x30ed, 0x30f3, 0x30f, 0x30ac, 0x30f3, 0x30de, 0x20f, - 0x30ae, 0x30ac, 0x30f, 0x30ae, 0x30cb, 0x30fc, 0x40f, 0x30ad, - 0x30e5, 0x30ea, 0x30fc, 0x40f, 0x30ae, 0x30eb, 0x30c0, 0x30fc, - 0x20f, 0x30ad, 0x30ed, 0x50f, 0x30ad, 0x30ed, 0x30b0, 0x30e9, - 0x30e0, 0x60f, 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8, 0x30eb, - 0x50f, 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8, 0x30f, 0x30b0, - 0x30e9, 0x30e0, 0x50f, 0x30b0, 0x30e9, 0x30e0, 0x30c8, 0x30f3, - 0x50f, 0x30af, 0x30eb, 0x30bc, 0x30a4, 0x30ed, 0x40f, 0x30af, - 0x30ed, 0x30fc, 0x30cd, 0x30f, 0x30b1, 0x30fc, 0x30b9, 0x30f, - 0x30b3, 0x30eb, 0x30ca, 0x30f, 0x30b3, 0x30fc, 0x30dd, 0x40f, - 0x30b5, 0x30a4, 0x30af, 0x30eb, 0x50f, 0x30b5, 0x30f3, 0x30c1, - 0x30fc, 0x30e0, 0x40f, 0x30b7, 0x30ea, 0x30f3, 0x30b0, 0x30f, - 0x30bb, 0x30f3, 0x30c1, 0x30f, 0x30bb, 0x30f3, 0x30c8, 0x30f, - 0x30c0, 0x30fc, 0x30b9, 0x20f, 0x30c7, 0x30b7, 0x20f, 0x30c9, - 0x30eb, 0x20f, 0x30c8, 0x30f3, 0x20f, 0x30ca, 0x30ce, 0x30f, - 0x30ce, 0x30c3, 0x30c8, 0x30f, 0x30cf, 0x30a4, 0x30c4, 0x50f, - 0x30d1, 0x30fc, 0x30bb, 0x30f3, 0x30c8, 0x30f, 0x30d1, 0x30fc, - 0x30c4, 0x40f, 0x30d0, 0x30fc, 0x30ec, 0x30eb, 0x50f, 0x30d4, - 0x30a2, 0x30b9, 0x30c8, 0x30eb, 0x30f, 0x30d4, 0x30af, 0x30eb, - 0x20f, 0x30d4, 0x30b3, 0x20f, 0x30d3, 0x30eb, 0x50f, 0x30d5, - 0x30a1, 0x30e9, 0x30c3, 0x30c9, 0x40f, 0x30d5, 0x30a3, 0x30fc, - 0x30c8, 0x50f, 0x30d6, 0x30c3, 0x30b7, 0x30a7, 0x30eb, 0x30f, - 0x30d5, 0x30e9, 0x30f3, 0x50f, 0x30d8, 0x30af, 0x30bf, 0x30fc, - 0x30eb, 0x20f, 0x30da, 0x30bd, 0x30f, 0x30da, 0x30cb, 0x30d2, - 0x30f, 0x30d8, 0x30eb, 0x30c4, 0x30f, 0x30da, 0x30f3, 0x30b9, - 0x30f, 0x30da, 0x30fc, 0x30b8, 0x30f, 0x30d9, 0x30fc, 0x30bf, - 0x40f, 0x30dd, 0x30a4, 0x30f3, 0x30c8, 0x30f, 0x30dc, 0x30eb, - 0x30c8, 0x20f, 0x30db, 0x30f3, 0x30f, 0x30dd, 0x30f3, 0x30c9, - 0x30f, 0x30db, 0x30fc, 0x30eb, 0x30f, 0x30db, 0x30fc, 0x30f3, - 0x40f, 0x30de, 0x30a4, 0x30af, 0x30ed, 0x30f, 0x30de, 0x30a4, - 0x30eb, 0x30f, 0x30de, 0x30c3, 0x30cf, 0x30f, 0x30de, 0x30eb, - 0x30af, 0x50f, 0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3, 0x40f, - 0x30df, 0x30af, 0x30ed, 0x30f3, 0x20f, 0x30df, 0x30ea, 0x50f, - 0x30df, 0x30ea, 0x30d0, 0x30fc, 0x30eb, 0x20f, 0x30e1, 0x30ac, - 0x40f, 0x30e1, 0x30ac, 0x30c8, 0x30f3, 0x40f, 0x30e1, 0x30fc, - 0x30c8, 0x30eb, 0x30f, 0x30e4, 0x30fc, 0x30c9, 0x30f, 0x30e4, - 0x30fc, 0x30eb, 0x30f, 0x30e6, 0x30a2, 0x30f3, 0x40f, 0x30ea, - 0x30c3, 0x30c8, 0x30eb, 0x20f, 0x30ea, 0x30e9, 0x30f, 0x30eb, - 0x30d4, 0x30fc, 0x40f, 0x30eb, 0x30fc, 0x30d6, 0x30eb, 0x20f, - 0x30ec, 0x30e0, 0x50f, 0x30ec, 0x30f3, 0x30c8, 0x30b2, 0x30f3, - 0x30f, 0x30ef, 0x30c3, 0x30c8, 0x210, 0x30, 0x70b9, 0x210, - 0x31, 0x70b9, 0x210, 0x32, 0x70b9, 0x210, 0x33, 0x70b9, - 0x210, 0x34, 0x70b9, 0x210, 0x35, 0x70b9, 0x210, 0x36, - 0x70b9, 0x210, 0x37, 0x70b9, 0x210, 0x38, 0x70b9, 0x210, - 0x39, 0x70b9, 0x310, 0x31, 0x30, 0x70b9, 0x310, 0x31, - 0x31, 0x70b9, 0x310, 0x31, 0x32, 0x70b9, 0x310, 0x31, - 0x33, 0x70b9, 0x310, 0x31, 0x34, 0x70b9, 0x310, 0x31, - 0x35, 0x70b9, 0x310, 0x31, 0x36, 0x70b9, 0x310, 0x31, - 0x37, 0x70b9, 0x310, 0x31, 0x38, 0x70b9, 0x310, 0x31, - 0x39, 0x70b9, 0x310, 0x32, 0x30, 0x70b9, 0x310, 0x32, - 0x31, 0x70b9, 0x310, 0x32, 0x32, 0x70b9, 0x310, 0x32, - 0x33, 0x70b9, 0x310, 0x32, 0x34, 0x70b9, 0x30f, 0x68, - 0x50, 0x61, 0x20f, 0x64, 0x61, 0x20f, 0x41, 0x55, - 0x30f, 0x62, 0x61, 0x72, 0x20f, 0x6f, 0x56, 0x20f, - 0x70, 0x63, 0x20f, 0x64, 0x6d, 0x30f, 0x64, 0x6d, - 0xb2, 0x30f, 0x64, 0x6d, 0xb3, 0x20f, 0x49, 0x55, - 0x20f, 0x5e73, 0x6210, 0x20f, 0x662d, 0x548c, 0x20f, 0x5927, - 0x6b63, 0x20f, 0x660e, 0x6cbb, 0x40f, 0x682a, 0x5f0f, 0x4f1a, - 0x793e, 0x20f, 0x70, 0x41, 0x20f, 0x6e, 0x41, 0x20f, - 0x3bc, 0x41, 0x20f, 0x6d, 0x41, 0x20f, 0x6b, 0x41, - 0x20f, 0x4b, 0x42, 0x20f, 0x4d, 0x42, 0x20f, 0x47, - 0x42, 0x30f, 0x63, 0x61, 0x6c, 0x40f, 0x6b, 0x63, - 0x61, 0x6c, 0x20f, 0x70, 0x46, 0x20f, 0x6e, 0x46, - 0x20f, 0x3bc, 0x46, 0x20f, 0x3bc, 0x67, 0x20f, 0x6d, - 0x67, 0x20f, 0x6b, 0x67, 0x20f, 0x48, 0x7a, 0x30f, - 0x6b, 0x48, 0x7a, 0x30f, 0x4d, 0x48, 0x7a, 0x30f, - 0x47, 0x48, 0x7a, 0x30f, 0x54, 0x48, 0x7a, 0x20f, - 0x3bc, 0x2113, 0x20f, 0x6d, 0x2113, 0x20f, 0x64, 0x2113, - 0x20f, 0x6b, 0x2113, 0x20f, 0x66, 0x6d, 0x20f, 0x6e, - 0x6d, 0x20f, 0x3bc, 0x6d, 0x20f, 0x6d, 0x6d, 0x20f, - 0x63, 0x6d, 0x20f, 0x6b, 0x6d, 0x30f, 0x6d, 0x6d, - 0xb2, 0x30f, 0x63, 0x6d, 0xb2, 0x20f, 0x6d, 0xb2, - 0x30f, 0x6b, 0x6d, 0xb2, 0x30f, 0x6d, 0x6d, 0xb3, - 0x30f, 0x63, 0x6d, 0xb3, 0x20f, 0x6d, 0xb3, 0x30f, - 0x6b, 0x6d, 0xb3, 0x30f, 0x6d, 0x2215, 0x73, 0x40f, - 0x6d, 0x2215, 0x73, 0xb2, 0x20f, 0x50, 0x61, 0x30f, - 0x6b, 0x50, 0x61, 0x30f, 0x4d, 0x50, 0x61, 0x30f, - 0x47, 0x50, 0x61, 0x30f, 0x72, 0x61, 0x64, 0x50f, - 0x72, 0x61, 0x64, 0x2215, 0x73, 0x60f, 0x72, 0x61, - 0x64, 0x2215, 0x73, 0xb2, 0x20f, 0x70, 0x73, 0x20f, - 0x6e, 0x73, 0x20f, 0x3bc, 0x73, 0x20f, 0x6d, 0x73, - 0x20f, 0x70, 0x56, 0x20f, 0x6e, 0x56, 0x20f, 0x3bc, - 0x56, 0x20f, 0x6d, 0x56, 0x20f, 0x6b, 0x56, 0x20f, - 0x4d, 0x56, 0x20f, 0x70, 0x57, 0x20f, 0x6e, 0x57, - 0x20f, 0x3bc, 0x57, 0x20f, 0x6d, 0x57, 0x20f, 0x6b, - 0x57, 0x20f, 0x4d, 0x57, 0x20f, 0x6b, 0x3a9, 0x20f, - 0x4d, 0x3a9, 0x40f, 0x61, 0x2e, 0x6d, 0x2e, 0x20f, - 0x42, 0x71, 0x20f, 0x63, 0x63, 0x20f, 0x63, 0x64, - 0x40f, 0x43, 0x2215, 0x6b, 0x67, 0x30f, 0x43, 0x6f, - 0x2e, 0x20f, 0x64, 0x42, 0x20f, 0x47, 0x79, 0x20f, - 0x68, 0x61, 0x20f, 0x48, 0x50, 0x20f, 0x69, 0x6e, - 0x20f, 0x4b, 0x4b, 0x20f, 0x4b, 0x4d, 0x20f, 0x6b, - 0x74, 0x20f, 0x6c, 0x6d, 0x20f, 0x6c, 0x6e, 0x30f, - 0x6c, 0x6f, 0x67, 0x20f, 0x6c, 0x78, 0x20f, 0x6d, - 0x62, 0x30f, 0x6d, 0x69, 0x6c, 0x30f, 0x6d, 0x6f, - 0x6c, 0x20f, 0x50, 0x48, 0x40f, 0x70, 0x2e, 0x6d, - 0x2e, 0x30f, 0x50, 0x50, 0x4d, 0x20f, 0x50, 0x52, - 0x20f, 0x73, 0x72, 0x20f, 0x53, 0x76, 0x20f, 0x57, - 0x62, 0x30f, 0x56, 0x2215, 0x6d, 0x30f, 0x41, 0x2215, - 0x6d, 0x210, 0x31, 0x65e5, 0x210, 0x32, 0x65e5, 0x210, - 0x33, 0x65e5, 0x210, 0x34, 0x65e5, 0x210, 0x35, 0x65e5, - 0x210, 0x36, 0x65e5, 0x210, 0x37, 0x65e5, 0x210, 0x38, - 0x65e5, 0x210, 0x39, 0x65e5, 0x310, 0x31, 0x30, 0x65e5, - 0x310, 0x31, 0x31, 0x65e5, 0x310, 0x31, 0x32, 0x65e5, - 0x310, 0x31, 0x33, 0x65e5, 0x310, 0x31, 0x34, 0x65e5, - 0x310, 0x31, 0x35, 0x65e5, 0x310, 0x31, 0x36, 0x65e5, - 0x310, 0x31, 0x37, 0x65e5, 0x310, 0x31, 0x38, 0x65e5, - 0x310, 0x31, 0x39, 0x65e5, 0x310, 0x32, 0x30, 0x65e5, - 0x310, 0x32, 0x31, 0x65e5, 0x310, 0x32, 0x32, 0x65e5, - 0x310, 0x32, 0x33, 0x65e5, 0x310, 0x32, 0x34, 0x65e5, - 0x310, 0x32, 0x35, 0x65e5, 0x310, 0x32, 0x36, 0x65e5, - 0x310, 0x32, 0x37, 0x65e5, 0x310, 0x32, 0x38, 0x65e5, - 0x310, 0x32, 0x39, 0x65e5, 0x310, 0x33, 0x30, 0x65e5, - 0x310, 0x33, 0x31, 0x65e5, 0x30f, 0x67, 0x61, 0x6c, - 0x101, 0x8c48, 0x101, 0x66f4, 0x101, 0x8eca, 0x101, 0x8cc8, - 0x101, 0x6ed1, 0x101, 0x4e32, 0x101, 0x53e5, 0x101, 0x9f9c, - 0x101, 0x9f9c, 0x101, 0x5951, 0x101, 0x91d1, 0x101, 0x5587, - 0x101, 0x5948, 0x101, 0x61f6, 0x101, 0x7669, 0x101, 0x7f85, - 0x101, 0x863f, 0x101, 0x87ba, 0x101, 0x88f8, 0x101, 0x908f, - 0x101, 0x6a02, 0x101, 0x6d1b, 0x101, 0x70d9, 0x101, 0x73de, - 0x101, 0x843d, 0x101, 0x916a, 0x101, 0x99f1, 0x101, 0x4e82, - 0x101, 0x5375, 0x101, 0x6b04, 0x101, 0x721b, 0x101, 0x862d, - 0x101, 0x9e1e, 0x101, 0x5d50, 0x101, 0x6feb, 0x101, 0x85cd, - 0x101, 0x8964, 0x101, 0x62c9, 0x101, 0x81d8, 0x101, 0x881f, - 0x101, 0x5eca, 0x101, 0x6717, 0x101, 0x6d6a, 0x101, 0x72fc, - 0x101, 0x90ce, 0x101, 0x4f86, 0x101, 0x51b7, 0x101, 0x52de, - 0x101, 0x64c4, 0x101, 0x6ad3, 0x101, 0x7210, 0x101, 0x76e7, - 0x101, 0x8001, 0x101, 0x8606, 0x101, 0x865c, 0x101, 0x8def, - 0x101, 0x9732, 0x101, 0x9b6f, 0x101, 0x9dfa, 0x101, 0x788c, - 0x101, 0x797f, 0x101, 0x7da0, 0x101, 0x83c9, 0x101, 0x9304, - 0x101, 0x9e7f, 0x101, 0x8ad6, 0x101, 0x58df, 0x101, 0x5f04, - 0x101, 0x7c60, 0x101, 0x807e, 0x101, 0x7262, 0x101, 0x78ca, - 0x101, 0x8cc2, 0x101, 0x96f7, 0x101, 0x58d8, 0x101, 0x5c62, - 0x101, 0x6a13, 0x101, 0x6dda, 0x101, 0x6f0f, 0x101, 0x7d2f, - 0x101, 0x7e37, 0x101, 0x964b, 0x101, 0x52d2, 0x101, 0x808b, - 0x101, 0x51dc, 0x101, 0x51cc, 0x101, 0x7a1c, 0x101, 0x7dbe, - 0x101, 0x83f1, 0x101, 0x9675, 0x101, 0x8b80, 0x101, 0x62cf, - 0x101, 0x6a02, 0x101, 0x8afe, 0x101, 0x4e39, 0x101, 0x5be7, - 0x101, 0x6012, 0x101, 0x7387, 0x101, 0x7570, 0x101, 0x5317, - 0x101, 0x78fb, 0x101, 0x4fbf, 0x101, 0x5fa9, 0x101, 0x4e0d, - 0x101, 0x6ccc, 0x101, 0x6578, 0x101, 0x7d22, 0x101, 0x53c3, - 0x101, 0x585e, 0x101, 0x7701, 0x101, 0x8449, 0x101, 0x8aaa, - 0x101, 0x6bba, 0x101, 0x8fb0, 0x101, 0x6c88, 0x101, 0x62fe, - 0x101, 0x82e5, 0x101, 0x63a0, 0x101, 0x7565, 0x101, 0x4eae, - 0x101, 0x5169, 0x101, 0x51c9, 0x101, 0x6881, 0x101, 0x7ce7, - 0x101, 0x826f, 0x101, 0x8ad2, 0x101, 0x91cf, 0x101, 0x52f5, - 0x101, 0x5442, 0x101, 0x5973, 0x101, 0x5eec, 0x101, 0x65c5, - 0x101, 0x6ffe, 0x101, 0x792a, 0x101, 0x95ad, 0x101, 0x9a6a, - 0x101, 0x9e97, 0x101, 0x9ece, 0x101, 0x529b, 0x101, 0x66c6, - 0x101, 0x6b77, 0x101, 0x8f62, 0x101, 0x5e74, 0x101, 0x6190, - 0x101, 0x6200, 0x101, 0x649a, 0x101, 0x6f23, 0x101, 0x7149, - 0x101, 0x7489, 0x101, 0x79ca, 0x101, 0x7df4, 0x101, 0x806f, - 0x101, 0x8f26, 0x101, 0x84ee, 0x101, 0x9023, 0x101, 0x934a, - 0x101, 0x5217, 0x101, 0x52a3, 0x101, 0x54bd, 0x101, 0x70c8, - 0x101, 0x88c2, 0x101, 0x8aaa, 0x101, 0x5ec9, 0x101, 0x5ff5, - 0x101, 0x637b, 0x101, 0x6bae, 0x101, 0x7c3e, 0x101, 0x7375, - 0x101, 0x4ee4, 0x101, 0x56f9, 0x101, 0x5be7, 0x101, 0x5dba, - 0x101, 0x601c, 0x101, 0x73b2, 0x101, 0x7469, 0x101, 0x7f9a, - 0x101, 0x8046, 0x101, 0x9234, 0x101, 0x96f6, 0x101, 0x9748, - 0x101, 0x9818, 0x101, 0x4f8b, 0x101, 0x79ae, 0x101, 0x91b4, - 0x101, 0x96b8, 0x101, 0x60e1, 0x101, 0x4e86, 0x101, 0x50da, - 0x101, 0x5bee, 0x101, 0x5c3f, 0x101, 0x6599, 0x101, 0x6a02, - 0x101, 0x71ce, 0x101, 0x7642, 0x101, 0x84fc, 0x101, 0x907c, - 0x101, 0x9f8d, 0x101, 0x6688, 0x101, 0x962e, 0x101, 0x5289, - 0x101, 0x677b, 0x101, 0x67f3, 0x101, 0x6d41, 0x101, 0x6e9c, - 0x101, 0x7409, 0x101, 0x7559, 0x101, 0x786b, 0x101, 0x7d10, - 0x101, 0x985e, 0x101, 0x516d, 0x101, 0x622e, 0x101, 0x9678, - 0x101, 0x502b, 0x101, 0x5d19, 0x101, 0x6dea, 0x101, 0x8f2a, - 0x101, 0x5f8b, 0x101, 0x6144, 0x101, 0x6817, 0x101, 0x7387, - 0x101, 0x9686, 0x101, 0x5229, 0x101, 0x540f, 0x101, 0x5c65, - 0x101, 0x6613, 0x101, 0x674e, 0x101, 0x68a8, 0x101, 0x6ce5, - 0x101, 0x7406, 0x101, 0x75e2, 0x101, 0x7f79, 0x101, 0x88cf, - 0x101, 0x88e1, 0x101, 0x91cc, 0x101, 0x96e2, 0x101, 0x533f, - 0x101, 0x6eba, 0x101, 0x541d, 0x101, 0x71d0, 0x101, 0x7498, - 0x101, 0x85fa, 0x101, 0x96a3, 0x101, 0x9c57, 0x101, 0x9e9f, - 0x101, 0x6797, 0x101, 0x6dcb, 0x101, 0x81e8, 0x101, 0x7acb, - 0x101, 0x7b20, 0x101, 0x7c92, 0x101, 0x72c0, 0x101, 0x7099, - 0x101, 0x8b58, 0x101, 0x4ec0, 0x101, 0x8336, 0x101, 0x523a, - 0x101, 0x5207, 0x101, 0x5ea6, 0x101, 0x62d3, 0x101, 0x7cd6, - 0x101, 0x5b85, 0x101, 0x6d1e, 0x101, 0x66b4, 0x101, 0x8f3b, - 0x101, 0x884c, 0x101, 0x964d, 0x101, 0x898b, 0x101, 0x5ed3, - 0x101, 0x5140, 0x101, 0x55c0, 0x101, 0x585a, 0x101, 0x6674, - 0x101, 0x51de, 0x101, 0x732a, 0x101, 0x76ca, 0x101, 0x793c, - 0x101, 0x795e, 0x101, 0x7965, 0x101, 0x798f, 0x101, 0x9756, - 0x101, 0x7cbe, 0x101, 0x7fbd, 0x101, 0x8612, 0x101, 0x8af8, - 0x101, 0x9038, 0x101, 0x90fd, 0x101, 0x98ef, 0x101, 0x98fc, - 0x101, 0x9928, 0x101, 0x9db4, 0x101, 0x4fae, 0x101, 0x50e7, - 0x101, 0x514d, 0x101, 0x52c9, 0x101, 0x52e4, 0x101, 0x5351, - 0x101, 0x559d, 0x101, 0x5606, 0x101, 0x5668, 0x101, 0x5840, - 0x101, 0x58a8, 0x101, 0x5c64, 0x101, 0x5c6e, 0x101, 0x6094, - 0x101, 0x6168, 0x101, 0x618e, 0x101, 0x61f2, 0x101, 0x654f, - 0x101, 0x65e2, 0x101, 0x6691, 0x101, 0x6885, 0x101, 0x6d77, - 0x101, 0x6e1a, 0x101, 0x6f22, 0x101, 0x716e, 0x101, 0x722b, - 0x101, 0x7422, 0x101, 0x7891, 0x101, 0x793e, 0x101, 0x7949, - 0x101, 0x7948, 0x101, 0x7950, 0x101, 0x7956, 0x101, 0x795d, - 0x101, 0x798d, 0x101, 0x798e, 0x101, 0x7a40, 0x101, 0x7a81, - 0x101, 0x7bc0, 0x101, 0x7df4, 0x101, 0x7e09, 0x101, 0x7e41, - 0x101, 0x7f72, 0x101, 0x8005, 0x101, 0x81ed, 0x101, 0x8279, - 0x101, 0x8279, 0x101, 0x8457, 0x101, 0x8910, 0x101, 0x8996, - 0x101, 0x8b01, 0x101, 0x8b39, 0x101, 0x8cd3, 0x101, 0x8d08, - 0x101, 0x8fb6, 0x101, 0x9038, 0x101, 0x96e3, 0x101, 0x97ff, - 0x101, 0x983b, 0x101, 0x4e26, 0x101, 0x51b5, 0x101, 0x5168, - 0x101, 0x4f80, 0x101, 0x5145, 0x101, 0x5180, 0x101, 0x52c7, - 0x101, 0x52fa, 0x101, 0x559d, 0x101, 0x5555, 0x101, 0x5599, - 0x101, 0x55e2, 0x101, 0x585a, 0x101, 0x58b3, 0x101, 0x5944, - 0x101, 0x5954, 0x101, 0x5a62, 0x101, 0x5b28, 0x101, 0x5ed2, - 0x101, 0x5ed9, 0x101, 0x5f69, 0x101, 0x5fad, 0x101, 0x60d8, - 0x101, 0x614e, 0x101, 0x6108, 0x101, 0x618e, 0x101, 0x6160, - 0x101, 0x61f2, 0x101, 0x6234, 0x101, 0x63c4, 0x101, 0x641c, - 0x101, 0x6452, 0x101, 0x6556, 0x101, 0x6674, 0x101, 0x6717, - 0x101, 0x671b, 0x101, 0x6756, 0x101, 0x6b79, 0x101, 0x6bba, - 0x101, 0x6d41, 0x101, 0x6edb, 0x101, 0x6ecb, 0x101, 0x6f22, - 0x101, 0x701e, 0x101, 0x716e, 0x101, 0x77a7, 0x101, 0x7235, - 0x101, 0x72af, 0x101, 0x732a, 0x101, 0x7471, 0x101, 0x7506, - 0x101, 0x753b, 0x101, 0x761d, 0x101, 0x761f, 0x101, 0x76ca, - 0x101, 0x76db, 0x101, 0x76f4, 0x101, 0x774a, 0x101, 0x7740, - 0x101, 0x78cc, 0x101, 0x7ab1, 0x101, 0x7bc0, 0x101, 0x7c7b, - 0x101, 0x7d5b, 0x101, 0x7df4, 0x101, 0x7f3e, 0x101, 0x8005, - 0x101, 0x8352, 0x101, 0x83ef, 0x101, 0x8779, 0x101, 0x8941, - 0x101, 0x8986, 0x101, 0x8996, 0x101, 0x8abf, 0x101, 0x8af8, - 0x101, 0x8acb, 0x101, 0x8b01, 0x101, 0x8afe, 0x101, 0x8aed, - 0x101, 0x8b39, 0x101, 0x8b8a, 0x101, 0x8d08, 0x101, 0x8f38, - 0x101, 0x9072, 0x101, 0x9199, 0x101, 0x9276, 0x101, 0x967c, - 0x101, 0x96e3, 0x101, 0x9756, 0x101, 0x97db, 0x101, 0x97ff, - 0x101, 0x980b, 0x101, 0x983b, 0x101, 0x9b12, 0x101, 0x9f9c, - 0x201, 0xd84a, 0xdc4a, 0x201, 0xd84a, 0xdc44, 0x201, 0xd84c, - 0xdfd5, 0x101, 0x3b9d, 0x101, 0x4018, 0x101, 0x4039, 0x201, - 0xd854, 0xde49, 0x201, 0xd857, 0xdcd0, 0x201, 0xd85f, 0xded3, - 0x101, 0x9f43, 0x101, 0x9f8e, 0x210, 0x66, 0x66, 0x210, - 0x66, 0x69, 0x210, 0x66, 0x6c, 0x310, 0x66, 0x66, - 0x69, 0x310, 0x66, 0x66, 0x6c, 0x210, 0x17f, 0x74, - 0x210, 0x73, 0x74, 0x210, 0x574, 0x576, 0x210, 0x574, - 0x565, 0x210, 0x574, 0x56b, 0x210, 0x57e, 0x576, 0x210, - 0x574, 0x56d, 0x201, 0x5d9, 0x5b4, 0x201, 0x5f2, 0x5b7, - 0x102, 0x5e2, 0x102, 0x5d0, 0x102, 0x5d3, 0x102, 0x5d4, - 0x102, 0x5db, 0x102, 0x5dc, 0x102, 0x5dd, 0x102, 0x5e8, - 0x102, 0x5ea, 0x102, 0x2b, 0x201, 0x5e9, 0x5c1, 0x201, - 0x5e9, 0x5c2, 0x201, 0xfb49, 0x5c1, 0x201, 0xfb49, 0x5c2, - 0x201, 0x5d0, 0x5b7, 0x201, 0x5d0, 0x5b8, 0x201, 0x5d0, - 0x5bc, 0x201, 0x5d1, 0x5bc, 0x201, 0x5d2, 0x5bc, 0x201, - 0x5d3, 0x5bc, 0x201, 0x5d4, 0x5bc, 0x201, 0x5d5, 0x5bc, - 0x201, 0x5d6, 0x5bc, 0x201, 0x5d8, 0x5bc, 0x201, 0x5d9, - 0x5bc, 0x201, 0x5da, 0x5bc, 0x201, 0x5db, 0x5bc, 0x201, - 0x5dc, 0x5bc, 0x201, 0x5de, 0x5bc, 0x201, 0x5e0, 0x5bc, - 0x201, 0x5e1, 0x5bc, 0x201, 0x5e3, 0x5bc, 0x201, 0x5e4, - 0x5bc, 0x201, 0x5e6, 0x5bc, 0x201, 0x5e7, 0x5bc, 0x201, - 0x5e8, 0x5bc, 0x201, 0x5e9, 0x5bc, 0x201, 0x5ea, 0x5bc, - 0x201, 0x5d5, 0x5b9, 0x201, 0x5d1, 0x5bf, 0x201, 0x5db, - 0x5bf, 0x201, 0x5e4, 0x5bf, 0x210, 0x5d0, 0x5dc, 0x107, - 0x671, 0x106, 0x671, 0x107, 0x67b, 0x106, 0x67b, 0x104, - 0x67b, 0x105, 0x67b, 0x107, 0x67e, 0x106, 0x67e, 0x104, - 0x67e, 0x105, 0x67e, 0x107, 0x680, 0x106, 0x680, 0x104, - 0x680, 0x105, 0x680, 0x107, 0x67a, 0x106, 0x67a, 0x104, - 0x67a, 0x105, 0x67a, 0x107, 0x67f, 0x106, 0x67f, 0x104, - 0x67f, 0x105, 0x67f, 0x107, 0x679, 0x106, 0x679, 0x104, - 0x679, 0x105, 0x679, 0x107, 0x6a4, 0x106, 0x6a4, 0x104, - 0x6a4, 0x105, 0x6a4, 0x107, 0x6a6, 0x106, 0x6a6, 0x104, - 0x6a6, 0x105, 0x6a6, 0x107, 0x684, 0x106, 0x684, 0x104, - 0x684, 0x105, 0x684, 0x107, 0x683, 0x106, 0x683, 0x104, - 0x683, 0x105, 0x683, 0x107, 0x686, 0x106, 0x686, 0x104, - 0x686, 0x105, 0x686, 0x107, 0x687, 0x106, 0x687, 0x104, - 0x687, 0x105, 0x687, 0x107, 0x68d, 0x106, 0x68d, 0x107, - 0x68c, 0x106, 0x68c, 0x107, 0x68e, 0x106, 0x68e, 0x107, - 0x688, 0x106, 0x688, 0x107, 0x698, 0x106, 0x698, 0x107, - 0x691, 0x106, 0x691, 0x107, 0x6a9, 0x106, 0x6a9, 0x104, - 0x6a9, 0x105, 0x6a9, 0x107, 0x6af, 0x106, 0x6af, 0x104, - 0x6af, 0x105, 0x6af, 0x107, 0x6b3, 0x106, 0x6b3, 0x104, - 0x6b3, 0x105, 0x6b3, 0x107, 0x6b1, 0x106, 0x6b1, 0x104, - 0x6b1, 0x105, 0x6b1, 0x107, 0x6ba, 0x106, 0x6ba, 0x107, - 0x6bb, 0x106, 0x6bb, 0x104, 0x6bb, 0x105, 0x6bb, 0x107, - 0x6c0, 0x106, 0x6c0, 0x107, 0x6c1, 0x106, 0x6c1, 0x104, - 0x6c1, 0x105, 0x6c1, 0x107, 0x6be, 0x106, 0x6be, 0x104, - 0x6be, 0x105, 0x6be, 0x107, 0x6d2, 0x106, 0x6d2, 0x107, - 0x6d3, 0x106, 0x6d3, 0x107, 0x6ad, 0x106, 0x6ad, 0x104, - 0x6ad, 0x105, 0x6ad, 0x107, 0x6c7, 0x106, 0x6c7, 0x107, - 0x6c6, 0x106, 0x6c6, 0x107, 0x6c8, 0x106, 0x6c8, 0x107, - 0x677, 0x107, 0x6cb, 0x106, 0x6cb, 0x107, 0x6c5, 0x106, - 0x6c5, 0x107, 0x6c9, 0x106, 0x6c9, 0x107, 0x6d0, 0x106, - 0x6d0, 0x104, 0x6d0, 0x105, 0x6d0, 0x104, 0x649, 0x105, - 0x649, 0x207, 0x626, 0x627, 0x206, 0x626, 0x627, 0x207, - 0x626, 0x6d5, 0x206, 0x626, 0x6d5, 0x207, 0x626, 0x648, - 0x206, 0x626, 0x648, 0x207, 0x626, 0x6c7, 0x206, 0x626, - 0x6c7, 0x207, 0x626, 0x6c6, 0x206, 0x626, 0x6c6, 0x207, - 0x626, 0x6c8, 0x206, 0x626, 0x6c8, 0x207, 0x626, 0x6d0, - 0x206, 0x626, 0x6d0, 0x204, 0x626, 0x6d0, 0x207, 0x626, - 0x649, 0x206, 0x626, 0x649, 0x204, 0x626, 0x649, 0x107, - 0x6cc, 0x106, 0x6cc, 0x104, 0x6cc, 0x105, 0x6cc, 0x207, - 0x626, 0x62c, 0x207, 0x626, 0x62d, 0x207, 0x626, 0x645, - 0x207, 0x626, 0x649, 0x207, 0x626, 0x64a, 0x207, 0x628, - 0x62c, 0x207, 0x628, 0x62d, 0x207, 0x628, 0x62e, 0x207, - 0x628, 0x645, 0x207, 0x628, 0x649, 0x207, 0x628, 0x64a, - 0x207, 0x62a, 0x62c, 0x207, 0x62a, 0x62d, 0x207, 0x62a, - 0x62e, 0x207, 0x62a, 0x645, 0x207, 0x62a, 0x649, 0x207, - 0x62a, 0x64a, 0x207, 0x62b, 0x62c, 0x207, 0x62b, 0x645, - 0x207, 0x62b, 0x649, 0x207, 0x62b, 0x64a, 0x207, 0x62c, - 0x62d, 0x207, 0x62c, 0x645, 0x207, 0x62d, 0x62c, 0x207, - 0x62d, 0x645, 0x207, 0x62e, 0x62c, 0x207, 0x62e, 0x62d, - 0x207, 0x62e, 0x645, 0x207, 0x633, 0x62c, 0x207, 0x633, - 0x62d, 0x207, 0x633, 0x62e, 0x207, 0x633, 0x645, 0x207, - 0x635, 0x62d, 0x207, 0x635, 0x645, 0x207, 0x636, 0x62c, - 0x207, 0x636, 0x62d, 0x207, 0x636, 0x62e, 0x207, 0x636, - 0x645, 0x207, 0x637, 0x62d, 0x207, 0x637, 0x645, 0x207, - 0x638, 0x645, 0x207, 0x639, 0x62c, 0x207, 0x639, 0x645, - 0x207, 0x63a, 0x62c, 0x207, 0x63a, 0x645, 0x207, 0x641, - 0x62c, 0x207, 0x641, 0x62d, 0x207, 0x641, 0x62e, 0x207, - 0x641, 0x645, 0x207, 0x641, 0x649, 0x207, 0x641, 0x64a, - 0x207, 0x642, 0x62d, 0x207, 0x642, 0x645, 0x207, 0x642, - 0x649, 0x207, 0x642, 0x64a, 0x207, 0x643, 0x627, 0x207, - 0x643, 0x62c, 0x207, 0x643, 0x62d, 0x207, 0x643, 0x62e, - 0x207, 0x643, 0x644, 0x207, 0x643, 0x645, 0x207, 0x643, - 0x649, 0x207, 0x643, 0x64a, 0x207, 0x644, 0x62c, 0x207, - 0x644, 0x62d, 0x207, 0x644, 0x62e, 0x207, 0x644, 0x645, - 0x207, 0x644, 0x649, 0x207, 0x644, 0x64a, 0x207, 0x645, - 0x62c, 0x207, 0x645, 0x62d, 0x207, 0x645, 0x62e, 0x207, - 0x645, 0x645, 0x207, 0x645, 0x649, 0x207, 0x645, 0x64a, - 0x207, 0x646, 0x62c, 0x207, 0x646, 0x62d, 0x207, 0x646, - 0x62e, 0x207, 0x646, 0x645, 0x207, 0x646, 0x649, 0x207, - 0x646, 0x64a, 0x207, 0x647, 0x62c, 0x207, 0x647, 0x645, - 0x207, 0x647, 0x649, 0x207, 0x647, 0x64a, 0x207, 0x64a, - 0x62c, 0x207, 0x64a, 0x62d, 0x207, 0x64a, 0x62e, 0x207, - 0x64a, 0x645, 0x207, 0x64a, 0x649, 0x207, 0x64a, 0x64a, - 0x207, 0x630, 0x670, 0x207, 0x631, 0x670, 0x207, 0x649, - 0x670, 0x307, 0x20, 0x64c, 0x651, 0x307, 0x20, 0x64d, - 0x651, 0x307, 0x20, 0x64e, 0x651, 0x307, 0x20, 0x64f, - 0x651, 0x307, 0x20, 0x650, 0x651, 0x307, 0x20, 0x651, - 0x670, 0x206, 0x626, 0x631, 0x206, 0x626, 0x632, 0x206, - 0x626, 0x645, 0x206, 0x626, 0x646, 0x206, 0x626, 0x649, - 0x206, 0x626, 0x64a, 0x206, 0x628, 0x631, 0x206, 0x628, - 0x632, 0x206, 0x628, 0x645, 0x206, 0x628, 0x646, 0x206, - 0x628, 0x649, 0x206, 0x628, 0x64a, 0x206, 0x62a, 0x631, - 0x206, 0x62a, 0x632, 0x206, 0x62a, 0x645, 0x206, 0x62a, - 0x646, 0x206, 0x62a, 0x649, 0x206, 0x62a, 0x64a, 0x206, - 0x62b, 0x631, 0x206, 0x62b, 0x632, 0x206, 0x62b, 0x645, - 0x206, 0x62b, 0x646, 0x206, 0x62b, 0x649, 0x206, 0x62b, - 0x64a, 0x206, 0x641, 0x649, 0x206, 0x641, 0x64a, 0x206, - 0x642, 0x649, 0x206, 0x642, 0x64a, 0x206, 0x643, 0x627, - 0x206, 0x643, 0x644, 0x206, 0x643, 0x645, 0x206, 0x643, - 0x649, 0x206, 0x643, 0x64a, 0x206, 0x644, 0x645, 0x206, - 0x644, 0x649, 0x206, 0x644, 0x64a, 0x206, 0x645, 0x627, - 0x206, 0x645, 0x645, 0x206, 0x646, 0x631, 0x206, 0x646, - 0x632, 0x206, 0x646, 0x645, 0x206, 0x646, 0x646, 0x206, - 0x646, 0x649, 0x206, 0x646, 0x64a, 0x206, 0x649, 0x670, - 0x206, 0x64a, 0x631, 0x206, 0x64a, 0x632, 0x206, 0x64a, - 0x645, 0x206, 0x64a, 0x646, 0x206, 0x64a, 0x649, 0x206, - 0x64a, 0x64a, 0x204, 0x626, 0x62c, 0x204, 0x626, 0x62d, - 0x204, 0x626, 0x62e, 0x204, 0x626, 0x645, 0x204, 0x626, - 0x647, 0x204, 0x628, 0x62c, 0x204, 0x628, 0x62d, 0x204, - 0x628, 0x62e, 0x204, 0x628, 0x645, 0x204, 0x628, 0x647, - 0x204, 0x62a, 0x62c, 0x204, 0x62a, 0x62d, 0x204, 0x62a, - 0x62e, 0x204, 0x62a, 0x645, 0x204, 0x62a, 0x647, 0x204, - 0x62b, 0x645, 0x204, 0x62c, 0x62d, 0x204, 0x62c, 0x645, - 0x204, 0x62d, 0x62c, 0x204, 0x62d, 0x645, 0x204, 0x62e, - 0x62c, 0x204, 0x62e, 0x645, 0x204, 0x633, 0x62c, 0x204, - 0x633, 0x62d, 0x204, 0x633, 0x62e, 0x204, 0x633, 0x645, - 0x204, 0x635, 0x62d, 0x204, 0x635, 0x62e, 0x204, 0x635, - 0x645, 0x204, 0x636, 0x62c, 0x204, 0x636, 0x62d, 0x204, - 0x636, 0x62e, 0x204, 0x636, 0x645, 0x204, 0x637, 0x62d, - 0x204, 0x638, 0x645, 0x204, 0x639, 0x62c, 0x204, 0x639, - 0x645, 0x204, 0x63a, 0x62c, 0x204, 0x63a, 0x645, 0x204, - 0x641, 0x62c, 0x204, 0x641, 0x62d, 0x204, 0x641, 0x62e, - 0x204, 0x641, 0x645, 0x204, 0x642, 0x62d, 0x204, 0x642, - 0x645, 0x204, 0x643, 0x62c, 0x204, 0x643, 0x62d, 0x204, - 0x643, 0x62e, 0x204, 0x643, 0x644, 0x204, 0x643, 0x645, - 0x204, 0x644, 0x62c, 0x204, 0x644, 0x62d, 0x204, 0x644, - 0x62e, 0x204, 0x644, 0x645, 0x204, 0x644, 0x647, 0x204, - 0x645, 0x62c, 0x204, 0x645, 0x62d, 0x204, 0x645, 0x62e, - 0x204, 0x645, 0x645, 0x204, 0x646, 0x62c, 0x204, 0x646, - 0x62d, 0x204, 0x646, 0x62e, 0x204, 0x646, 0x645, 0x204, - 0x646, 0x647, 0x204, 0x647, 0x62c, 0x204, 0x647, 0x645, - 0x204, 0x647, 0x670, 0x204, 0x64a, 0x62c, 0x204, 0x64a, - 0x62d, 0x204, 0x64a, 0x62e, 0x204, 0x64a, 0x645, 0x204, - 0x64a, 0x647, 0x205, 0x626, 0x645, 0x205, 0x626, 0x647, - 0x205, 0x628, 0x645, 0x205, 0x628, 0x647, 0x205, 0x62a, - 0x645, 0x205, 0x62a, 0x647, 0x205, 0x62b, 0x645, 0x205, - 0x62b, 0x647, 0x205, 0x633, 0x645, 0x205, 0x633, 0x647, - 0x205, 0x634, 0x645, 0x205, 0x634, 0x647, 0x205, 0x643, - 0x644, 0x205, 0x643, 0x645, 0x205, 0x644, 0x645, 0x205, - 0x646, 0x645, 0x205, 0x646, 0x647, 0x205, 0x64a, 0x645, - 0x205, 0x64a, 0x647, 0x305, 0x640, 0x64e, 0x651, 0x305, - 0x640, 0x64f, 0x651, 0x305, 0x640, 0x650, 0x651, 0x207, - 0x637, 0x649, 0x207, 0x637, 0x64a, 0x207, 0x639, 0x649, - 0x207, 0x639, 0x64a, 0x207, 0x63a, 0x649, 0x207, 0x63a, - 0x64a, 0x207, 0x633, 0x649, 0x207, 0x633, 0x64a, 0x207, - 0x634, 0x649, 0x207, 0x634, 0x64a, 0x207, 0x62d, 0x649, - 0x207, 0x62d, 0x64a, 0x207, 0x62c, 0x649, 0x207, 0x62c, - 0x64a, 0x207, 0x62e, 0x649, 0x207, 0x62e, 0x64a, 0x207, - 0x635, 0x649, 0x207, 0x635, 0x64a, 0x207, 0x636, 0x649, - 0x207, 0x636, 0x64a, 0x207, 0x634, 0x62c, 0x207, 0x634, - 0x62d, 0x207, 0x634, 0x62e, 0x207, 0x634, 0x645, 0x207, - 0x634, 0x631, 0x207, 0x633, 0x631, 0x207, 0x635, 0x631, - 0x207, 0x636, 0x631, 0x206, 0x637, 0x649, 0x206, 0x637, - 0x64a, 0x206, 0x639, 0x649, 0x206, 0x639, 0x64a, 0x206, - 0x63a, 0x649, 0x206, 0x63a, 0x64a, 0x206, 0x633, 0x649, - 0x206, 0x633, 0x64a, 0x206, 0x634, 0x649, 0x206, 0x634, - 0x64a, 0x206, 0x62d, 0x649, 0x206, 0x62d, 0x64a, 0x206, - 0x62c, 0x649, 0x206, 0x62c, 0x64a, 0x206, 0x62e, 0x649, - 0x206, 0x62e, 0x64a, 0x206, 0x635, 0x649, 0x206, 0x635, - 0x64a, 0x206, 0x636, 0x649, 0x206, 0x636, 0x64a, 0x206, - 0x634, 0x62c, 0x206, 0x634, 0x62d, 0x206, 0x634, 0x62e, - 0x206, 0x634, 0x645, 0x206, 0x634, 0x631, 0x206, 0x633, - 0x631, 0x206, 0x635, 0x631, 0x206, 0x636, 0x631, 0x204, - 0x634, 0x62c, 0x204, 0x634, 0x62d, 0x204, 0x634, 0x62e, - 0x204, 0x634, 0x645, 0x204, 0x633, 0x647, 0x204, 0x634, - 0x647, 0x204, 0x637, 0x645, 0x205, 0x633, 0x62c, 0x205, - 0x633, 0x62d, 0x205, 0x633, 0x62e, 0x205, 0x634, 0x62c, - 0x205, 0x634, 0x62d, 0x205, 0x634, 0x62e, 0x205, 0x637, - 0x645, 0x205, 0x638, 0x645, 0x206, 0x627, 0x64b, 0x207, - 0x627, 0x64b, 0x304, 0x62a, 0x62c, 0x645, 0x306, 0x62a, - 0x62d, 0x62c, 0x304, 0x62a, 0x62d, 0x62c, 0x304, 0x62a, - 0x62d, 0x645, 0x304, 0x62a, 0x62e, 0x645, 0x304, 0x62a, - 0x645, 0x62c, 0x304, 0x62a, 0x645, 0x62d, 0x304, 0x62a, - 0x645, 0x62e, 0x306, 0x62c, 0x645, 0x62d, 0x304, 0x62c, - 0x645, 0x62d, 0x306, 0x62d, 0x645, 0x64a, 0x306, 0x62d, - 0x645, 0x649, 0x304, 0x633, 0x62d, 0x62c, 0x304, 0x633, - 0x62c, 0x62d, 0x306, 0x633, 0x62c, 0x649, 0x306, 0x633, - 0x645, 0x62d, 0x304, 0x633, 0x645, 0x62d, 0x304, 0x633, - 0x645, 0x62c, 0x306, 0x633, 0x645, 0x645, 0x304, 0x633, - 0x645, 0x645, 0x306, 0x635, 0x62d, 0x62d, 0x304, 0x635, - 0x62d, 0x62d, 0x306, 0x635, 0x645, 0x645, 0x306, 0x634, - 0x62d, 0x645, 0x304, 0x634, 0x62d, 0x645, 0x306, 0x634, - 0x62c, 0x64a, 0x306, 0x634, 0x645, 0x62e, 0x304, 0x634, - 0x645, 0x62e, 0x306, 0x634, 0x645, 0x645, 0x304, 0x634, - 0x645, 0x645, 0x306, 0x636, 0x62d, 0x649, 0x306, 0x636, - 0x62e, 0x645, 0x304, 0x636, 0x62e, 0x645, 0x306, 0x637, - 0x645, 0x62d, 0x304, 0x637, 0x645, 0x62d, 0x304, 0x637, - 0x645, 0x645, 0x306, 0x637, 0x645, 0x64a, 0x306, 0x639, - 0x62c, 0x645, 0x306, 0x639, 0x645, 0x645, 0x304, 0x639, - 0x645, 0x645, 0x306, 0x639, 0x645, 0x649, 0x306, 0x63a, - 0x645, 0x645, 0x306, 0x63a, 0x645, 0x64a, 0x306, 0x63a, - 0x645, 0x649, 0x306, 0x641, 0x62e, 0x645, 0x304, 0x641, - 0x62e, 0x645, 0x306, 0x642, 0x645, 0x62d, 0x306, 0x642, - 0x645, 0x645, 0x306, 0x644, 0x62d, 0x645, 0x306, 0x644, - 0x62d, 0x64a, 0x306, 0x644, 0x62d, 0x649, 0x304, 0x644, - 0x62c, 0x62c, 0x306, 0x644, 0x62c, 0x62c, 0x306, 0x644, - 0x62e, 0x645, 0x304, 0x644, 0x62e, 0x645, 0x306, 0x644, - 0x645, 0x62d, 0x304, 0x644, 0x645, 0x62d, 0x304, 0x645, - 0x62d, 0x62c, 0x304, 0x645, 0x62d, 0x645, 0x306, 0x645, - 0x62d, 0x64a, 0x304, 0x645, 0x62c, 0x62d, 0x304, 0x645, - 0x62c, 0x645, 0x304, 0x645, 0x62e, 0x62c, 0x304, 0x645, - 0x62e, 0x645, 0x304, 0x645, 0x62c, 0x62e, 0x304, 0x647, - 0x645, 0x62c, 0x304, 0x647, 0x645, 0x645, 0x304, 0x646, - 0x62d, 0x645, 0x306, 0x646, 0x62d, 0x649, 0x306, 0x646, - 0x62c, 0x645, 0x304, 0x646, 0x62c, 0x645, 0x306, 0x646, - 0x62c, 0x649, 0x306, 0x646, 0x645, 0x64a, 0x306, 0x646, - 0x645, 0x649, 0x306, 0x64a, 0x645, 0x645, 0x304, 0x64a, - 0x645, 0x645, 0x306, 0x628, 0x62e, 0x64a, 0x306, 0x62a, - 0x62c, 0x64a, 0x306, 0x62a, 0x62c, 0x649, 0x306, 0x62a, - 0x62e, 0x64a, 0x306, 0x62a, 0x62e, 0x649, 0x306, 0x62a, - 0x645, 0x64a, 0x306, 0x62a, 0x645, 0x649, 0x306, 0x62c, - 0x645, 0x64a, 0x306, 0x62c, 0x62d, 0x649, 0x306, 0x62c, - 0x645, 0x649, 0x306, 0x633, 0x62e, 0x649, 0x306, 0x635, - 0x62d, 0x64a, 0x306, 0x634, 0x62d, 0x64a, 0x306, 0x636, - 0x62d, 0x64a, 0x306, 0x644, 0x62c, 0x64a, 0x306, 0x644, - 0x645, 0x64a, 0x306, 0x64a, 0x62d, 0x64a, 0x306, 0x64a, - 0x62c, 0x64a, 0x306, 0x64a, 0x645, 0x64a, 0x306, 0x645, - 0x645, 0x64a, 0x306, 0x642, 0x645, 0x64a, 0x306, 0x646, - 0x62d, 0x64a, 0x304, 0x642, 0x645, 0x62d, 0x304, 0x644, - 0x62d, 0x645, 0x306, 0x639, 0x645, 0x64a, 0x306, 0x643, - 0x645, 0x64a, 0x304, 0x646, 0x62c, 0x62d, 0x306, 0x645, - 0x62e, 0x64a, 0x304, 0x644, 0x62c, 0x645, 0x306, 0x643, - 0x645, 0x645, 0x306, 0x644, 0x62c, 0x645, 0x306, 0x646, - 0x62c, 0x62d, 0x306, 0x62c, 0x62d, 0x64a, 0x306, 0x62d, - 0x62c, 0x64a, 0x306, 0x645, 0x62c, 0x64a, 0x306, 0x641, - 0x645, 0x64a, 0x306, 0x628, 0x62d, 0x64a, 0x304, 0x643, - 0x645, 0x645, 0x304, 0x639, 0x62c, 0x645, 0x304, 0x635, - 0x645, 0x645, 0x306, 0x633, 0x62e, 0x64a, 0x306, 0x646, - 0x62c, 0x64a, 0x307, 0x635, 0x644, 0x6d2, 0x307, 0x642, - 0x644, 0x6d2, 0x407, 0x627, 0x644, 0x644, 0x647, 0x407, - 0x627, 0x643, 0x628, 0x631, 0x407, 0x645, 0x62d, 0x645, - 0x62f, 0x407, 0x635, 0x644, 0x639, 0x645, 0x407, 0x631, - 0x633, 0x648, 0x644, 0x407, 0x639, 0x644, 0x64a, 0x647, - 0x407, 0x648, 0x633, 0x644, 0x645, 0x307, 0x635, 0x644, - 0x649, 0x1207, 0x635, 0x644, 0x649, 0x20, 0x627, 0x644, - 0x644, 0x647, 0x20, 0x639, 0x644, 0x64a, 0x647, 0x20, - 0x648, 0x633, 0x644, 0x645, 0x807, 0x62c, 0x644, 0x20, - 0x62c, 0x644, 0x627, 0x644, 0x647, 0x407, 0x631, 0x6cc, - 0x627, 0x644, 0x10b, 0x2c, 0x10b, 0x3001, 0x10b, 0x3002, - 0x10b, 0x3a, 0x10b, 0x3b, 0x10b, 0x21, 0x10b, 0x3f, - 0x10b, 0x3016, 0x10b, 0x3017, 0x10b, 0x2026, 0x10b, 0x2025, - 0x10b, 0x2014, 0x10b, 0x2013, 0x10b, 0x5f, 0x10b, 0x5f, - 0x10b, 0x28, 0x10b, 0x29, 0x10b, 0x7b, 0x10b, 0x7d, - 0x10b, 0x3014, 0x10b, 0x3015, 0x10b, 0x3010, 0x10b, 0x3011, - 0x10b, 0x300a, 0x10b, 0x300b, 0x10b, 0x3008, 0x10b, 0x3009, - 0x10b, 0x300c, 0x10b, 0x300d, 0x10b, 0x300e, 0x10b, 0x300f, - 0x10b, 0x5b, 0x10b, 0x5d, 0x110, 0x203e, 0x110, 0x203e, - 0x110, 0x203e, 0x110, 0x203e, 0x110, 0x5f, 0x110, 0x5f, - 0x110, 0x5f, 0x10e, 0x2c, 0x10e, 0x3001, 0x10e, 0x2e, - 0x10e, 0x3b, 0x10e, 0x3a, 0x10e, 0x3f, 0x10e, 0x21, - 0x10e, 0x2014, 0x10e, 0x28, 0x10e, 0x29, 0x10e, 0x7b, - 0x10e, 0x7d, 0x10e, 0x3014, 0x10e, 0x3015, 0x10e, 0x23, - 0x10e, 0x26, 0x10e, 0x2a, 0x10e, 0x2b, 0x10e, 0x2d, - 0x10e, 0x3c, 0x10e, 0x3e, 0x10e, 0x3d, 0x10e, 0x5c, - 0x10e, 0x24, 0x10e, 0x25, 0x10e, 0x40, 0x207, 0x20, - 0x64b, 0x205, 0x640, 0x64b, 0x207, 0x20, 0x64c, 0x207, - 0x20, 0x64d, 0x207, 0x20, 0x64e, 0x205, 0x640, 0x64e, - 0x207, 0x20, 0x64f, 0x205, 0x640, 0x64f, 0x207, 0x20, - 0x650, 0x205, 0x640, 0x650, 0x207, 0x20, 0x651, 0x205, - 0x640, 0x651, 0x207, 0x20, 0x652, 0x205, 0x640, 0x652, - 0x107, 0x621, 0x107, 0x622, 0x106, 0x622, 0x107, 0x623, - 0x106, 0x623, 0x107, 0x624, 0x106, 0x624, 0x107, 0x625, - 0x106, 0x625, 0x107, 0x626, 0x106, 0x626, 0x104, 0x626, - 0x105, 0x626, 0x107, 0x627, 0x106, 0x627, 0x107, 0x628, - 0x106, 0x628, 0x104, 0x628, 0x105, 0x628, 0x107, 0x629, - 0x106, 0x629, 0x107, 0x62a, 0x106, 0x62a, 0x104, 0x62a, - 0x105, 0x62a, 0x107, 0x62b, 0x106, 0x62b, 0x104, 0x62b, - 0x105, 0x62b, 0x107, 0x62c, 0x106, 0x62c, 0x104, 0x62c, - 0x105, 0x62c, 0x107, 0x62d, 0x106, 0x62d, 0x104, 0x62d, - 0x105, 0x62d, 0x107, 0x62e, 0x106, 0x62e, 0x104, 0x62e, - 0x105, 0x62e, 0x107, 0x62f, 0x106, 0x62f, 0x107, 0x630, - 0x106, 0x630, 0x107, 0x631, 0x106, 0x631, 0x107, 0x632, - 0x106, 0x632, 0x107, 0x633, 0x106, 0x633, 0x104, 0x633, - 0x105, 0x633, 0x107, 0x634, 0x106, 0x634, 0x104, 0x634, - 0x105, 0x634, 0x107, 0x635, 0x106, 0x635, 0x104, 0x635, - 0x105, 0x635, 0x107, 0x636, 0x106, 0x636, 0x104, 0x636, - 0x105, 0x636, 0x107, 0x637, 0x106, 0x637, 0x104, 0x637, - 0x105, 0x637, 0x107, 0x638, 0x106, 0x638, 0x104, 0x638, - 0x105, 0x638, 0x107, 0x639, 0x106, 0x639, 0x104, 0x639, - 0x105, 0x639, 0x107, 0x63a, 0x106, 0x63a, 0x104, 0x63a, - 0x105, 0x63a, 0x107, 0x641, 0x106, 0x641, 0x104, 0x641, - 0x105, 0x641, 0x107, 0x642, 0x106, 0x642, 0x104, 0x642, - 0x105, 0x642, 0x107, 0x643, 0x106, 0x643, 0x104, 0x643, - 0x105, 0x643, 0x107, 0x644, 0x106, 0x644, 0x104, 0x644, - 0x105, 0x644, 0x107, 0x645, 0x106, 0x645, 0x104, 0x645, - 0x105, 0x645, 0x107, 0x646, 0x106, 0x646, 0x104, 0x646, - 0x105, 0x646, 0x107, 0x647, 0x106, 0x647, 0x104, 0x647, - 0x105, 0x647, 0x107, 0x648, 0x106, 0x648, 0x107, 0x649, - 0x106, 0x649, 0x107, 0x64a, 0x106, 0x64a, 0x104, 0x64a, - 0x105, 0x64a, 0x207, 0x644, 0x622, 0x206, 0x644, 0x622, - 0x207, 0x644, 0x623, 0x206, 0x644, 0x623, 0x207, 0x644, - 0x625, 0x206, 0x644, 0x625, 0x207, 0x644, 0x627, 0x206, - 0x644, 0x627, 0x10c, 0x21, 0x10c, 0x22, 0x10c, 0x23, - 0x10c, 0x24, 0x10c, 0x25, 0x10c, 0x26, 0x10c, 0x27, - 0x10c, 0x28, 0x10c, 0x29, 0x10c, 0x2a, 0x10c, 0x2b, - 0x10c, 0x2c, 0x10c, 0x2d, 0x10c, 0x2e, 0x10c, 0x2f, - 0x10c, 0x30, 0x10c, 0x31, 0x10c, 0x32, 0x10c, 0x33, - 0x10c, 0x34, 0x10c, 0x35, 0x10c, 0x36, 0x10c, 0x37, - 0x10c, 0x38, 0x10c, 0x39, 0x10c, 0x3a, 0x10c, 0x3b, - 0x10c, 0x3c, 0x10c, 0x3d, 0x10c, 0x3e, 0x10c, 0x3f, - 0x10c, 0x40, 0x10c, 0x41, 0x10c, 0x42, 0x10c, 0x43, - 0x10c, 0x44, 0x10c, 0x45, 0x10c, 0x46, 0x10c, 0x47, - 0x10c, 0x48, 0x10c, 0x49, 0x10c, 0x4a, 0x10c, 0x4b, - 0x10c, 0x4c, 0x10c, 0x4d, 0x10c, 0x4e, 0x10c, 0x4f, - 0x10c, 0x50, 0x10c, 0x51, 0x10c, 0x52, 0x10c, 0x53, - 0x10c, 0x54, 0x10c, 0x55, 0x10c, 0x56, 0x10c, 0x57, - 0x10c, 0x58, 0x10c, 0x59, 0x10c, 0x5a, 0x10c, 0x5b, - 0x10c, 0x5c, 0x10c, 0x5d, 0x10c, 0x5e, 0x10c, 0x5f, - 0x10c, 0x60, 0x10c, 0x61, 0x10c, 0x62, 0x10c, 0x63, - 0x10c, 0x64, 0x10c, 0x65, 0x10c, 0x66, 0x10c, 0x67, - 0x10c, 0x68, 0x10c, 0x69, 0x10c, 0x6a, 0x10c, 0x6b, - 0x10c, 0x6c, 0x10c, 0x6d, 0x10c, 0x6e, 0x10c, 0x6f, - 0x10c, 0x70, 0x10c, 0x71, 0x10c, 0x72, 0x10c, 0x73, - 0x10c, 0x74, 0x10c, 0x75, 0x10c, 0x76, 0x10c, 0x77, - 0x10c, 0x78, 0x10c, 0x79, 0x10c, 0x7a, 0x10c, 0x7b, - 0x10c, 0x7c, 0x10c, 0x7d, 0x10c, 0x7e, 0x10c, 0x2985, - 0x10c, 0x2986, 0x10d, 0x3002, 0x10d, 0x300c, 0x10d, 0x300d, - 0x10d, 0x3001, 0x10d, 0x30fb, 0x10d, 0x30f2, 0x10d, 0x30a1, - 0x10d, 0x30a3, 0x10d, 0x30a5, 0x10d, 0x30a7, 0x10d, 0x30a9, - 0x10d, 0x30e3, 0x10d, 0x30e5, 0x10d, 0x30e7, 0x10d, 0x30c3, - 0x10d, 0x30fc, 0x10d, 0x30a2, 0x10d, 0x30a4, 0x10d, 0x30a6, - 0x10d, 0x30a8, 0x10d, 0x30aa, 0x10d, 0x30ab, 0x10d, 0x30ad, - 0x10d, 0x30af, 0x10d, 0x30b1, 0x10d, 0x30b3, 0x10d, 0x30b5, - 0x10d, 0x30b7, 0x10d, 0x30b9, 0x10d, 0x30bb, 0x10d, 0x30bd, - 0x10d, 0x30bf, 0x10d, 0x30c1, 0x10d, 0x30c4, 0x10d, 0x30c6, - 0x10d, 0x30c8, 0x10d, 0x30ca, 0x10d, 0x30cb, 0x10d, 0x30cc, - 0x10d, 0x30cd, 0x10d, 0x30ce, 0x10d, 0x30cf, 0x10d, 0x30d2, - 0x10d, 0x30d5, 0x10d, 0x30d8, 0x10d, 0x30db, 0x10d, 0x30de, - 0x10d, 0x30df, 0x10d, 0x30e0, 0x10d, 0x30e1, 0x10d, 0x30e2, - 0x10d, 0x30e4, 0x10d, 0x30e6, 0x10d, 0x30e8, 0x10d, 0x30e9, - 0x10d, 0x30ea, 0x10d, 0x30eb, 0x10d, 0x30ec, 0x10d, 0x30ed, - 0x10d, 0x30ef, 0x10d, 0x30f3, 0x10d, 0x3099, 0x10d, 0x309a, - 0x10d, 0x3164, 0x10d, 0x3131, 0x10d, 0x3132, 0x10d, 0x3133, - 0x10d, 0x3134, 0x10d, 0x3135, 0x10d, 0x3136, 0x10d, 0x3137, - 0x10d, 0x3138, 0x10d, 0x3139, 0x10d, 0x313a, 0x10d, 0x313b, - 0x10d, 0x313c, 0x10d, 0x313d, 0x10d, 0x313e, 0x10d, 0x313f, - 0x10d, 0x3140, 0x10d, 0x3141, 0x10d, 0x3142, 0x10d, 0x3143, - 0x10d, 0x3144, 0x10d, 0x3145, 0x10d, 0x3146, 0x10d, 0x3147, - 0x10d, 0x3148, 0x10d, 0x3149, 0x10d, 0x314a, 0x10d, 0x314b, - 0x10d, 0x314c, 0x10d, 0x314d, 0x10d, 0x314e, 0x10d, 0x314f, - 0x10d, 0x3150, 0x10d, 0x3151, 0x10d, 0x3152, 0x10d, 0x3153, - 0x10d, 0x3154, 0x10d, 0x3155, 0x10d, 0x3156, 0x10d, 0x3157, - 0x10d, 0x3158, 0x10d, 0x3159, 0x10d, 0x315a, 0x10d, 0x315b, - 0x10d, 0x315c, 0x10d, 0x315d, 0x10d, 0x315e, 0x10d, 0x315f, - 0x10d, 0x3160, 0x10d, 0x3161, 0x10d, 0x3162, 0x10d, 0x3163, - 0x10c, 0xa2, 0x10c, 0xa3, 0x10c, 0xac, 0x10c, 0xaf, - 0x10c, 0xa6, 0x10c, 0xa5, 0x10c, 0x20a9, 0x10d, 0x2502, - 0x10d, 0x2190, 0x10d, 0x2191, 0x10d, 0x2192, 0x10d, 0x2193, - 0x10d, 0x25a0, 0x10d, 0x25cb, 0x401, 0xd834, 0xdd57, 0xd834, - 0xdd65, 0x401, 0xd834, 0xdd58, 0xd834, 0xdd65, 0x401, 0xd834, - 0xdd5f, 0xd834, 0xdd6e, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd6f, - 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd70, 0x401, 0xd834, 0xdd5f, - 0xd834, 0xdd71, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd72, 0x401, - 0xd834, 0xddb9, 0xd834, 0xdd65, 0x401, 0xd834, 0xddba, 0xd834, - 0xdd65, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6e, 0x401, 0xd834, - 0xddbc, 0xd834, 0xdd6e, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6f, - 0x401, 0xd834, 0xddbc, 0xd834, 0xdd6f, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, - 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, - 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, - 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, - 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, - 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, - 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, 0x4a, 0x102, - 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, 0x4e, 0x102, - 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, 0x102, - 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, - 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, - 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, - 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, - 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, - 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, - 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, - 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, - 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x43, 0x102, - 0x44, 0x102, 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, - 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, - 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, - 0x66, 0x102, 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, - 0x6b, 0x102, 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, - 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, - 0x4d, 0x102, 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, - 0x51, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, - 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, - 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, - 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, - 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, - 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, - 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, - 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, 0x47, 0x102, - 0x49, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, - 0x4d, 0x102, 0x4f, 0x102, 0x53, 0x102, 0x54, 0x102, - 0x55, 0x102, 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, - 0x59, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, - 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, - 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, - 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, - 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, - 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, - 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, - 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, - 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, - 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, - 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, - 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, - 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, - 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x131, 0x102, - 0x237, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, - 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, - 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, - 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, - 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, - 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, - 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, - 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, - 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, - 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, - 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, - 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, - 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, - 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, - 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, - 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, - 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, - 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, - 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, - 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, - 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, - 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, - 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, - 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, - 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, - 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, - 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, - 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, - 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, - 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, - 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, - 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, - 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, - 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, - 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, - 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, - 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, - 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, - 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, - 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, - 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, - 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, - 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, - 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, - 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, - 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, - 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, - 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, - 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, - 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, - 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, - 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, - 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, - 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, - 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, - 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, - 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, - 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, - 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, - 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, - 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, - 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, - 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, - 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, - 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, - 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, - 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, - 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, - 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, - 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, - 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, - 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, - 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x3dc, 0x102, - 0x3dd, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, - 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, - 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, - 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, - 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, - 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, - 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, - 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, - 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, - 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, - 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, - 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, - 0x37, 0x102, 0x38, 0x102, 0x39, 0x101, 0x4e3d, 0x101, - 0x4e38, 0x101, 0x4e41, 0x201, 0xd840, 0xdd22, 0x101, 0x4f60, - 0x101, 0x4fae, 0x101, 0x4fbb, 0x101, 0x5002, 0x101, 0x507a, - 0x101, 0x5099, 0x101, 0x50e7, 0x101, 0x50cf, 0x101, 0x349e, - 0x201, 0xd841, 0xde3a, 0x101, 0x514d, 0x101, 0x5154, 0x101, - 0x5164, 0x101, 0x5177, 0x201, 0xd841, 0xdd1c, 0x101, 0x34b9, - 0x101, 0x5167, 0x101, 0x518d, 0x201, 0xd841, 0xdd4b, 0x101, - 0x5197, 0x101, 0x51a4, 0x101, 0x4ecc, 0x101, 0x51ac, 0x101, - 0x51b5, 0x201, 0xd864, 0xdddf, 0x101, 0x51f5, 0x101, 0x5203, - 0x101, 0x34df, 0x101, 0x523b, 0x101, 0x5246, 0x101, 0x5272, - 0x101, 0x5277, 0x101, 0x3515, 0x101, 0x52c7, 0x101, 0x52c9, - 0x101, 0x52e4, 0x101, 0x52fa, 0x101, 0x5305, 0x101, 0x5306, - 0x101, 0x5317, 0x101, 0x5349, 0x101, 0x5351, 0x101, 0x535a, - 0x101, 0x5373, 0x101, 0x537d, 0x101, 0x537f, 0x101, 0x537f, - 0x101, 0x537f, 0x201, 0xd842, 0xde2c, 0x101, 0x7070, 0x101, - 0x53ca, 0x101, 0x53df, 0x201, 0xd842, 0xdf63, 0x101, 0x53eb, - 0x101, 0x53f1, 0x101, 0x5406, 0x101, 0x549e, 0x101, 0x5438, - 0x101, 0x5448, 0x101, 0x5468, 0x101, 0x54a2, 0x101, 0x54f6, - 0x101, 0x5510, 0x101, 0x5553, 0x101, 0x5563, 0x101, 0x5584, - 0x101, 0x5584, 0x101, 0x5599, 0x101, 0x55ab, 0x101, 0x55b3, - 0x101, 0x55c2, 0x101, 0x5716, 0x101, 0x5606, 0x101, 0x5717, - 0x101, 0x5651, 0x101, 0x5674, 0x101, 0x5207, 0x101, 0x58ee, - 0x101, 0x57ce, 0x101, 0x57f4, 0x101, 0x580d, 0x101, 0x578b, - 0x101, 0x5832, 0x101, 0x5831, 0x101, 0x58ac, 0x201, 0xd845, - 0xdce4, 0x101, 0x58f2, 0x101, 0x58f7, 0x101, 0x5906, 0x101, - 0x591a, 0x101, 0x5922, 0x101, 0x5962, 0x201, 0xd845, 0xdea8, - 0x201, 0xd845, 0xdeea, 0x101, 0x59ec, 0x101, 0x5a1b, 0x101, - 0x5a27, 0x101, 0x59d8, 0x101, 0x5a66, 0x101, 0x36ee, 0x101, - 0x36fc, 0x101, 0x5b08, 0x101, 0x5b3e, 0x101, 0x5b3e, 0x201, - 0xd846, 0xddc8, 0x101, 0x5bc3, 0x101, 0x5bd8, 0x101, 0x5be7, - 0x101, 0x5bf3, 0x201, 0xd846, 0xdf18, 0x101, 0x5bff, 0x101, - 0x5c06, 0x101, 0x5f53, 0x101, 0x5c22, 0x101, 0x3781, 0x101, - 0x5c60, 0x101, 0x5c6e, 0x101, 0x5cc0, 0x101, 0x5c8d, 0x201, - 0xd847, 0xdde4, 0x101, 0x5d43, 0x201, 0xd847, 0xdde6, 0x101, - 0x5d6e, 0x101, 0x5d6b, 0x101, 0x5d7c, 0x101, 0x5de1, 0x101, - 0x5de2, 0x101, 0x382f, 0x101, 0x5dfd, 0x101, 0x5e28, 0x101, - 0x5e3d, 0x101, 0x5e69, 0x101, 0x3862, 0x201, 0xd848, 0xdd83, - 0x101, 0x387c, 0x101, 0x5eb0, 0x101, 0x5eb3, 0x101, 0x5eb6, - 0x101, 0x5eca, 0x201, 0xd868, 0xdf92, 0x101, 0x5efe, 0x201, - 0xd848, 0xdf31, 0x201, 0xd848, 0xdf31, 0x101, 0x8201, 0x101, - 0x5f22, 0x101, 0x5f22, 0x101, 0x38c7, 0x201, 0xd84c, 0xdeb8, - 0x201, 0xd858, 0xddda, 0x101, 0x5f62, 0x101, 0x5f6b, 0x101, - 0x38e3, 0x101, 0x5f9a, 0x101, 0x5fcd, 0x101, 0x5fd7, 0x101, - 0x5ff9, 0x101, 0x6081, 0x101, 0x393a, 0x101, 0x391c, 0x101, - 0x6094, 0x201, 0xd849, 0xded4, 0x101, 0x60c7, 0x101, 0x6148, - 0x101, 0x614c, 0x101, 0x614e, 0x101, 0x614c, 0x101, 0x617a, - 0x101, 0x618e, 0x101, 0x61b2, 0x101, 0x61a4, 0x101, 0x61af, - 0x101, 0x61de, 0x101, 0x61f2, 0x101, 0x61f6, 0x101, 0x6210, - 0x101, 0x621b, 0x101, 0x625d, 0x101, 0x62b1, 0x101, 0x62d4, - 0x101, 0x6350, 0x201, 0xd84a, 0xdf0c, 0x101, 0x633d, 0x101, - 0x62fc, 0x101, 0x6368, 0x101, 0x6383, 0x101, 0x63e4, 0x201, - 0xd84a, 0xdff1, 0x101, 0x6422, 0x101, 0x63c5, 0x101, 0x63a9, - 0x101, 0x3a2e, 0x101, 0x6469, 0x101, 0x647e, 0x101, 0x649d, - 0x101, 0x6477, 0x101, 0x3a6c, 0x101, 0x654f, 0x101, 0x656c, - 0x201, 0xd84c, 0xdc0a, 0x101, 0x65e3, 0x101, 0x66f8, 0x101, - 0x6649, 0x101, 0x3b19, 0x101, 0x6691, 0x101, 0x3b08, 0x101, - 0x3ae4, 0x101, 0x5192, 0x101, 0x5195, 0x101, 0x6700, 0x101, - 0x669c, 0x101, 0x80ad, 0x101, 0x43d9, 0x101, 0x6717, 0x101, - 0x671b, 0x101, 0x6721, 0x101, 0x675e, 0x101, 0x6753, 0x201, - 0xd84c, 0xdfc3, 0x101, 0x3b49, 0x101, 0x67fa, 0x101, 0x6785, - 0x101, 0x6852, 0x101, 0x6885, 0x201, 0xd84d, 0xdc6d, 0x101, - 0x688e, 0x101, 0x681f, 0x101, 0x6914, 0x101, 0x3b9d, 0x101, - 0x6942, 0x101, 0x69a3, 0x101, 0x69ea, 0x101, 0x6aa8, 0x201, - 0xd84d, 0xdea3, 0x101, 0x6adb, 0x101, 0x3c18, 0x101, 0x6b21, - 0x201, 0xd84e, 0xdca7, 0x101, 0x6b54, 0x101, 0x3c4e, 0x101, - 0x6b72, 0x101, 0x6b9f, 0x101, 0x6bba, 0x101, 0x6bbb, 0x201, - 0xd84e, 0xde8d, 0x201, 0xd847, 0xdd0b, 0x201, 0xd84e, 0xdefa, - 0x101, 0x6c4e, 0x201, 0xd84f, 0xdcbc, 0x101, 0x6cbf, 0x101, - 0x6ccd, 0x101, 0x6c67, 0x101, 0x6d16, 0x101, 0x6d3e, 0x101, - 0x6d77, 0x101, 0x6d41, 0x101, 0x6d69, 0x101, 0x6d78, 0x101, - 0x6d85, 0x201, 0xd84f, 0xdd1e, 0x101, 0x6d34, 0x101, 0x6e2f, - 0x101, 0x6e6e, 0x101, 0x3d33, 0x101, 0x6ecb, 0x101, 0x6ec7, - 0x201, 0xd84f, 0xded1, 0x101, 0x6df9, 0x101, 0x6f6e, 0x201, - 0xd84f, 0xdf5e, 0x201, 0xd84f, 0xdf8e, 0x101, 0x6fc6, 0x101, - 0x7039, 0x101, 0x701e, 0x101, 0x701b, 0x101, 0x3d96, 0x101, - 0x704a, 0x101, 0x707d, 0x101, 0x7077, 0x101, 0x70ad, 0x201, - 0xd841, 0xdd25, 0x101, 0x7145, 0x201, 0xd850, 0xde63, 0x101, - 0x719c, 0x201, 0xd850, 0xdfab, 0x101, 0x7228, 0x101, 0x7235, - 0x101, 0x7250, 0x201, 0xd851, 0xde08, 0x101, 0x7280, 0x101, - 0x7295, 0x201, 0xd851, 0xdf35, 0x201, 0xd852, 0xdc14, 0x101, - 0x737a, 0x101, 0x738b, 0x101, 0x3eac, 0x101, 0x73a5, 0x101, - 0x3eb8, 0x101, 0x3eb8, 0x101, 0x7447, 0x101, 0x745c, 0x101, - 0x7471, 0x101, 0x7485, 0x101, 0x74ca, 0x101, 0x3f1b, 0x101, - 0x7524, 0x201, 0xd853, 0xdc36, 0x101, 0x753e, 0x201, 0xd853, - 0xdc92, 0x101, 0x7570, 0x201, 0xd848, 0xdd9f, 0x101, 0x7610, - 0x201, 0xd853, 0xdfa1, 0x201, 0xd853, 0xdfb8, 0x201, 0xd854, - 0xdc44, 0x101, 0x3ffc, 0x101, 0x4008, 0x101, 0x76f4, 0x201, - 0xd854, 0xdcf3, 0x201, 0xd854, 0xdcf2, 0x201, 0xd854, 0xdd19, - 0x201, 0xd854, 0xdd33, 0x101, 0x771e, 0x101, 0x771f, 0x101, - 0x771f, 0x101, 0x774a, 0x101, 0x4039, 0x101, 0x778b, 0x101, - 0x4046, 0x101, 0x4096, 0x201, 0xd855, 0xdc1d, 0x101, 0x784e, - 0x101, 0x788c, 0x101, 0x78cc, 0x101, 0x40e3, 0x201, 0xd855, - 0xde26, 0x101, 0x7956, 0x201, 0xd855, 0xde9a, 0x201, 0xd855, - 0xdec5, 0x101, 0x798f, 0x101, 0x79eb, 0x101, 0x412f, 0x101, - 0x7a40, 0x101, 0x7a4a, 0x101, 0x7a4f, 0x201, 0xd856, 0xdd7c, - 0x201, 0xd856, 0xdea7, 0x201, 0xd856, 0xdea7, 0x101, 0x7aee, - 0x101, 0x4202, 0x201, 0xd856, 0xdfab, 0x101, 0x7bc6, 0x101, - 0x7bc9, 0x101, 0x4227, 0x201, 0xd857, 0xdc80, 0x101, 0x7cd2, - 0x101, 0x42a0, 0x101, 0x7ce8, 0x101, 0x7ce3, 0x101, 0x7d00, - 0x201, 0xd857, 0xdf86, 0x101, 0x7d63, 0x101, 0x4301, 0x101, - 0x7dc7, 0x101, 0x7e02, 0x101, 0x7e45, 0x101, 0x4334, 0x201, - 0xd858, 0xde28, 0x201, 0xd858, 0xde47, 0x101, 0x4359, 0x201, - 0xd858, 0xded9, 0x101, 0x7f7a, 0x201, 0xd858, 0xdf3e, 0x101, - 0x7f95, 0x101, 0x7ffa, 0x101, 0x8005, 0x201, 0xd859, 0xdcda, - 0x201, 0xd859, 0xdd23, 0x101, 0x8060, 0x201, 0xd859, 0xdda8, - 0x101, 0x8070, 0x201, 0xd84c, 0xdf5f, 0x101, 0x43d5, 0x101, - 0x80b2, 0x101, 0x8103, 0x101, 0x440b, 0x101, 0x813e, 0x101, - 0x5ab5, 0x201, 0xd859, 0xdfa7, 0x201, 0xd859, 0xdfb5, 0x201, - 0xd84c, 0xdf93, 0x201, 0xd84c, 0xdf9c, 0x101, 0x8201, 0x101, - 0x8204, 0x101, 0x8f9e, 0x101, 0x446b, 0x101, 0x8291, 0x101, - 0x828b, 0x101, 0x829d, 0x101, 0x52b3, 0x101, 0x82b1, 0x101, - 0x82b3, 0x101, 0x82bd, 0x101, 0x82e6, 0x201, 0xd85a, 0xdf3c, - 0x101, 0x82e5, 0x101, 0x831d, 0x101, 0x8363, 0x101, 0x83ad, - 0x101, 0x8323, 0x101, 0x83bd, 0x101, 0x83e7, 0x101, 0x8457, - 0x101, 0x8353, 0x101, 0x83ca, 0x101, 0x83cc, 0x101, 0x83dc, - 0x201, 0xd85b, 0xdc36, 0x201, 0xd85b, 0xdd6b, 0x201, 0xd85b, - 0xdcd5, 0x101, 0x452b, 0x101, 0x84f1, 0x101, 0x84f3, 0x101, - 0x8516, 0x201, 0xd85c, 0xdfca, 0x101, 0x8564, 0x201, 0xd85b, - 0xdf2c, 0x101, 0x455d, 0x101, 0x4561, 0x201, 0xd85b, 0xdfb1, - 0x201, 0xd85c, 0xdcd2, 0x101, 0x456b, 0x101, 0x8650, 0x101, - 0x865c, 0x101, 0x8667, 0x101, 0x8669, 0x101, 0x86a9, 0x101, - 0x8688, 0x101, 0x870e, 0x101, 0x86e2, 0x101, 0x8779, 0x101, - 0x8728, 0x101, 0x876b, 0x101, 0x8786, 0x101, 0x45d7, 0x101, - 0x87e1, 0x101, 0x8801, 0x101, 0x45f9, 0x101, 0x8860, 0x101, - 0x8863, 0x201, 0xd85d, 0xde67, 0x101, 0x88d7, 0x101, 0x88de, - 0x101, 0x4635, 0x101, 0x88fa, 0x101, 0x34bb, 0x201, 0xd85e, - 0xdcae, 0x201, 0xd85e, 0xdd66, 0x101, 0x46be, 0x101, 0x46c7, - 0x101, 0x8aa0, 0x101, 0x8aed, 0x101, 0x8b8a, 0x101, 0x8c55, - 0x201, 0xd85f, 0xdca8, 0x101, 0x8cab, 0x101, 0x8cc1, 0x101, - 0x8d1b, 0x101, 0x8d77, 0x201, 0xd85f, 0xdf2f, 0x201, 0xd842, - 0xdc04, 0x101, 0x8dcb, 0x101, 0x8dbc, 0x101, 0x8df0, 0x201, - 0xd842, 0xdcde, 0x101, 0x8ed4, 0x101, 0x8f38, 0x201, 0xd861, - 0xddd2, 0x201, 0xd861, 0xdded, 0x101, 0x9094, 0x101, 0x90f1, - 0x101, 0x9111, 0x201, 0xd861, 0xdf2e, 0x101, 0x911b, 0x101, - 0x9238, 0x101, 0x92d7, 0x101, 0x92d8, 0x101, 0x927c, 0x101, - 0x93f9, 0x101, 0x9415, 0x201, 0xd862, 0xdffa, 0x101, 0x958b, - 0x101, 0x4995, 0x101, 0x95b7, 0x201, 0xd863, 0xdd77, 0x101, - 0x49e6, 0x101, 0x96c3, 0x101, 0x5db2, 0x101, 0x9723, 0x201, - 0xd864, 0xdd45, 0x201, 0xd864, 0xde1a, 0x101, 0x4a6e, 0x101, - 0x4a76, 0x101, 0x97e0, 0x201, 0xd865, 0xdc0a, 0x101, 0x4ab2, - 0x201, 0xd865, 0xdc96, 0x101, 0x980b, 0x101, 0x980b, 0x101, - 0x9829, 0x201, 0xd865, 0xddb6, 0x101, 0x98e2, 0x101, 0x4b33, - 0x101, 0x9929, 0x101, 0x99a7, 0x101, 0x99c2, 0x101, 0x99fe, - 0x101, 0x4bce, 0x201, 0xd866, 0xdf30, 0x101, 0x9b12, 0x101, - 0x9c40, 0x101, 0x9cfd, 0x101, 0x4cce, 0x101, 0x4ced, 0x101, - 0x9d67, 0x201, 0xd868, 0xdcce, 0x101, 0x4cf8, 0x201, 0xd868, - 0xdd05, 0x201, 0xd868, 0xde0e, 0x201, 0xd868, 0xde91, 0x101, - 0x9ebb, 0x101, 0x4d56, 0x101, 0x9ef9, 0x101, 0x9efe, 0x101, - 0x9f05, 0x101, 0x9f0f, 0x101, 0x9f16, 0x101, 0x9f3b, 0x201, - 0xd869, 0xde00, + 0x103, 0x20, 0x210, 0x20, 0x308, 0x109, 0x61, 0x210, + 0x20, 0x304, 0x109, 0x32, 0x109, 0x33, 0x210, 0x20, + 0x301, 0x110, 0x3bc, 0x210, 0x20, 0x327, 0x109, 0x31, + 0x109, 0x6f, 0x311, 0x31, 0x2044, 0x34, 0x311, 0x31, + 0x2044, 0x32, 0x311, 0x33, 0x2044, 0x34, 0x201, 0x41, + 0x300, 0x201, 0x41, 0x301, 0x201, 0x41, 0x302, 0x201, + 0x41, 0x303, 0x201, 0x41, 0x308, 0x201, 0x41, 0x30a, + 0x201, 0x43, 0x327, 0x201, 0x45, 0x300, 0x201, 0x45, + 0x301, 0x201, 0x45, 0x302, 0x201, 0x45, 0x308, 0x201, + 0x49, 0x300, 0x201, 0x49, 0x301, 0x201, 0x49, 0x302, + 0x201, 0x49, 0x308, 0x201, 0x4e, 0x303, 0x201, 0x4f, + 0x300, 0x201, 0x4f, 0x301, 0x201, 0x4f, 0x302, 0x201, + 0x4f, 0x303, 0x201, 0x4f, 0x308, 0x201, 0x55, 0x300, + 0x201, 0x55, 0x301, 0x201, 0x55, 0x302, 0x201, 0x55, + 0x308, 0x201, 0x59, 0x301, 0x201, 0x61, 0x300, 0x201, + 0x61, 0x301, 0x201, 0x61, 0x302, 0x201, 0x61, 0x303, + 0x201, 0x61, 0x308, 0x201, 0x61, 0x30a, 0x201, 0x63, + 0x327, 0x201, 0x65, 0x300, 0x201, 0x65, 0x301, 0x201, + 0x65, 0x302, 0x201, 0x65, 0x308, 0x201, 0x69, 0x300, + 0x201, 0x69, 0x301, 0x201, 0x69, 0x302, 0x201, 0x69, + 0x308, 0x201, 0x6e, 0x303, 0x201, 0x6f, 0x300, 0x201, + 0x6f, 0x301, 0x201, 0x6f, 0x302, 0x201, 0x6f, 0x303, + 0x201, 0x6f, 0x308, 0x201, 0x75, 0x300, 0x201, 0x75, + 0x301, 0x201, 0x75, 0x302, 0x201, 0x75, 0x308, 0x201, + 0x79, 0x301, 0x201, 0x79, 0x308, 0x201, 0x41, 0x304, + 0x201, 0x61, 0x304, 0x201, 0x41, 0x306, 0x201, 0x61, + 0x306, 0x201, 0x41, 0x328, 0x201, 0x61, 0x328, 0x201, + 0x43, 0x301, 0x201, 0x63, 0x301, 0x201, 0x43, 0x302, + 0x201, 0x63, 0x302, 0x201, 0x43, 0x307, 0x201, 0x63, + 0x307, 0x201, 0x43, 0x30c, 0x201, 0x63, 0x30c, 0x201, + 0x44, 0x30c, 0x201, 0x64, 0x30c, 0x201, 0x45, 0x304, + 0x201, 0x65, 0x304, 0x201, 0x45, 0x306, 0x201, 0x65, + 0x306, 0x201, 0x45, 0x307, 0x201, 0x65, 0x307, 0x201, + 0x45, 0x328, 0x201, 0x65, 0x328, 0x201, 0x45, 0x30c, + 0x201, 0x65, 0x30c, 0x201, 0x47, 0x302, 0x201, 0x67, + 0x302, 0x201, 0x47, 0x306, 0x201, 0x67, 0x306, 0x201, + 0x47, 0x307, 0x201, 0x67, 0x307, 0x201, 0x47, 0x327, + 0x201, 0x67, 0x327, 0x201, 0x48, 0x302, 0x201, 0x68, + 0x302, 0x201, 0x49, 0x303, 0x201, 0x69, 0x303, 0x201, + 0x49, 0x304, 0x201, 0x69, 0x304, 0x201, 0x49, 0x306, + 0x201, 0x69, 0x306, 0x201, 0x49, 0x328, 0x201, 0x69, + 0x328, 0x201, 0x49, 0x307, 0x210, 0x49, 0x4a, 0x210, + 0x69, 0x6a, 0x201, 0x4a, 0x302, 0x201, 0x6a, 0x302, + 0x201, 0x4b, 0x327, 0x201, 0x6b, 0x327, 0x201, 0x4c, + 0x301, 0x201, 0x6c, 0x301, 0x201, 0x4c, 0x327, 0x201, + 0x6c, 0x327, 0x201, 0x4c, 0x30c, 0x201, 0x6c, 0x30c, + 0x210, 0x4c, 0xb7, 0x210, 0x6c, 0xb7, 0x201, 0x4e, + 0x301, 0x201, 0x6e, 0x301, 0x201, 0x4e, 0x327, 0x201, + 0x6e, 0x327, 0x201, 0x4e, 0x30c, 0x201, 0x6e, 0x30c, + 0x210, 0x2bc, 0x6e, 0x201, 0x4f, 0x304, 0x201, 0x6f, + 0x304, 0x201, 0x4f, 0x306, 0x201, 0x6f, 0x306, 0x201, + 0x4f, 0x30b, 0x201, 0x6f, 0x30b, 0x201, 0x52, 0x301, + 0x201, 0x72, 0x301, 0x201, 0x52, 0x327, 0x201, 0x72, + 0x327, 0x201, 0x52, 0x30c, 0x201, 0x72, 0x30c, 0x201, + 0x53, 0x301, 0x201, 0x73, 0x301, 0x201, 0x53, 0x302, + 0x201, 0x73, 0x302, 0x201, 0x53, 0x327, 0x201, 0x73, + 0x327, 0x201, 0x53, 0x30c, 0x201, 0x73, 0x30c, 0x201, + 0x54, 0x327, 0x201, 0x74, 0x327, 0x201, 0x54, 0x30c, + 0x201, 0x74, 0x30c, 0x201, 0x55, 0x303, 0x201, 0x75, + 0x303, 0x201, 0x55, 0x304, 0x201, 0x75, 0x304, 0x201, + 0x55, 0x306, 0x201, 0x75, 0x306, 0x201, 0x55, 0x30a, + 0x201, 0x75, 0x30a, 0x201, 0x55, 0x30b, 0x201, 0x75, + 0x30b, 0x201, 0x55, 0x328, 0x201, 0x75, 0x328, 0x201, + 0x57, 0x302, 0x201, 0x77, 0x302, 0x201, 0x59, 0x302, + 0x201, 0x79, 0x302, 0x201, 0x59, 0x308, 0x201, 0x5a, + 0x301, 0x201, 0x7a, 0x301, 0x201, 0x5a, 0x307, 0x201, + 0x7a, 0x307, 0x201, 0x5a, 0x30c, 0x201, 0x7a, 0x30c, + 0x110, 0x73, 0x201, 0x4f, 0x31b, 0x201, 0x6f, 0x31b, + 0x201, 0x55, 0x31b, 0x201, 0x75, 0x31b, 0x210, 0x44, + 0x17d, 0x210, 0x44, 0x17e, 0x210, 0x64, 0x17e, 0x210, + 0x4c, 0x4a, 0x210, 0x4c, 0x6a, 0x210, 0x6c, 0x6a, + 0x210, 0x4e, 0x4a, 0x210, 0x4e, 0x6a, 0x210, 0x6e, + 0x6a, 0x201, 0x41, 0x30c, 0x201, 0x61, 0x30c, 0x201, + 0x49, 0x30c, 0x201, 0x69, 0x30c, 0x201, 0x4f, 0x30c, + 0x201, 0x6f, 0x30c, 0x201, 0x55, 0x30c, 0x201, 0x75, + 0x30c, 0x201, 0xdc, 0x304, 0x201, 0xfc, 0x304, 0x201, + 0xdc, 0x301, 0x201, 0xfc, 0x301, 0x201, 0xdc, 0x30c, + 0x201, 0xfc, 0x30c, 0x201, 0xdc, 0x300, 0x201, 0xfc, + 0x300, 0x201, 0xc4, 0x304, 0x201, 0xe4, 0x304, 0x201, + 0x226, 0x304, 0x201, 0x227, 0x304, 0x201, 0xc6, 0x304, + 0x201, 0xe6, 0x304, 0x201, 0x47, 0x30c, 0x201, 0x67, + 0x30c, 0x201, 0x4b, 0x30c, 0x201, 0x6b, 0x30c, 0x201, + 0x4f, 0x328, 0x201, 0x6f, 0x328, 0x201, 0x1ea, 0x304, + 0x201, 0x1eb, 0x304, 0x201, 0x1b7, 0x30c, 0x201, 0x292, + 0x30c, 0x201, 0x6a, 0x30c, 0x210, 0x44, 0x5a, 0x210, + 0x44, 0x7a, 0x210, 0x64, 0x7a, 0x201, 0x47, 0x301, + 0x201, 0x67, 0x301, 0x201, 0x4e, 0x300, 0x201, 0x6e, + 0x300, 0x201, 0xc5, 0x301, 0x201, 0xe5, 0x301, 0x201, + 0xc6, 0x301, 0x201, 0xe6, 0x301, 0x201, 0xd8, 0x301, + 0x201, 0xf8, 0x301, 0x201, 0x41, 0x30f, 0x201, 0x61, + 0x30f, 0x201, 0x41, 0x311, 0x201, 0x61, 0x311, 0x201, + 0x45, 0x30f, 0x201, 0x65, 0x30f, 0x201, 0x45, 0x311, + 0x201, 0x65, 0x311, 0x201, 0x49, 0x30f, 0x201, 0x69, + 0x30f, 0x201, 0x49, 0x311, 0x201, 0x69, 0x311, 0x201, + 0x4f, 0x30f, 0x201, 0x6f, 0x30f, 0x201, 0x4f, 0x311, + 0x201, 0x6f, 0x311, 0x201, 0x52, 0x30f, 0x201, 0x72, + 0x30f, 0x201, 0x52, 0x311, 0x201, 0x72, 0x311, 0x201, + 0x55, 0x30f, 0x201, 0x75, 0x30f, 0x201, 0x55, 0x311, + 0x201, 0x75, 0x311, 0x201, 0x53, 0x326, 0x201, 0x73, + 0x326, 0x201, 0x54, 0x326, 0x201, 0x74, 0x326, 0x201, + 0x48, 0x30c, 0x201, 0x68, 0x30c, 0x201, 0x41, 0x307, + 0x201, 0x61, 0x307, 0x201, 0x45, 0x327, 0x201, 0x65, + 0x327, 0x201, 0xd6, 0x304, 0x201, 0xf6, 0x304, 0x201, + 0xd5, 0x304, 0x201, 0xf5, 0x304, 0x201, 0x4f, 0x307, + 0x201, 0x6f, 0x307, 0x201, 0x22e, 0x304, 0x201, 0x22f, + 0x304, 0x201, 0x59, 0x304, 0x201, 0x79, 0x304, 0x109, + 0x68, 0x109, 0x266, 0x109, 0x6a, 0x109, 0x72, 0x109, + 0x279, 0x109, 0x27b, 0x109, 0x281, 0x109, 0x77, 0x109, + 0x79, 0x210, 0x20, 0x306, 0x210, 0x20, 0x307, 0x210, + 0x20, 0x30a, 0x210, 0x20, 0x328, 0x210, 0x20, 0x303, + 0x210, 0x20, 0x30b, 0x109, 0x263, 0x109, 0x6c, 0x109, + 0x73, 0x109, 0x78, 0x109, 0x295, 0x101, 0x300, 0x101, + 0x301, 0x101, 0x313, 0x201, 0x308, 0x301, 0x101, 0x2b9, + 0x210, 0x20, 0x345, 0x101, 0x3b, 0x210, 0x20, 0x301, + 0x201, 0xa8, 0x301, 0x201, 0x391, 0x301, 0x101, 0xb7, + 0x201, 0x395, 0x301, 0x201, 0x397, 0x301, 0x201, 0x399, + 0x301, 0x201, 0x39f, 0x301, 0x201, 0x3a5, 0x301, 0x201, + 0x3a9, 0x301, 0x201, 0x3ca, 0x301, 0x201, 0x399, 0x308, + 0x201, 0x3a5, 0x308, 0x201, 0x3b1, 0x301, 0x201, 0x3b5, + 0x301, 0x201, 0x3b7, 0x301, 0x201, 0x3b9, 0x301, 0x201, + 0x3cb, 0x301, 0x201, 0x3b9, 0x308, 0x201, 0x3c5, 0x308, + 0x201, 0x3bf, 0x301, 0x201, 0x3c5, 0x301, 0x201, 0x3c9, + 0x301, 0x110, 0x3b2, 0x110, 0x3b8, 0x110, 0x3a5, 0x201, + 0x3d2, 0x301, 0x201, 0x3d2, 0x308, 0x110, 0x3c6, 0x110, + 0x3c0, 0x110, 0x3ba, 0x110, 0x3c1, 0x110, 0x3c2, 0x110, + 0x398, 0x110, 0x3b5, 0x110, 0x3a3, 0x201, 0x415, 0x300, + 0x201, 0x415, 0x308, 0x201, 0x413, 0x301, 0x201, 0x406, + 0x308, 0x201, 0x41a, 0x301, 0x201, 0x418, 0x300, 0x201, + 0x423, 0x306, 0x201, 0x418, 0x306, 0x201, 0x438, 0x306, + 0x201, 0x435, 0x300, 0x201, 0x435, 0x308, 0x201, 0x433, + 0x301, 0x201, 0x456, 0x308, 0x201, 0x43a, 0x301, 0x201, + 0x438, 0x300, 0x201, 0x443, 0x306, 0x201, 0x474, 0x30f, + 0x201, 0x475, 0x30f, 0x201, 0x416, 0x306, 0x201, 0x436, + 0x306, 0x201, 0x410, 0x306, 0x201, 0x430, 0x306, 0x201, + 0x410, 0x308, 0x201, 0x430, 0x308, 0x201, 0x415, 0x306, + 0x201, 0x435, 0x306, 0x201, 0x4d8, 0x308, 0x201, 0x4d9, + 0x308, 0x201, 0x416, 0x308, 0x201, 0x436, 0x308, 0x201, + 0x417, 0x308, 0x201, 0x437, 0x308, 0x201, 0x418, 0x304, + 0x201, 0x438, 0x304, 0x201, 0x418, 0x308, 0x201, 0x438, + 0x308, 0x201, 0x41e, 0x308, 0x201, 0x43e, 0x308, 0x201, + 0x4e8, 0x308, 0x201, 0x4e9, 0x308, 0x201, 0x42d, 0x308, + 0x201, 0x44d, 0x308, 0x201, 0x423, 0x304, 0x201, 0x443, + 0x304, 0x201, 0x423, 0x308, 0x201, 0x443, 0x308, 0x201, + 0x423, 0x30b, 0x201, 0x443, 0x30b, 0x201, 0x427, 0x308, + 0x201, 0x447, 0x308, 0x201, 0x42b, 0x308, 0x201, 0x44b, + 0x308, 0x210, 0x565, 0x582, 0x201, 0x627, 0x653, 0x201, + 0x627, 0x654, 0x201, 0x648, 0x654, 0x201, 0x627, 0x655, + 0x201, 0x64a, 0x654, 0x210, 0x627, 0x674, 0x210, 0x648, + 0x674, 0x210, 0x6c7, 0x674, 0x210, 0x64a, 0x674, 0x201, + 0x6d5, 0x654, 0x201, 0x6c1, 0x654, 0x201, 0x6d2, 0x654, + 0x201, 0x928, 0x93c, 0x201, 0x930, 0x93c, 0x201, 0x933, + 0x93c, 0x201, 0x915, 0x93c, 0x201, 0x916, 0x93c, 0x201, + 0x917, 0x93c, 0x201, 0x91c, 0x93c, 0x201, 0x921, 0x93c, + 0x201, 0x922, 0x93c, 0x201, 0x92b, 0x93c, 0x201, 0x92f, + 0x93c, 0x201, 0x9c7, 0x9be, 0x201, 0x9c7, 0x9d7, 0x201, + 0x9a1, 0x9bc, 0x201, 0x9a2, 0x9bc, 0x201, 0x9af, 0x9bc, + 0x201, 0xa32, 0xa3c, 0x201, 0xa38, 0xa3c, 0x201, 0xa16, + 0xa3c, 0x201, 0xa17, 0xa3c, 0x201, 0xa1c, 0xa3c, 0x201, + 0xa2b, 0xa3c, 0x201, 0xb47, 0xb56, 0x201, 0xb47, 0xb3e, + 0x201, 0xb47, 0xb57, 0x201, 0xb21, 0xb3c, 0x201, 0xb22, + 0xb3c, 0x201, 0xb92, 0xbd7, 0x201, 0xbc6, 0xbbe, 0x201, + 0xbc7, 0xbbe, 0x201, 0xbc6, 0xbd7, 0x201, 0xc46, 0xc56, + 0x201, 0xcbf, 0xcd5, 0x201, 0xcc6, 0xcd5, 0x201, 0xcc6, + 0xcd6, 0x201, 0xcc6, 0xcc2, 0x201, 0xcca, 0xcd5, 0x201, + 0xd46, 0xd3e, 0x201, 0xd47, 0xd3e, 0x201, 0xd46, 0xd57, + 0x201, 0xdd9, 0xdca, 0x201, 0xdd9, 0xdcf, 0x201, 0xddc, + 0xdca, 0x201, 0xdd9, 0xddf, 0x210, 0xe4d, 0xe32, 0x210, + 0xecd, 0xeb2, 0x210, 0xeab, 0xe99, 0x210, 0xeab, 0xea1, + 0x103, 0xf0b, 0x201, 0xf42, 0xfb7, 0x201, 0xf4c, 0xfb7, + 0x201, 0xf51, 0xfb7, 0x201, 0xf56, 0xfb7, 0x201, 0xf5b, + 0xfb7, 0x201, 0xf40, 0xfb5, 0x201, 0xf71, 0xf72, 0x201, + 0xf71, 0xf74, 0x201, 0xfb2, 0xf80, 0x210, 0xfb2, 0xf81, + 0x201, 0xfb3, 0xf80, 0x210, 0xfb3, 0xf81, 0x201, 0xf71, + 0xf80, 0x201, 0xf92, 0xfb7, 0x201, 0xf9c, 0xfb7, 0x201, + 0xfa1, 0xfb7, 0x201, 0xfa6, 0xfb7, 0x201, 0xfab, 0xfb7, + 0x201, 0xf90, 0xfb5, 0x201, 0x1025, 0x102e, 0x109, 0x10dc, + 0x201, 0x1b05, 0x1b35, 0x201, 0x1b07, 0x1b35, 0x201, 0x1b09, + 0x1b35, 0x201, 0x1b0b, 0x1b35, 0x201, 0x1b0d, 0x1b35, 0x201, + 0x1b11, 0x1b35, 0x201, 0x1b3a, 0x1b35, 0x201, 0x1b3c, 0x1b35, + 0x201, 0x1b3e, 0x1b35, 0x201, 0x1b3f, 0x1b35, 0x201, 0x1b42, + 0x1b35, 0x109, 0x41, 0x109, 0xc6, 0x109, 0x42, 0x109, + 0x44, 0x109, 0x45, 0x109, 0x18e, 0x109, 0x47, 0x109, + 0x48, 0x109, 0x49, 0x109, 0x4a, 0x109, 0x4b, 0x109, + 0x4c, 0x109, 0x4d, 0x109, 0x4e, 0x109, 0x4f, 0x109, + 0x222, 0x109, 0x50, 0x109, 0x52, 0x109, 0x54, 0x109, + 0x55, 0x109, 0x57, 0x109, 0x61, 0x109, 0x250, 0x109, + 0x251, 0x109, 0x1d02, 0x109, 0x62, 0x109, 0x64, 0x109, + 0x65, 0x109, 0x259, 0x109, 0x25b, 0x109, 0x25c, 0x109, + 0x67, 0x109, 0x6b, 0x109, 0x6d, 0x109, 0x14b, 0x109, + 0x6f, 0x109, 0x254, 0x109, 0x1d16, 0x109, 0x1d17, 0x109, + 0x70, 0x109, 0x74, 0x109, 0x75, 0x109, 0x1d1d, 0x109, + 0x26f, 0x109, 0x76, 0x109, 0x1d25, 0x109, 0x3b2, 0x109, + 0x3b3, 0x109, 0x3b4, 0x109, 0x3c6, 0x109, 0x3c7, 0x10a, + 0x69, 0x10a, 0x72, 0x10a, 0x75, 0x10a, 0x76, 0x10a, + 0x3b2, 0x10a, 0x3b3, 0x10a, 0x3c1, 0x10a, 0x3c6, 0x10a, + 0x3c7, 0x109, 0x43d, 0x109, 0x252, 0x109, 0x63, 0x109, + 0x255, 0x109, 0xf0, 0x109, 0x25c, 0x109, 0x66, 0x109, + 0x25f, 0x109, 0x261, 0x109, 0x265, 0x109, 0x268, 0x109, + 0x269, 0x109, 0x26a, 0x109, 0x1d7b, 0x109, 0x29d, 0x109, + 0x26d, 0x109, 0x1d85, 0x109, 0x29f, 0x109, 0x271, 0x109, + 0x270, 0x109, 0x272, 0x109, 0x273, 0x109, 0x274, 0x109, + 0x275, 0x109, 0x278, 0x109, 0x282, 0x109, 0x283, 0x109, + 0x1ab, 0x109, 0x289, 0x109, 0x28a, 0x109, 0x1d1c, 0x109, + 0x28b, 0x109, 0x28c, 0x109, 0x7a, 0x109, 0x290, 0x109, + 0x291, 0x109, 0x292, 0x109, 0x3b8, 0x201, 0x41, 0x325, + 0x201, 0x61, 0x325, 0x201, 0x42, 0x307, 0x201, 0x62, + 0x307, 0x201, 0x42, 0x323, 0x201, 0x62, 0x323, 0x201, + 0x42, 0x331, 0x201, 0x62, 0x331, 0x201, 0xc7, 0x301, + 0x201, 0xe7, 0x301, 0x201, 0x44, 0x307, 0x201, 0x64, + 0x307, 0x201, 0x44, 0x323, 0x201, 0x64, 0x323, 0x201, + 0x44, 0x331, 0x201, 0x64, 0x331, 0x201, 0x44, 0x327, + 0x201, 0x64, 0x327, 0x201, 0x44, 0x32d, 0x201, 0x64, + 0x32d, 0x201, 0x112, 0x300, 0x201, 0x113, 0x300, 0x201, + 0x112, 0x301, 0x201, 0x113, 0x301, 0x201, 0x45, 0x32d, + 0x201, 0x65, 0x32d, 0x201, 0x45, 0x330, 0x201, 0x65, + 0x330, 0x201, 0x228, 0x306, 0x201, 0x229, 0x306, 0x201, + 0x46, 0x307, 0x201, 0x66, 0x307, 0x201, 0x47, 0x304, + 0x201, 0x67, 0x304, 0x201, 0x48, 0x307, 0x201, 0x68, + 0x307, 0x201, 0x48, 0x323, 0x201, 0x68, 0x323, 0x201, + 0x48, 0x308, 0x201, 0x68, 0x308, 0x201, 0x48, 0x327, + 0x201, 0x68, 0x327, 0x201, 0x48, 0x32e, 0x201, 0x68, + 0x32e, 0x201, 0x49, 0x330, 0x201, 0x69, 0x330, 0x201, + 0xcf, 0x301, 0x201, 0xef, 0x301, 0x201, 0x4b, 0x301, + 0x201, 0x6b, 0x301, 0x201, 0x4b, 0x323, 0x201, 0x6b, + 0x323, 0x201, 0x4b, 0x331, 0x201, 0x6b, 0x331, 0x201, + 0x4c, 0x323, 0x201, 0x6c, 0x323, 0x201, 0x1e36, 0x304, + 0x201, 0x1e37, 0x304, 0x201, 0x4c, 0x331, 0x201, 0x6c, + 0x331, 0x201, 0x4c, 0x32d, 0x201, 0x6c, 0x32d, 0x201, + 0x4d, 0x301, 0x201, 0x6d, 0x301, 0x201, 0x4d, 0x307, + 0x201, 0x6d, 0x307, 0x201, 0x4d, 0x323, 0x201, 0x6d, + 0x323, 0x201, 0x4e, 0x307, 0x201, 0x6e, 0x307, 0x201, + 0x4e, 0x323, 0x201, 0x6e, 0x323, 0x201, 0x4e, 0x331, + 0x201, 0x6e, 0x331, 0x201, 0x4e, 0x32d, 0x201, 0x6e, + 0x32d, 0x201, 0xd5, 0x301, 0x201, 0xf5, 0x301, 0x201, + 0xd5, 0x308, 0x201, 0xf5, 0x308, 0x201, 0x14c, 0x300, + 0x201, 0x14d, 0x300, 0x201, 0x14c, 0x301, 0x201, 0x14d, + 0x301, 0x201, 0x50, 0x301, 0x201, 0x70, 0x301, 0x201, + 0x50, 0x307, 0x201, 0x70, 0x307, 0x201, 0x52, 0x307, + 0x201, 0x72, 0x307, 0x201, 0x52, 0x323, 0x201, 0x72, + 0x323, 0x201, 0x1e5a, 0x304, 0x201, 0x1e5b, 0x304, 0x201, + 0x52, 0x331, 0x201, 0x72, 0x331, 0x201, 0x53, 0x307, + 0x201, 0x73, 0x307, 0x201, 0x53, 0x323, 0x201, 0x73, + 0x323, 0x201, 0x15a, 0x307, 0x201, 0x15b, 0x307, 0x201, + 0x160, 0x307, 0x201, 0x161, 0x307, 0x201, 0x1e62, 0x307, + 0x201, 0x1e63, 0x307, 0x201, 0x54, 0x307, 0x201, 0x74, + 0x307, 0x201, 0x54, 0x323, 0x201, 0x74, 0x323, 0x201, + 0x54, 0x331, 0x201, 0x74, 0x331, 0x201, 0x54, 0x32d, + 0x201, 0x74, 0x32d, 0x201, 0x55, 0x324, 0x201, 0x75, + 0x324, 0x201, 0x55, 0x330, 0x201, 0x75, 0x330, 0x201, + 0x55, 0x32d, 0x201, 0x75, 0x32d, 0x201, 0x168, 0x301, + 0x201, 0x169, 0x301, 0x201, 0x16a, 0x308, 0x201, 0x16b, + 0x308, 0x201, 0x56, 0x303, 0x201, 0x76, 0x303, 0x201, + 0x56, 0x323, 0x201, 0x76, 0x323, 0x201, 0x57, 0x300, + 0x201, 0x77, 0x300, 0x201, 0x57, 0x301, 0x201, 0x77, + 0x301, 0x201, 0x57, 0x308, 0x201, 0x77, 0x308, 0x201, + 0x57, 0x307, 0x201, 0x77, 0x307, 0x201, 0x57, 0x323, + 0x201, 0x77, 0x323, 0x201, 0x58, 0x307, 0x201, 0x78, + 0x307, 0x201, 0x58, 0x308, 0x201, 0x78, 0x308, 0x201, + 0x59, 0x307, 0x201, 0x79, 0x307, 0x201, 0x5a, 0x302, + 0x201, 0x7a, 0x302, 0x201, 0x5a, 0x323, 0x201, 0x7a, + 0x323, 0x201, 0x5a, 0x331, 0x201, 0x7a, 0x331, 0x201, + 0x68, 0x331, 0x201, 0x74, 0x308, 0x201, 0x77, 0x30a, + 0x201, 0x79, 0x30a, 0x210, 0x61, 0x2be, 0x201, 0x17f, + 0x307, 0x201, 0x41, 0x323, 0x201, 0x61, 0x323, 0x201, + 0x41, 0x309, 0x201, 0x61, 0x309, 0x201, 0xc2, 0x301, + 0x201, 0xe2, 0x301, 0x201, 0xc2, 0x300, 0x201, 0xe2, + 0x300, 0x201, 0xc2, 0x309, 0x201, 0xe2, 0x309, 0x201, + 0xc2, 0x303, 0x201, 0xe2, 0x303, 0x201, 0x1ea0, 0x302, + 0x201, 0x1ea1, 0x302, 0x201, 0x102, 0x301, 0x201, 0x103, + 0x301, 0x201, 0x102, 0x300, 0x201, 0x103, 0x300, 0x201, + 0x102, 0x309, 0x201, 0x103, 0x309, 0x201, 0x102, 0x303, + 0x201, 0x103, 0x303, 0x201, 0x1ea0, 0x306, 0x201, 0x1ea1, + 0x306, 0x201, 0x45, 0x323, 0x201, 0x65, 0x323, 0x201, + 0x45, 0x309, 0x201, 0x65, 0x309, 0x201, 0x45, 0x303, + 0x201, 0x65, 0x303, 0x201, 0xca, 0x301, 0x201, 0xea, + 0x301, 0x201, 0xca, 0x300, 0x201, 0xea, 0x300, 0x201, + 0xca, 0x309, 0x201, 0xea, 0x309, 0x201, 0xca, 0x303, + 0x201, 0xea, 0x303, 0x201, 0x1eb8, 0x302, 0x201, 0x1eb9, + 0x302, 0x201, 0x49, 0x309, 0x201, 0x69, 0x309, 0x201, + 0x49, 0x323, 0x201, 0x69, 0x323, 0x201, 0x4f, 0x323, + 0x201, 0x6f, 0x323, 0x201, 0x4f, 0x309, 0x201, 0x6f, + 0x309, 0x201, 0xd4, 0x301, 0x201, 0xf4, 0x301, 0x201, + 0xd4, 0x300, 0x201, 0xf4, 0x300, 0x201, 0xd4, 0x309, + 0x201, 0xf4, 0x309, 0x201, 0xd4, 0x303, 0x201, 0xf4, + 0x303, 0x201, 0x1ecc, 0x302, 0x201, 0x1ecd, 0x302, 0x201, + 0x1a0, 0x301, 0x201, 0x1a1, 0x301, 0x201, 0x1a0, 0x300, + 0x201, 0x1a1, 0x300, 0x201, 0x1a0, 0x309, 0x201, 0x1a1, + 0x309, 0x201, 0x1a0, 0x303, 0x201, 0x1a1, 0x303, 0x201, + 0x1a0, 0x323, 0x201, 0x1a1, 0x323, 0x201, 0x55, 0x323, + 0x201, 0x75, 0x323, 0x201, 0x55, 0x309, 0x201, 0x75, + 0x309, 0x201, 0x1af, 0x301, 0x201, 0x1b0, 0x301, 0x201, + 0x1af, 0x300, 0x201, 0x1b0, 0x300, 0x201, 0x1af, 0x309, + 0x201, 0x1b0, 0x309, 0x201, 0x1af, 0x303, 0x201, 0x1b0, + 0x303, 0x201, 0x1af, 0x323, 0x201, 0x1b0, 0x323, 0x201, + 0x59, 0x300, 0x201, 0x79, 0x300, 0x201, 0x59, 0x323, + 0x201, 0x79, 0x323, 0x201, 0x59, 0x309, 0x201, 0x79, + 0x309, 0x201, 0x59, 0x303, 0x201, 0x79, 0x303, 0x201, + 0x3b1, 0x313, 0x201, 0x3b1, 0x314, 0x201, 0x1f00, 0x300, + 0x201, 0x1f01, 0x300, 0x201, 0x1f00, 0x301, 0x201, 0x1f01, + 0x301, 0x201, 0x1f00, 0x342, 0x201, 0x1f01, 0x342, 0x201, + 0x391, 0x313, 0x201, 0x391, 0x314, 0x201, 0x1f08, 0x300, + 0x201, 0x1f09, 0x300, 0x201, 0x1f08, 0x301, 0x201, 0x1f09, + 0x301, 0x201, 0x1f08, 0x342, 0x201, 0x1f09, 0x342, 0x201, + 0x3b5, 0x313, 0x201, 0x3b5, 0x314, 0x201, 0x1f10, 0x300, + 0x201, 0x1f11, 0x300, 0x201, 0x1f10, 0x301, 0x201, 0x1f11, + 0x301, 0x201, 0x395, 0x313, 0x201, 0x395, 0x314, 0x201, + 0x1f18, 0x300, 0x201, 0x1f19, 0x300, 0x201, 0x1f18, 0x301, + 0x201, 0x1f19, 0x301, 0x201, 0x3b7, 0x313, 0x201, 0x3b7, + 0x314, 0x201, 0x1f20, 0x300, 0x201, 0x1f21, 0x300, 0x201, + 0x1f20, 0x301, 0x201, 0x1f21, 0x301, 0x201, 0x1f20, 0x342, + 0x201, 0x1f21, 0x342, 0x201, 0x397, 0x313, 0x201, 0x397, + 0x314, 0x201, 0x1f28, 0x300, 0x201, 0x1f29, 0x300, 0x201, + 0x1f28, 0x301, 0x201, 0x1f29, 0x301, 0x201, 0x1f28, 0x342, + 0x201, 0x1f29, 0x342, 0x201, 0x3b9, 0x313, 0x201, 0x3b9, + 0x314, 0x201, 0x1f30, 0x300, 0x201, 0x1f31, 0x300, 0x201, + 0x1f30, 0x301, 0x201, 0x1f31, 0x301, 0x201, 0x1f30, 0x342, + 0x201, 0x1f31, 0x342, 0x201, 0x399, 0x313, 0x201, 0x399, + 0x314, 0x201, 0x1f38, 0x300, 0x201, 0x1f39, 0x300, 0x201, + 0x1f38, 0x301, 0x201, 0x1f39, 0x301, 0x201, 0x1f38, 0x342, + 0x201, 0x1f39, 0x342, 0x201, 0x3bf, 0x313, 0x201, 0x3bf, + 0x314, 0x201, 0x1f40, 0x300, 0x201, 0x1f41, 0x300, 0x201, + 0x1f40, 0x301, 0x201, 0x1f41, 0x301, 0x201, 0x39f, 0x313, + 0x201, 0x39f, 0x314, 0x201, 0x1f48, 0x300, 0x201, 0x1f49, + 0x300, 0x201, 0x1f48, 0x301, 0x201, 0x1f49, 0x301, 0x201, + 0x3c5, 0x313, 0x201, 0x3c5, 0x314, 0x201, 0x1f50, 0x300, + 0x201, 0x1f51, 0x300, 0x201, 0x1f50, 0x301, 0x201, 0x1f51, + 0x301, 0x201, 0x1f50, 0x342, 0x201, 0x1f51, 0x342, 0x201, + 0x3a5, 0x314, 0x201, 0x1f59, 0x300, 0x201, 0x1f59, 0x301, + 0x201, 0x1f59, 0x342, 0x201, 0x3c9, 0x313, 0x201, 0x3c9, + 0x314, 0x201, 0x1f60, 0x300, 0x201, 0x1f61, 0x300, 0x201, + 0x1f60, 0x301, 0x201, 0x1f61, 0x301, 0x201, 0x1f60, 0x342, + 0x201, 0x1f61, 0x342, 0x201, 0x3a9, 0x313, 0x201, 0x3a9, + 0x314, 0x201, 0x1f68, 0x300, 0x201, 0x1f69, 0x300, 0x201, + 0x1f68, 0x301, 0x201, 0x1f69, 0x301, 0x201, 0x1f68, 0x342, + 0x201, 0x1f69, 0x342, 0x201, 0x3b1, 0x300, 0x101, 0x3ac, + 0x201, 0x3b5, 0x300, 0x101, 0x3ad, 0x201, 0x3b7, 0x300, + 0x101, 0x3ae, 0x201, 0x3b9, 0x300, 0x101, 0x3af, 0x201, + 0x3bf, 0x300, 0x101, 0x3cc, 0x201, 0x3c5, 0x300, 0x101, + 0x3cd, 0x201, 0x3c9, 0x300, 0x101, 0x3ce, 0x201, 0x1f00, + 0x345, 0x201, 0x1f01, 0x345, 0x201, 0x1f02, 0x345, 0x201, + 0x1f03, 0x345, 0x201, 0x1f04, 0x345, 0x201, 0x1f05, 0x345, + 0x201, 0x1f06, 0x345, 0x201, 0x1f07, 0x345, 0x201, 0x1f08, + 0x345, 0x201, 0x1f09, 0x345, 0x201, 0x1f0a, 0x345, 0x201, + 0x1f0b, 0x345, 0x201, 0x1f0c, 0x345, 0x201, 0x1f0d, 0x345, + 0x201, 0x1f0e, 0x345, 0x201, 0x1f0f, 0x345, 0x201, 0x1f20, + 0x345, 0x201, 0x1f21, 0x345, 0x201, 0x1f22, 0x345, 0x201, + 0x1f23, 0x345, 0x201, 0x1f24, 0x345, 0x201, 0x1f25, 0x345, + 0x201, 0x1f26, 0x345, 0x201, 0x1f27, 0x345, 0x201, 0x1f28, + 0x345, 0x201, 0x1f29, 0x345, 0x201, 0x1f2a, 0x345, 0x201, + 0x1f2b, 0x345, 0x201, 0x1f2c, 0x345, 0x201, 0x1f2d, 0x345, + 0x201, 0x1f2e, 0x345, 0x201, 0x1f2f, 0x345, 0x201, 0x1f60, + 0x345, 0x201, 0x1f61, 0x345, 0x201, 0x1f62, 0x345, 0x201, + 0x1f63, 0x345, 0x201, 0x1f64, 0x345, 0x201, 0x1f65, 0x345, + 0x201, 0x1f66, 0x345, 0x201, 0x1f67, 0x345, 0x201, 0x1f68, + 0x345, 0x201, 0x1f69, 0x345, 0x201, 0x1f6a, 0x345, 0x201, + 0x1f6b, 0x345, 0x201, 0x1f6c, 0x345, 0x201, 0x1f6d, 0x345, + 0x201, 0x1f6e, 0x345, 0x201, 0x1f6f, 0x345, 0x201, 0x3b1, + 0x306, 0x201, 0x3b1, 0x304, 0x201, 0x1f70, 0x345, 0x201, + 0x3b1, 0x345, 0x201, 0x3ac, 0x345, 0x201, 0x3b1, 0x342, + 0x201, 0x1fb6, 0x345, 0x201, 0x391, 0x306, 0x201, 0x391, + 0x304, 0x201, 0x391, 0x300, 0x101, 0x386, 0x201, 0x391, + 0x345, 0x210, 0x20, 0x313, 0x101, 0x3b9, 0x210, 0x20, + 0x313, 0x210, 0x20, 0x342, 0x201, 0xa8, 0x342, 0x201, + 0x1f74, 0x345, 0x201, 0x3b7, 0x345, 0x201, 0x3ae, 0x345, + 0x201, 0x3b7, 0x342, 0x201, 0x1fc6, 0x345, 0x201, 0x395, + 0x300, 0x101, 0x388, 0x201, 0x397, 0x300, 0x101, 0x389, + 0x201, 0x397, 0x345, 0x201, 0x1fbf, 0x300, 0x201, 0x1fbf, + 0x301, 0x201, 0x1fbf, 0x342, 0x201, 0x3b9, 0x306, 0x201, + 0x3b9, 0x304, 0x201, 0x3ca, 0x300, 0x101, 0x390, 0x201, + 0x3b9, 0x342, 0x201, 0x3ca, 0x342, 0x201, 0x399, 0x306, + 0x201, 0x399, 0x304, 0x201, 0x399, 0x300, 0x101, 0x38a, + 0x201, 0x1ffe, 0x300, 0x201, 0x1ffe, 0x301, 0x201, 0x1ffe, + 0x342, 0x201, 0x3c5, 0x306, 0x201, 0x3c5, 0x304, 0x201, + 0x3cb, 0x300, 0x101, 0x3b0, 0x201, 0x3c1, 0x313, 0x201, + 0x3c1, 0x314, 0x201, 0x3c5, 0x342, 0x201, 0x3cb, 0x342, + 0x201, 0x3a5, 0x306, 0x201, 0x3a5, 0x304, 0x201, 0x3a5, + 0x300, 0x101, 0x38e, 0x201, 0x3a1, 0x314, 0x201, 0xa8, + 0x300, 0x101, 0x385, 0x101, 0x60, 0x201, 0x1f7c, 0x345, + 0x201, 0x3c9, 0x345, 0x201, 0x3ce, 0x345, 0x201, 0x3c9, + 0x342, 0x201, 0x1ff6, 0x345, 0x201, 0x39f, 0x300, 0x101, + 0x38c, 0x201, 0x3a9, 0x300, 0x101, 0x38f, 0x201, 0x3a9, + 0x345, 0x101, 0xb4, 0x210, 0x20, 0x314, 0x101, 0x2002, + 0x101, 0x2003, 0x110, 0x20, 0x110, 0x20, 0x110, 0x20, + 0x110, 0x20, 0x110, 0x20, 0x103, 0x20, 0x110, 0x20, + 0x110, 0x20, 0x110, 0x20, 0x103, 0x2010, 0x210, 0x20, + 0x333, 0x110, 0x2e, 0x210, 0x2e, 0x2e, 0x310, 0x2e, + 0x2e, 0x2e, 0x103, 0x20, 0x210, 0x2032, 0x2032, 0x310, + 0x2032, 0x2032, 0x2032, 0x210, 0x2035, 0x2035, 0x310, 0x2035, + 0x2035, 0x2035, 0x210, 0x21, 0x21, 0x210, 0x20, 0x305, + 0x210, 0x3f, 0x3f, 0x210, 0x3f, 0x21, 0x210, 0x21, + 0x3f, 0x410, 0x2032, 0x2032, 0x2032, 0x2032, 0x110, 0x20, + 0x109, 0x30, 0x109, 0x69, 0x109, 0x34, 0x109, 0x35, + 0x109, 0x36, 0x109, 0x37, 0x109, 0x38, 0x109, 0x39, + 0x109, 0x2b, 0x109, 0x2212, 0x109, 0x3d, 0x109, 0x28, + 0x109, 0x29, 0x109, 0x6e, 0x10a, 0x30, 0x10a, 0x31, + 0x10a, 0x32, 0x10a, 0x33, 0x10a, 0x34, 0x10a, 0x35, + 0x10a, 0x36, 0x10a, 0x37, 0x10a, 0x38, 0x10a, 0x39, + 0x10a, 0x2b, 0x10a, 0x2212, 0x10a, 0x3d, 0x10a, 0x28, + 0x10a, 0x29, 0x10a, 0x61, 0x10a, 0x65, 0x10a, 0x6f, + 0x10a, 0x78, 0x10a, 0x259, 0x210, 0x52, 0x73, 0x310, + 0x61, 0x2f, 0x63, 0x310, 0x61, 0x2f, 0x73, 0x102, + 0x43, 0x210, 0xb0, 0x43, 0x310, 0x63, 0x2f, 0x6f, + 0x310, 0x63, 0x2f, 0x75, 0x110, 0x190, 0x210, 0xb0, + 0x46, 0x102, 0x67, 0x102, 0x48, 0x102, 0x48, 0x102, + 0x48, 0x102, 0x68, 0x102, 0x127, 0x102, 0x49, 0x102, + 0x49, 0x102, 0x4c, 0x102, 0x6c, 0x102, 0x4e, 0x210, + 0x4e, 0x6f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, + 0x102, 0x52, 0x102, 0x52, 0x209, 0x53, 0x4d, 0x310, + 0x54, 0x45, 0x4c, 0x209, 0x54, 0x4d, 0x102, 0x5a, + 0x101, 0x3a9, 0x102, 0x5a, 0x101, 0x4b, 0x101, 0xc5, + 0x102, 0x42, 0x102, 0x43, 0x102, 0x65, 0x102, 0x45, + 0x102, 0x46, 0x102, 0x4d, 0x102, 0x6f, 0x110, 0x5d0, + 0x110, 0x5d1, 0x110, 0x5d2, 0x110, 0x5d3, 0x102, 0x69, + 0x310, 0x46, 0x41, 0x58, 0x102, 0x3c0, 0x102, 0x3b3, + 0x102, 0x393, 0x102, 0x3a0, 0x102, 0x2211, 0x102, 0x44, + 0x102, 0x64, 0x102, 0x65, 0x102, 0x69, 0x102, 0x6a, + 0x311, 0x31, 0x2044, 0x33, 0x311, 0x32, 0x2044, 0x33, + 0x311, 0x31, 0x2044, 0x35, 0x311, 0x32, 0x2044, 0x35, + 0x311, 0x33, 0x2044, 0x35, 0x311, 0x34, 0x2044, 0x35, + 0x311, 0x31, 0x2044, 0x36, 0x311, 0x35, 0x2044, 0x36, + 0x311, 0x31, 0x2044, 0x38, 0x311, 0x33, 0x2044, 0x38, + 0x311, 0x35, 0x2044, 0x38, 0x311, 0x37, 0x2044, 0x38, + 0x211, 0x31, 0x2044, 0x110, 0x49, 0x210, 0x49, 0x49, + 0x310, 0x49, 0x49, 0x49, 0x210, 0x49, 0x56, 0x110, + 0x56, 0x210, 0x56, 0x49, 0x310, 0x56, 0x49, 0x49, + 0x410, 0x56, 0x49, 0x49, 0x49, 0x210, 0x49, 0x58, + 0x110, 0x58, 0x210, 0x58, 0x49, 0x310, 0x58, 0x49, + 0x49, 0x110, 0x4c, 0x110, 0x43, 0x110, 0x44, 0x110, + 0x4d, 0x110, 0x69, 0x210, 0x69, 0x69, 0x310, 0x69, + 0x69, 0x69, 0x210, 0x69, 0x76, 0x110, 0x76, 0x210, + 0x76, 0x69, 0x310, 0x76, 0x69, 0x69, 0x410, 0x76, + 0x69, 0x69, 0x69, 0x210, 0x69, 0x78, 0x110, 0x78, + 0x210, 0x78, 0x69, 0x310, 0x78, 0x69, 0x69, 0x110, + 0x6c, 0x110, 0x63, 0x110, 0x64, 0x110, 0x6d, 0x201, + 0x2190, 0x338, 0x201, 0x2192, 0x338, 0x201, 0x2194, 0x338, + 0x201, 0x21d0, 0x338, 0x201, 0x21d4, 0x338, 0x201, 0x21d2, + 0x338, 0x201, 0x2203, 0x338, 0x201, 0x2208, 0x338, 0x201, + 0x220b, 0x338, 0x201, 0x2223, 0x338, 0x201, 0x2225, 0x338, + 0x210, 0x222b, 0x222b, 0x310, 0x222b, 0x222b, 0x222b, 0x210, + 0x222e, 0x222e, 0x310, 0x222e, 0x222e, 0x222e, 0x201, 0x223c, + 0x338, 0x201, 0x2243, 0x338, 0x201, 0x2245, 0x338, 0x201, + 0x2248, 0x338, 0x201, 0x3d, 0x338, 0x201, 0x2261, 0x338, + 0x201, 0x224d, 0x338, 0x201, 0x3c, 0x338, 0x201, 0x3e, + 0x338, 0x201, 0x2264, 0x338, 0x201, 0x2265, 0x338, 0x201, + 0x2272, 0x338, 0x201, 0x2273, 0x338, 0x201, 0x2276, 0x338, + 0x201, 0x2277, 0x338, 0x201, 0x227a, 0x338, 0x201, 0x227b, + 0x338, 0x201, 0x2282, 0x338, 0x201, 0x2283, 0x338, 0x201, + 0x2286, 0x338, 0x201, 0x2287, 0x338, 0x201, 0x22a2, 0x338, + 0x201, 0x22a8, 0x338, 0x201, 0x22a9, 0x338, 0x201, 0x22ab, + 0x338, 0x201, 0x227c, 0x338, 0x201, 0x227d, 0x338, 0x201, + 0x2291, 0x338, 0x201, 0x2292, 0x338, 0x201, 0x22b2, 0x338, + 0x201, 0x22b3, 0x338, 0x201, 0x22b4, 0x338, 0x201, 0x22b5, + 0x338, 0x101, 0x3008, 0x101, 0x3009, 0x108, 0x31, 0x108, + 0x32, 0x108, 0x33, 0x108, 0x34, 0x108, 0x35, 0x108, + 0x36, 0x108, 0x37, 0x108, 0x38, 0x108, 0x39, 0x208, + 0x31, 0x30, 0x208, 0x31, 0x31, 0x208, 0x31, 0x32, + 0x208, 0x31, 0x33, 0x208, 0x31, 0x34, 0x208, 0x31, + 0x35, 0x208, 0x31, 0x36, 0x208, 0x31, 0x37, 0x208, + 0x31, 0x38, 0x208, 0x31, 0x39, 0x208, 0x32, 0x30, + 0x310, 0x28, 0x31, 0x29, 0x310, 0x28, 0x32, 0x29, + 0x310, 0x28, 0x33, 0x29, 0x310, 0x28, 0x34, 0x29, + 0x310, 0x28, 0x35, 0x29, 0x310, 0x28, 0x36, 0x29, + 0x310, 0x28, 0x37, 0x29, 0x310, 0x28, 0x38, 0x29, + 0x310, 0x28, 0x39, 0x29, 0x410, 0x28, 0x31, 0x30, + 0x29, 0x410, 0x28, 0x31, 0x31, 0x29, 0x410, 0x28, + 0x31, 0x32, 0x29, 0x410, 0x28, 0x31, 0x33, 0x29, + 0x410, 0x28, 0x31, 0x34, 0x29, 0x410, 0x28, 0x31, + 0x35, 0x29, 0x410, 0x28, 0x31, 0x36, 0x29, 0x410, + 0x28, 0x31, 0x37, 0x29, 0x410, 0x28, 0x31, 0x38, + 0x29, 0x410, 0x28, 0x31, 0x39, 0x29, 0x410, 0x28, + 0x32, 0x30, 0x29, 0x210, 0x31, 0x2e, 0x210, 0x32, + 0x2e, 0x210, 0x33, 0x2e, 0x210, 0x34, 0x2e, 0x210, + 0x35, 0x2e, 0x210, 0x36, 0x2e, 0x210, 0x37, 0x2e, + 0x210, 0x38, 0x2e, 0x210, 0x39, 0x2e, 0x310, 0x31, + 0x30, 0x2e, 0x310, 0x31, 0x31, 0x2e, 0x310, 0x31, + 0x32, 0x2e, 0x310, 0x31, 0x33, 0x2e, 0x310, 0x31, + 0x34, 0x2e, 0x310, 0x31, 0x35, 0x2e, 0x310, 0x31, + 0x36, 0x2e, 0x310, 0x31, 0x37, 0x2e, 0x310, 0x31, + 0x38, 0x2e, 0x310, 0x31, 0x39, 0x2e, 0x310, 0x32, + 0x30, 0x2e, 0x310, 0x28, 0x61, 0x29, 0x310, 0x28, + 0x62, 0x29, 0x310, 0x28, 0x63, 0x29, 0x310, 0x28, + 0x64, 0x29, 0x310, 0x28, 0x65, 0x29, 0x310, 0x28, + 0x66, 0x29, 0x310, 0x28, 0x67, 0x29, 0x310, 0x28, + 0x68, 0x29, 0x310, 0x28, 0x69, 0x29, 0x310, 0x28, + 0x6a, 0x29, 0x310, 0x28, 0x6b, 0x29, 0x310, 0x28, + 0x6c, 0x29, 0x310, 0x28, 0x6d, 0x29, 0x310, 0x28, + 0x6e, 0x29, 0x310, 0x28, 0x6f, 0x29, 0x310, 0x28, + 0x70, 0x29, 0x310, 0x28, 0x71, 0x29, 0x310, 0x28, + 0x72, 0x29, 0x310, 0x28, 0x73, 0x29, 0x310, 0x28, + 0x74, 0x29, 0x310, 0x28, 0x75, 0x29, 0x310, 0x28, + 0x76, 0x29, 0x310, 0x28, 0x77, 0x29, 0x310, 0x28, + 0x78, 0x29, 0x310, 0x28, 0x79, 0x29, 0x310, 0x28, + 0x7a, 0x29, 0x108, 0x41, 0x108, 0x42, 0x108, 0x43, + 0x108, 0x44, 0x108, 0x45, 0x108, 0x46, 0x108, 0x47, + 0x108, 0x48, 0x108, 0x49, 0x108, 0x4a, 0x108, 0x4b, + 0x108, 0x4c, 0x108, 0x4d, 0x108, 0x4e, 0x108, 0x4f, + 0x108, 0x50, 0x108, 0x51, 0x108, 0x52, 0x108, 0x53, + 0x108, 0x54, 0x108, 0x55, 0x108, 0x56, 0x108, 0x57, + 0x108, 0x58, 0x108, 0x59, 0x108, 0x5a, 0x108, 0x61, + 0x108, 0x62, 0x108, 0x63, 0x108, 0x64, 0x108, 0x65, + 0x108, 0x66, 0x108, 0x67, 0x108, 0x68, 0x108, 0x69, + 0x108, 0x6a, 0x108, 0x6b, 0x108, 0x6c, 0x108, 0x6d, + 0x108, 0x6e, 0x108, 0x6f, 0x108, 0x70, 0x108, 0x71, + 0x108, 0x72, 0x108, 0x73, 0x108, 0x74, 0x108, 0x75, + 0x108, 0x76, 0x108, 0x77, 0x108, 0x78, 0x108, 0x79, + 0x108, 0x7a, 0x108, 0x30, 0x410, 0x222b, 0x222b, 0x222b, + 0x222b, 0x310, 0x3a, 0x3a, 0x3d, 0x210, 0x3d, 0x3d, + 0x310, 0x3d, 0x3d, 0x3d, 0x201, 0x2add, 0x338, 0x109, + 0x2d61, 0x110, 0x6bcd, 0x110, 0x9f9f, 0x110, 0x4e00, 0x110, + 0x4e28, 0x110, 0x4e36, 0x110, 0x4e3f, 0x110, 0x4e59, 0x110, + 0x4e85, 0x110, 0x4e8c, 0x110, 0x4ea0, 0x110, 0x4eba, 0x110, + 0x513f, 0x110, 0x5165, 0x110, 0x516b, 0x110, 0x5182, 0x110, + 0x5196, 0x110, 0x51ab, 0x110, 0x51e0, 0x110, 0x51f5, 0x110, + 0x5200, 0x110, 0x529b, 0x110, 0x52f9, 0x110, 0x5315, 0x110, + 0x531a, 0x110, 0x5338, 0x110, 0x5341, 0x110, 0x535c, 0x110, + 0x5369, 0x110, 0x5382, 0x110, 0x53b6, 0x110, 0x53c8, 0x110, + 0x53e3, 0x110, 0x56d7, 0x110, 0x571f, 0x110, 0x58eb, 0x110, + 0x5902, 0x110, 0x590a, 0x110, 0x5915, 0x110, 0x5927, 0x110, + 0x5973, 0x110, 0x5b50, 0x110, 0x5b80, 0x110, 0x5bf8, 0x110, + 0x5c0f, 0x110, 0x5c22, 0x110, 0x5c38, 0x110, 0x5c6e, 0x110, + 0x5c71, 0x110, 0x5ddb, 0x110, 0x5de5, 0x110, 0x5df1, 0x110, + 0x5dfe, 0x110, 0x5e72, 0x110, 0x5e7a, 0x110, 0x5e7f, 0x110, + 0x5ef4, 0x110, 0x5efe, 0x110, 0x5f0b, 0x110, 0x5f13, 0x110, + 0x5f50, 0x110, 0x5f61, 0x110, 0x5f73, 0x110, 0x5fc3, 0x110, + 0x6208, 0x110, 0x6236, 0x110, 0x624b, 0x110, 0x652f, 0x110, + 0x6534, 0x110, 0x6587, 0x110, 0x6597, 0x110, 0x65a4, 0x110, + 0x65b9, 0x110, 0x65e0, 0x110, 0x65e5, 0x110, 0x66f0, 0x110, + 0x6708, 0x110, 0x6728, 0x110, 0x6b20, 0x110, 0x6b62, 0x110, + 0x6b79, 0x110, 0x6bb3, 0x110, 0x6bcb, 0x110, 0x6bd4, 0x110, + 0x6bdb, 0x110, 0x6c0f, 0x110, 0x6c14, 0x110, 0x6c34, 0x110, + 0x706b, 0x110, 0x722a, 0x110, 0x7236, 0x110, 0x723b, 0x110, + 0x723f, 0x110, 0x7247, 0x110, 0x7259, 0x110, 0x725b, 0x110, + 0x72ac, 0x110, 0x7384, 0x110, 0x7389, 0x110, 0x74dc, 0x110, + 0x74e6, 0x110, 0x7518, 0x110, 0x751f, 0x110, 0x7528, 0x110, + 0x7530, 0x110, 0x758b, 0x110, 0x7592, 0x110, 0x7676, 0x110, + 0x767d, 0x110, 0x76ae, 0x110, 0x76bf, 0x110, 0x76ee, 0x110, + 0x77db, 0x110, 0x77e2, 0x110, 0x77f3, 0x110, 0x793a, 0x110, + 0x79b8, 0x110, 0x79be, 0x110, 0x7a74, 0x110, 0x7acb, 0x110, + 0x7af9, 0x110, 0x7c73, 0x110, 0x7cf8, 0x110, 0x7f36, 0x110, + 0x7f51, 0x110, 0x7f8a, 0x110, 0x7fbd, 0x110, 0x8001, 0x110, + 0x800c, 0x110, 0x8012, 0x110, 0x8033, 0x110, 0x807f, 0x110, + 0x8089, 0x110, 0x81e3, 0x110, 0x81ea, 0x110, 0x81f3, 0x110, + 0x81fc, 0x110, 0x820c, 0x110, 0x821b, 0x110, 0x821f, 0x110, + 0x826e, 0x110, 0x8272, 0x110, 0x8278, 0x110, 0x864d, 0x110, + 0x866b, 0x110, 0x8840, 0x110, 0x884c, 0x110, 0x8863, 0x110, + 0x897e, 0x110, 0x898b, 0x110, 0x89d2, 0x110, 0x8a00, 0x110, + 0x8c37, 0x110, 0x8c46, 0x110, 0x8c55, 0x110, 0x8c78, 0x110, + 0x8c9d, 0x110, 0x8d64, 0x110, 0x8d70, 0x110, 0x8db3, 0x110, + 0x8eab, 0x110, 0x8eca, 0x110, 0x8f9b, 0x110, 0x8fb0, 0x110, + 0x8fb5, 0x110, 0x9091, 0x110, 0x9149, 0x110, 0x91c6, 0x110, + 0x91cc, 0x110, 0x91d1, 0x110, 0x9577, 0x110, 0x9580, 0x110, + 0x961c, 0x110, 0x96b6, 0x110, 0x96b9, 0x110, 0x96e8, 0x110, + 0x9751, 0x110, 0x975e, 0x110, 0x9762, 0x110, 0x9769, 0x110, + 0x97cb, 0x110, 0x97ed, 0x110, 0x97f3, 0x110, 0x9801, 0x110, + 0x98a8, 0x110, 0x98db, 0x110, 0x98df, 0x110, 0x9996, 0x110, + 0x9999, 0x110, 0x99ac, 0x110, 0x9aa8, 0x110, 0x9ad8, 0x110, + 0x9adf, 0x110, 0x9b25, 0x110, 0x9b2f, 0x110, 0x9b32, 0x110, + 0x9b3c, 0x110, 0x9b5a, 0x110, 0x9ce5, 0x110, 0x9e75, 0x110, + 0x9e7f, 0x110, 0x9ea5, 0x110, 0x9ebb, 0x110, 0x9ec3, 0x110, + 0x9ecd, 0x110, 0x9ed1, 0x110, 0x9ef9, 0x110, 0x9efd, 0x110, + 0x9f0e, 0x110, 0x9f13, 0x110, 0x9f20, 0x110, 0x9f3b, 0x110, + 0x9f4a, 0x110, 0x9f52, 0x110, 0x9f8d, 0x110, 0x9f9c, 0x110, + 0x9fa0, 0x10c, 0x20, 0x110, 0x3012, 0x110, 0x5341, 0x110, + 0x5344, 0x110, 0x5345, 0x201, 0x304b, 0x3099, 0x201, 0x304d, + 0x3099, 0x201, 0x304f, 0x3099, 0x201, 0x3051, 0x3099, 0x201, + 0x3053, 0x3099, 0x201, 0x3055, 0x3099, 0x201, 0x3057, 0x3099, + 0x201, 0x3059, 0x3099, 0x201, 0x305b, 0x3099, 0x201, 0x305d, + 0x3099, 0x201, 0x305f, 0x3099, 0x201, 0x3061, 0x3099, 0x201, + 0x3064, 0x3099, 0x201, 0x3066, 0x3099, 0x201, 0x3068, 0x3099, + 0x201, 0x306f, 0x3099, 0x201, 0x306f, 0x309a, 0x201, 0x3072, + 0x3099, 0x201, 0x3072, 0x309a, 0x201, 0x3075, 0x3099, 0x201, + 0x3075, 0x309a, 0x201, 0x3078, 0x3099, 0x201, 0x3078, 0x309a, + 0x201, 0x307b, 0x3099, 0x201, 0x307b, 0x309a, 0x201, 0x3046, + 0x3099, 0x210, 0x20, 0x3099, 0x210, 0x20, 0x309a, 0x201, + 0x309d, 0x3099, 0x20b, 0x3088, 0x308a, 0x201, 0x30ab, 0x3099, + 0x201, 0x30ad, 0x3099, 0x201, 0x30af, 0x3099, 0x201, 0x30b1, + 0x3099, 0x201, 0x30b3, 0x3099, 0x201, 0x30b5, 0x3099, 0x201, + 0x30b7, 0x3099, 0x201, 0x30b9, 0x3099, 0x201, 0x30bb, 0x3099, + 0x201, 0x30bd, 0x3099, 0x201, 0x30bf, 0x3099, 0x201, 0x30c1, + 0x3099, 0x201, 0x30c4, 0x3099, 0x201, 0x30c6, 0x3099, 0x201, + 0x30c8, 0x3099, 0x201, 0x30cf, 0x3099, 0x201, 0x30cf, 0x309a, + 0x201, 0x30d2, 0x3099, 0x201, 0x30d2, 0x309a, 0x201, 0x30d5, + 0x3099, 0x201, 0x30d5, 0x309a, 0x201, 0x30d8, 0x3099, 0x201, + 0x30d8, 0x309a, 0x201, 0x30db, 0x3099, 0x201, 0x30db, 0x309a, + 0x201, 0x30a6, 0x3099, 0x201, 0x30ef, 0x3099, 0x201, 0x30f0, + 0x3099, 0x201, 0x30f1, 0x3099, 0x201, 0x30f2, 0x3099, 0x201, + 0x30fd, 0x3099, 0x20b, 0x30b3, 0x30c8, 0x110, 0x1100, 0x110, + 0x1101, 0x110, 0x11aa, 0x110, 0x1102, 0x110, 0x11ac, 0x110, + 0x11ad, 0x110, 0x1103, 0x110, 0x1104, 0x110, 0x1105, 0x110, + 0x11b0, 0x110, 0x11b1, 0x110, 0x11b2, 0x110, 0x11b3, 0x110, + 0x11b4, 0x110, 0x11b5, 0x110, 0x111a, 0x110, 0x1106, 0x110, + 0x1107, 0x110, 0x1108, 0x110, 0x1121, 0x110, 0x1109, 0x110, + 0x110a, 0x110, 0x110b, 0x110, 0x110c, 0x110, 0x110d, 0x110, + 0x110e, 0x110, 0x110f, 0x110, 0x1110, 0x110, 0x1111, 0x110, + 0x1112, 0x110, 0x1161, 0x110, 0x1162, 0x110, 0x1163, 0x110, + 0x1164, 0x110, 0x1165, 0x110, 0x1166, 0x110, 0x1167, 0x110, + 0x1168, 0x110, 0x1169, 0x110, 0x116a, 0x110, 0x116b, 0x110, + 0x116c, 0x110, 0x116d, 0x110, 0x116e, 0x110, 0x116f, 0x110, + 0x1170, 0x110, 0x1171, 0x110, 0x1172, 0x110, 0x1173, 0x110, + 0x1174, 0x110, 0x1175, 0x110, 0x1160, 0x110, 0x1114, 0x110, + 0x1115, 0x110, 0x11c7, 0x110, 0x11c8, 0x110, 0x11cc, 0x110, + 0x11ce, 0x110, 0x11d3, 0x110, 0x11d7, 0x110, 0x11d9, 0x110, + 0x111c, 0x110, 0x11dd, 0x110, 0x11df, 0x110, 0x111d, 0x110, + 0x111e, 0x110, 0x1120, 0x110, 0x1122, 0x110, 0x1123, 0x110, + 0x1127, 0x110, 0x1129, 0x110, 0x112b, 0x110, 0x112c, 0x110, + 0x112d, 0x110, 0x112e, 0x110, 0x112f, 0x110, 0x1132, 0x110, + 0x1136, 0x110, 0x1140, 0x110, 0x1147, 0x110, 0x114c, 0x110, + 0x11f1, 0x110, 0x11f2, 0x110, 0x1157, 0x110, 0x1158, 0x110, + 0x1159, 0x110, 0x1184, 0x110, 0x1185, 0x110, 0x1188, 0x110, + 0x1191, 0x110, 0x1192, 0x110, 0x1194, 0x110, 0x119e, 0x110, + 0x11a1, 0x109, 0x4e00, 0x109, 0x4e8c, 0x109, 0x4e09, 0x109, + 0x56db, 0x109, 0x4e0a, 0x109, 0x4e2d, 0x109, 0x4e0b, 0x109, + 0x7532, 0x109, 0x4e59, 0x109, 0x4e19, 0x109, 0x4e01, 0x109, + 0x5929, 0x109, 0x5730, 0x109, 0x4eba, 0x310, 0x28, 0x1100, + 0x29, 0x310, 0x28, 0x1102, 0x29, 0x310, 0x28, 0x1103, + 0x29, 0x310, 0x28, 0x1105, 0x29, 0x310, 0x28, 0x1106, + 0x29, 0x310, 0x28, 0x1107, 0x29, 0x310, 0x28, 0x1109, + 0x29, 0x310, 0x28, 0x110b, 0x29, 0x310, 0x28, 0x110c, + 0x29, 0x310, 0x28, 0x110e, 0x29, 0x310, 0x28, 0x110f, + 0x29, 0x310, 0x28, 0x1110, 0x29, 0x310, 0x28, 0x1111, + 0x29, 0x310, 0x28, 0x1112, 0x29, 0x410, 0x28, 0x1100, + 0x1161, 0x29, 0x410, 0x28, 0x1102, 0x1161, 0x29, 0x410, + 0x28, 0x1103, 0x1161, 0x29, 0x410, 0x28, 0x1105, 0x1161, + 0x29, 0x410, 0x28, 0x1106, 0x1161, 0x29, 0x410, 0x28, + 0x1107, 0x1161, 0x29, 0x410, 0x28, 0x1109, 0x1161, 0x29, + 0x410, 0x28, 0x110b, 0x1161, 0x29, 0x410, 0x28, 0x110c, + 0x1161, 0x29, 0x410, 0x28, 0x110e, 0x1161, 0x29, 0x410, + 0x28, 0x110f, 0x1161, 0x29, 0x410, 0x28, 0x1110, 0x1161, + 0x29, 0x410, 0x28, 0x1111, 0x1161, 0x29, 0x410, 0x28, + 0x1112, 0x1161, 0x29, 0x410, 0x28, 0x110c, 0x116e, 0x29, + 0x710, 0x28, 0x110b, 0x1169, 0x110c, 0x1165, 0x11ab, 0x29, + 0x610, 0x28, 0x110b, 0x1169, 0x1112, 0x116e, 0x29, 0x310, + 0x28, 0x4e00, 0x29, 0x310, 0x28, 0x4e8c, 0x29, 0x310, + 0x28, 0x4e09, 0x29, 0x310, 0x28, 0x56db, 0x29, 0x310, + 0x28, 0x4e94, 0x29, 0x310, 0x28, 0x516d, 0x29, 0x310, + 0x28, 0x4e03, 0x29, 0x310, 0x28, 0x516b, 0x29, 0x310, + 0x28, 0x4e5d, 0x29, 0x310, 0x28, 0x5341, 0x29, 0x310, + 0x28, 0x6708, 0x29, 0x310, 0x28, 0x706b, 0x29, 0x310, + 0x28, 0x6c34, 0x29, 0x310, 0x28, 0x6728, 0x29, 0x310, + 0x28, 0x91d1, 0x29, 0x310, 0x28, 0x571f, 0x29, 0x310, + 0x28, 0x65e5, 0x29, 0x310, 0x28, 0x682a, 0x29, 0x310, + 0x28, 0x6709, 0x29, 0x310, 0x28, 0x793e, 0x29, 0x310, + 0x28, 0x540d, 0x29, 0x310, 0x28, 0x7279, 0x29, 0x310, + 0x28, 0x8ca1, 0x29, 0x310, 0x28, 0x795d, 0x29, 0x310, + 0x28, 0x52b4, 0x29, 0x310, 0x28, 0x4ee3, 0x29, 0x310, + 0x28, 0x547c, 0x29, 0x310, 0x28, 0x5b66, 0x29, 0x310, + 0x28, 0x76e3, 0x29, 0x310, 0x28, 0x4f01, 0x29, 0x310, + 0x28, 0x8cc7, 0x29, 0x310, 0x28, 0x5354, 0x29, 0x310, + 0x28, 0x796d, 0x29, 0x310, 0x28, 0x4f11, 0x29, 0x310, + 0x28, 0x81ea, 0x29, 0x310, 0x28, 0x81f3, 0x29, 0x30f, + 0x50, 0x54, 0x45, 0x208, 0x32, 0x31, 0x208, 0x32, + 0x32, 0x208, 0x32, 0x33, 0x208, 0x32, 0x34, 0x208, + 0x32, 0x35, 0x208, 0x32, 0x36, 0x208, 0x32, 0x37, + 0x208, 0x32, 0x38, 0x208, 0x32, 0x39, 0x208, 0x33, + 0x30, 0x208, 0x33, 0x31, 0x208, 0x33, 0x32, 0x208, + 0x33, 0x33, 0x208, 0x33, 0x34, 0x208, 0x33, 0x35, + 0x108, 0x1100, 0x108, 0x1102, 0x108, 0x1103, 0x108, 0x1105, + 0x108, 0x1106, 0x108, 0x1107, 0x108, 0x1109, 0x108, 0x110b, + 0x108, 0x110c, 0x108, 0x110e, 0x108, 0x110f, 0x108, 0x1110, + 0x108, 0x1111, 0x108, 0x1112, 0x208, 0x1100, 0x1161, 0x208, + 0x1102, 0x1161, 0x208, 0x1103, 0x1161, 0x208, 0x1105, 0x1161, + 0x208, 0x1106, 0x1161, 0x208, 0x1107, 0x1161, 0x208, 0x1109, + 0x1161, 0x208, 0x110b, 0x1161, 0x208, 0x110c, 0x1161, 0x208, + 0x110e, 0x1161, 0x208, 0x110f, 0x1161, 0x208, 0x1110, 0x1161, + 0x208, 0x1111, 0x1161, 0x208, 0x1112, 0x1161, 0x508, 0x110e, + 0x1161, 0x11b7, 0x1100, 0x1169, 0x408, 0x110c, 0x116e, 0x110b, + 0x1174, 0x208, 0x110b, 0x116e, 0x108, 0x4e00, 0x108, 0x4e8c, + 0x108, 0x4e09, 0x108, 0x56db, 0x108, 0x4e94, 0x108, 0x516d, + 0x108, 0x4e03, 0x108, 0x516b, 0x108, 0x4e5d, 0x108, 0x5341, + 0x108, 0x6708, 0x108, 0x706b, 0x108, 0x6c34, 0x108, 0x6728, + 0x108, 0x91d1, 0x108, 0x571f, 0x108, 0x65e5, 0x108, 0x682a, + 0x108, 0x6709, 0x108, 0x793e, 0x108, 0x540d, 0x108, 0x7279, + 0x108, 0x8ca1, 0x108, 0x795d, 0x108, 0x52b4, 0x108, 0x79d8, + 0x108, 0x7537, 0x108, 0x5973, 0x108, 0x9069, 0x108, 0x512a, + 0x108, 0x5370, 0x108, 0x6ce8, 0x108, 0x9805, 0x108, 0x4f11, + 0x108, 0x5199, 0x108, 0x6b63, 0x108, 0x4e0a, 0x108, 0x4e2d, + 0x108, 0x4e0b, 0x108, 0x5de6, 0x108, 0x53f3, 0x108, 0x533b, + 0x108, 0x5b97, 0x108, 0x5b66, 0x108, 0x76e3, 0x108, 0x4f01, + 0x108, 0x8cc7, 0x108, 0x5354, 0x108, 0x591c, 0x208, 0x33, + 0x36, 0x208, 0x33, 0x37, 0x208, 0x33, 0x38, 0x208, + 0x33, 0x39, 0x208, 0x34, 0x30, 0x208, 0x34, 0x31, + 0x208, 0x34, 0x32, 0x208, 0x34, 0x33, 0x208, 0x34, + 0x34, 0x208, 0x34, 0x35, 0x208, 0x34, 0x36, 0x208, + 0x34, 0x37, 0x208, 0x34, 0x38, 0x208, 0x34, 0x39, + 0x208, 0x35, 0x30, 0x210, 0x31, 0x6708, 0x210, 0x32, + 0x6708, 0x210, 0x33, 0x6708, 0x210, 0x34, 0x6708, 0x210, + 0x35, 0x6708, 0x210, 0x36, 0x6708, 0x210, 0x37, 0x6708, + 0x210, 0x38, 0x6708, 0x210, 0x39, 0x6708, 0x310, 0x31, + 0x30, 0x6708, 0x310, 0x31, 0x31, 0x6708, 0x310, 0x31, + 0x32, 0x6708, 0x20f, 0x48, 0x67, 0x30f, 0x65, 0x72, + 0x67, 0x20f, 0x65, 0x56, 0x30f, 0x4c, 0x54, 0x44, + 0x108, 0x30a2, 0x108, 0x30a4, 0x108, 0x30a6, 0x108, 0x30a8, + 0x108, 0x30aa, 0x108, 0x30ab, 0x108, 0x30ad, 0x108, 0x30af, + 0x108, 0x30b1, 0x108, 0x30b3, 0x108, 0x30b5, 0x108, 0x30b7, + 0x108, 0x30b9, 0x108, 0x30bb, 0x108, 0x30bd, 0x108, 0x30bf, + 0x108, 0x30c1, 0x108, 0x30c4, 0x108, 0x30c6, 0x108, 0x30c8, + 0x108, 0x30ca, 0x108, 0x30cb, 0x108, 0x30cc, 0x108, 0x30cd, + 0x108, 0x30ce, 0x108, 0x30cf, 0x108, 0x30d2, 0x108, 0x30d5, + 0x108, 0x30d8, 0x108, 0x30db, 0x108, 0x30de, 0x108, 0x30df, + 0x108, 0x30e0, 0x108, 0x30e1, 0x108, 0x30e2, 0x108, 0x30e4, + 0x108, 0x30e6, 0x108, 0x30e8, 0x108, 0x30e9, 0x108, 0x30ea, + 0x108, 0x30eb, 0x108, 0x30ec, 0x108, 0x30ed, 0x108, 0x30ef, + 0x108, 0x30f0, 0x108, 0x30f1, 0x108, 0x30f2, 0x40f, 0x30a2, + 0x30d1, 0x30fc, 0x30c8, 0x40f, 0x30a2, 0x30eb, 0x30d5, 0x30a1, + 0x40f, 0x30a2, 0x30f3, 0x30da, 0x30a2, 0x30f, 0x30a2, 0x30fc, + 0x30eb, 0x40f, 0x30a4, 0x30cb, 0x30f3, 0x30b0, 0x30f, 0x30a4, + 0x30f3, 0x30c1, 0x30f, 0x30a6, 0x30a9, 0x30f3, 0x50f, 0x30a8, + 0x30b9, 0x30af, 0x30fc, 0x30c9, 0x40f, 0x30a8, 0x30fc, 0x30ab, + 0x30fc, 0x30f, 0x30aa, 0x30f3, 0x30b9, 0x30f, 0x30aa, 0x30fc, + 0x30e0, 0x30f, 0x30ab, 0x30a4, 0x30ea, 0x40f, 0x30ab, 0x30e9, + 0x30c3, 0x30c8, 0x40f, 0x30ab, 0x30ed, 0x30ea, 0x30fc, 0x30f, + 0x30ac, 0x30ed, 0x30f3, 0x30f, 0x30ac, 0x30f3, 0x30de, 0x20f, + 0x30ae, 0x30ac, 0x30f, 0x30ae, 0x30cb, 0x30fc, 0x40f, 0x30ad, + 0x30e5, 0x30ea, 0x30fc, 0x40f, 0x30ae, 0x30eb, 0x30c0, 0x30fc, + 0x20f, 0x30ad, 0x30ed, 0x50f, 0x30ad, 0x30ed, 0x30b0, 0x30e9, + 0x30e0, 0x60f, 0x30ad, 0x30ed, 0x30e1, 0x30fc, 0x30c8, 0x30eb, + 0x50f, 0x30ad, 0x30ed, 0x30ef, 0x30c3, 0x30c8, 0x30f, 0x30b0, + 0x30e9, 0x30e0, 0x50f, 0x30b0, 0x30e9, 0x30e0, 0x30c8, 0x30f3, + 0x50f, 0x30af, 0x30eb, 0x30bc, 0x30a4, 0x30ed, 0x40f, 0x30af, + 0x30ed, 0x30fc, 0x30cd, 0x30f, 0x30b1, 0x30fc, 0x30b9, 0x30f, + 0x30b3, 0x30eb, 0x30ca, 0x30f, 0x30b3, 0x30fc, 0x30dd, 0x40f, + 0x30b5, 0x30a4, 0x30af, 0x30eb, 0x50f, 0x30b5, 0x30f3, 0x30c1, + 0x30fc, 0x30e0, 0x40f, 0x30b7, 0x30ea, 0x30f3, 0x30b0, 0x30f, + 0x30bb, 0x30f3, 0x30c1, 0x30f, 0x30bb, 0x30f3, 0x30c8, 0x30f, + 0x30c0, 0x30fc, 0x30b9, 0x20f, 0x30c7, 0x30b7, 0x20f, 0x30c9, + 0x30eb, 0x20f, 0x30c8, 0x30f3, 0x20f, 0x30ca, 0x30ce, 0x30f, + 0x30ce, 0x30c3, 0x30c8, 0x30f, 0x30cf, 0x30a4, 0x30c4, 0x50f, + 0x30d1, 0x30fc, 0x30bb, 0x30f3, 0x30c8, 0x30f, 0x30d1, 0x30fc, + 0x30c4, 0x40f, 0x30d0, 0x30fc, 0x30ec, 0x30eb, 0x50f, 0x30d4, + 0x30a2, 0x30b9, 0x30c8, 0x30eb, 0x30f, 0x30d4, 0x30af, 0x30eb, + 0x20f, 0x30d4, 0x30b3, 0x20f, 0x30d3, 0x30eb, 0x50f, 0x30d5, + 0x30a1, 0x30e9, 0x30c3, 0x30c9, 0x40f, 0x30d5, 0x30a3, 0x30fc, + 0x30c8, 0x50f, 0x30d6, 0x30c3, 0x30b7, 0x30a7, 0x30eb, 0x30f, + 0x30d5, 0x30e9, 0x30f3, 0x50f, 0x30d8, 0x30af, 0x30bf, 0x30fc, + 0x30eb, 0x20f, 0x30da, 0x30bd, 0x30f, 0x30da, 0x30cb, 0x30d2, + 0x30f, 0x30d8, 0x30eb, 0x30c4, 0x30f, 0x30da, 0x30f3, 0x30b9, + 0x30f, 0x30da, 0x30fc, 0x30b8, 0x30f, 0x30d9, 0x30fc, 0x30bf, + 0x40f, 0x30dd, 0x30a4, 0x30f3, 0x30c8, 0x30f, 0x30dc, 0x30eb, + 0x30c8, 0x20f, 0x30db, 0x30f3, 0x30f, 0x30dd, 0x30f3, 0x30c9, + 0x30f, 0x30db, 0x30fc, 0x30eb, 0x30f, 0x30db, 0x30fc, 0x30f3, + 0x40f, 0x30de, 0x30a4, 0x30af, 0x30ed, 0x30f, 0x30de, 0x30a4, + 0x30eb, 0x30f, 0x30de, 0x30c3, 0x30cf, 0x30f, 0x30de, 0x30eb, + 0x30af, 0x50f, 0x30de, 0x30f3, 0x30b7, 0x30e7, 0x30f3, 0x40f, + 0x30df, 0x30af, 0x30ed, 0x30f3, 0x20f, 0x30df, 0x30ea, 0x50f, + 0x30df, 0x30ea, 0x30d0, 0x30fc, 0x30eb, 0x20f, 0x30e1, 0x30ac, + 0x40f, 0x30e1, 0x30ac, 0x30c8, 0x30f3, 0x40f, 0x30e1, 0x30fc, + 0x30c8, 0x30eb, 0x30f, 0x30e4, 0x30fc, 0x30c9, 0x30f, 0x30e4, + 0x30fc, 0x30eb, 0x30f, 0x30e6, 0x30a2, 0x30f3, 0x40f, 0x30ea, + 0x30c3, 0x30c8, 0x30eb, 0x20f, 0x30ea, 0x30e9, 0x30f, 0x30eb, + 0x30d4, 0x30fc, 0x40f, 0x30eb, 0x30fc, 0x30d6, 0x30eb, 0x20f, + 0x30ec, 0x30e0, 0x50f, 0x30ec, 0x30f3, 0x30c8, 0x30b2, 0x30f3, + 0x30f, 0x30ef, 0x30c3, 0x30c8, 0x210, 0x30, 0x70b9, 0x210, + 0x31, 0x70b9, 0x210, 0x32, 0x70b9, 0x210, 0x33, 0x70b9, + 0x210, 0x34, 0x70b9, 0x210, 0x35, 0x70b9, 0x210, 0x36, + 0x70b9, 0x210, 0x37, 0x70b9, 0x210, 0x38, 0x70b9, 0x210, + 0x39, 0x70b9, 0x310, 0x31, 0x30, 0x70b9, 0x310, 0x31, + 0x31, 0x70b9, 0x310, 0x31, 0x32, 0x70b9, 0x310, 0x31, + 0x33, 0x70b9, 0x310, 0x31, 0x34, 0x70b9, 0x310, 0x31, + 0x35, 0x70b9, 0x310, 0x31, 0x36, 0x70b9, 0x310, 0x31, + 0x37, 0x70b9, 0x310, 0x31, 0x38, 0x70b9, 0x310, 0x31, + 0x39, 0x70b9, 0x310, 0x32, 0x30, 0x70b9, 0x310, 0x32, + 0x31, 0x70b9, 0x310, 0x32, 0x32, 0x70b9, 0x310, 0x32, + 0x33, 0x70b9, 0x310, 0x32, 0x34, 0x70b9, 0x30f, 0x68, + 0x50, 0x61, 0x20f, 0x64, 0x61, 0x20f, 0x41, 0x55, + 0x30f, 0x62, 0x61, 0x72, 0x20f, 0x6f, 0x56, 0x20f, + 0x70, 0x63, 0x20f, 0x64, 0x6d, 0x30f, 0x64, 0x6d, + 0xb2, 0x30f, 0x64, 0x6d, 0xb3, 0x20f, 0x49, 0x55, + 0x20f, 0x5e73, 0x6210, 0x20f, 0x662d, 0x548c, 0x20f, 0x5927, + 0x6b63, 0x20f, 0x660e, 0x6cbb, 0x40f, 0x682a, 0x5f0f, 0x4f1a, + 0x793e, 0x20f, 0x70, 0x41, 0x20f, 0x6e, 0x41, 0x20f, + 0x3bc, 0x41, 0x20f, 0x6d, 0x41, 0x20f, 0x6b, 0x41, + 0x20f, 0x4b, 0x42, 0x20f, 0x4d, 0x42, 0x20f, 0x47, + 0x42, 0x30f, 0x63, 0x61, 0x6c, 0x40f, 0x6b, 0x63, + 0x61, 0x6c, 0x20f, 0x70, 0x46, 0x20f, 0x6e, 0x46, + 0x20f, 0x3bc, 0x46, 0x20f, 0x3bc, 0x67, 0x20f, 0x6d, + 0x67, 0x20f, 0x6b, 0x67, 0x20f, 0x48, 0x7a, 0x30f, + 0x6b, 0x48, 0x7a, 0x30f, 0x4d, 0x48, 0x7a, 0x30f, + 0x47, 0x48, 0x7a, 0x30f, 0x54, 0x48, 0x7a, 0x20f, + 0x3bc, 0x2113, 0x20f, 0x6d, 0x2113, 0x20f, 0x64, 0x2113, + 0x20f, 0x6b, 0x2113, 0x20f, 0x66, 0x6d, 0x20f, 0x6e, + 0x6d, 0x20f, 0x3bc, 0x6d, 0x20f, 0x6d, 0x6d, 0x20f, + 0x63, 0x6d, 0x20f, 0x6b, 0x6d, 0x30f, 0x6d, 0x6d, + 0xb2, 0x30f, 0x63, 0x6d, 0xb2, 0x20f, 0x6d, 0xb2, + 0x30f, 0x6b, 0x6d, 0xb2, 0x30f, 0x6d, 0x6d, 0xb3, + 0x30f, 0x63, 0x6d, 0xb3, 0x20f, 0x6d, 0xb3, 0x30f, + 0x6b, 0x6d, 0xb3, 0x30f, 0x6d, 0x2215, 0x73, 0x40f, + 0x6d, 0x2215, 0x73, 0xb2, 0x20f, 0x50, 0x61, 0x30f, + 0x6b, 0x50, 0x61, 0x30f, 0x4d, 0x50, 0x61, 0x30f, + 0x47, 0x50, 0x61, 0x30f, 0x72, 0x61, 0x64, 0x50f, + 0x72, 0x61, 0x64, 0x2215, 0x73, 0x60f, 0x72, 0x61, + 0x64, 0x2215, 0x73, 0xb2, 0x20f, 0x70, 0x73, 0x20f, + 0x6e, 0x73, 0x20f, 0x3bc, 0x73, 0x20f, 0x6d, 0x73, + 0x20f, 0x70, 0x56, 0x20f, 0x6e, 0x56, 0x20f, 0x3bc, + 0x56, 0x20f, 0x6d, 0x56, 0x20f, 0x6b, 0x56, 0x20f, + 0x4d, 0x56, 0x20f, 0x70, 0x57, 0x20f, 0x6e, 0x57, + 0x20f, 0x3bc, 0x57, 0x20f, 0x6d, 0x57, 0x20f, 0x6b, + 0x57, 0x20f, 0x4d, 0x57, 0x20f, 0x6b, 0x3a9, 0x20f, + 0x4d, 0x3a9, 0x40f, 0x61, 0x2e, 0x6d, 0x2e, 0x20f, + 0x42, 0x71, 0x20f, 0x63, 0x63, 0x20f, 0x63, 0x64, + 0x40f, 0x43, 0x2215, 0x6b, 0x67, 0x30f, 0x43, 0x6f, + 0x2e, 0x20f, 0x64, 0x42, 0x20f, 0x47, 0x79, 0x20f, + 0x68, 0x61, 0x20f, 0x48, 0x50, 0x20f, 0x69, 0x6e, + 0x20f, 0x4b, 0x4b, 0x20f, 0x4b, 0x4d, 0x20f, 0x6b, + 0x74, 0x20f, 0x6c, 0x6d, 0x20f, 0x6c, 0x6e, 0x30f, + 0x6c, 0x6f, 0x67, 0x20f, 0x6c, 0x78, 0x20f, 0x6d, + 0x62, 0x30f, 0x6d, 0x69, 0x6c, 0x30f, 0x6d, 0x6f, + 0x6c, 0x20f, 0x50, 0x48, 0x40f, 0x70, 0x2e, 0x6d, + 0x2e, 0x30f, 0x50, 0x50, 0x4d, 0x20f, 0x50, 0x52, + 0x20f, 0x73, 0x72, 0x20f, 0x53, 0x76, 0x20f, 0x57, + 0x62, 0x30f, 0x56, 0x2215, 0x6d, 0x30f, 0x41, 0x2215, + 0x6d, 0x210, 0x31, 0x65e5, 0x210, 0x32, 0x65e5, 0x210, + 0x33, 0x65e5, 0x210, 0x34, 0x65e5, 0x210, 0x35, 0x65e5, + 0x210, 0x36, 0x65e5, 0x210, 0x37, 0x65e5, 0x210, 0x38, + 0x65e5, 0x210, 0x39, 0x65e5, 0x310, 0x31, 0x30, 0x65e5, + 0x310, 0x31, 0x31, 0x65e5, 0x310, 0x31, 0x32, 0x65e5, + 0x310, 0x31, 0x33, 0x65e5, 0x310, 0x31, 0x34, 0x65e5, + 0x310, 0x31, 0x35, 0x65e5, 0x310, 0x31, 0x36, 0x65e5, + 0x310, 0x31, 0x37, 0x65e5, 0x310, 0x31, 0x38, 0x65e5, + 0x310, 0x31, 0x39, 0x65e5, 0x310, 0x32, 0x30, 0x65e5, + 0x310, 0x32, 0x31, 0x65e5, 0x310, 0x32, 0x32, 0x65e5, + 0x310, 0x32, 0x33, 0x65e5, 0x310, 0x32, 0x34, 0x65e5, + 0x310, 0x32, 0x35, 0x65e5, 0x310, 0x32, 0x36, 0x65e5, + 0x310, 0x32, 0x37, 0x65e5, 0x310, 0x32, 0x38, 0x65e5, + 0x310, 0x32, 0x39, 0x65e5, 0x310, 0x33, 0x30, 0x65e5, + 0x310, 0x33, 0x31, 0x65e5, 0x30f, 0x67, 0x61, 0x6c, + 0x101, 0x8c48, 0x101, 0x66f4, 0x101, 0x8eca, 0x101, 0x8cc8, + 0x101, 0x6ed1, 0x101, 0x4e32, 0x101, 0x53e5, 0x101, 0x9f9c, + 0x101, 0x9f9c, 0x101, 0x5951, 0x101, 0x91d1, 0x101, 0x5587, + 0x101, 0x5948, 0x101, 0x61f6, 0x101, 0x7669, 0x101, 0x7f85, + 0x101, 0x863f, 0x101, 0x87ba, 0x101, 0x88f8, 0x101, 0x908f, + 0x101, 0x6a02, 0x101, 0x6d1b, 0x101, 0x70d9, 0x101, 0x73de, + 0x101, 0x843d, 0x101, 0x916a, 0x101, 0x99f1, 0x101, 0x4e82, + 0x101, 0x5375, 0x101, 0x6b04, 0x101, 0x721b, 0x101, 0x862d, + 0x101, 0x9e1e, 0x101, 0x5d50, 0x101, 0x6feb, 0x101, 0x85cd, + 0x101, 0x8964, 0x101, 0x62c9, 0x101, 0x81d8, 0x101, 0x881f, + 0x101, 0x5eca, 0x101, 0x6717, 0x101, 0x6d6a, 0x101, 0x72fc, + 0x101, 0x90ce, 0x101, 0x4f86, 0x101, 0x51b7, 0x101, 0x52de, + 0x101, 0x64c4, 0x101, 0x6ad3, 0x101, 0x7210, 0x101, 0x76e7, + 0x101, 0x8001, 0x101, 0x8606, 0x101, 0x865c, 0x101, 0x8def, + 0x101, 0x9732, 0x101, 0x9b6f, 0x101, 0x9dfa, 0x101, 0x788c, + 0x101, 0x797f, 0x101, 0x7da0, 0x101, 0x83c9, 0x101, 0x9304, + 0x101, 0x9e7f, 0x101, 0x8ad6, 0x101, 0x58df, 0x101, 0x5f04, + 0x101, 0x7c60, 0x101, 0x807e, 0x101, 0x7262, 0x101, 0x78ca, + 0x101, 0x8cc2, 0x101, 0x96f7, 0x101, 0x58d8, 0x101, 0x5c62, + 0x101, 0x6a13, 0x101, 0x6dda, 0x101, 0x6f0f, 0x101, 0x7d2f, + 0x101, 0x7e37, 0x101, 0x964b, 0x101, 0x52d2, 0x101, 0x808b, + 0x101, 0x51dc, 0x101, 0x51cc, 0x101, 0x7a1c, 0x101, 0x7dbe, + 0x101, 0x83f1, 0x101, 0x9675, 0x101, 0x8b80, 0x101, 0x62cf, + 0x101, 0x6a02, 0x101, 0x8afe, 0x101, 0x4e39, 0x101, 0x5be7, + 0x101, 0x6012, 0x101, 0x7387, 0x101, 0x7570, 0x101, 0x5317, + 0x101, 0x78fb, 0x101, 0x4fbf, 0x101, 0x5fa9, 0x101, 0x4e0d, + 0x101, 0x6ccc, 0x101, 0x6578, 0x101, 0x7d22, 0x101, 0x53c3, + 0x101, 0x585e, 0x101, 0x7701, 0x101, 0x8449, 0x101, 0x8aaa, + 0x101, 0x6bba, 0x101, 0x8fb0, 0x101, 0x6c88, 0x101, 0x62fe, + 0x101, 0x82e5, 0x101, 0x63a0, 0x101, 0x7565, 0x101, 0x4eae, + 0x101, 0x5169, 0x101, 0x51c9, 0x101, 0x6881, 0x101, 0x7ce7, + 0x101, 0x826f, 0x101, 0x8ad2, 0x101, 0x91cf, 0x101, 0x52f5, + 0x101, 0x5442, 0x101, 0x5973, 0x101, 0x5eec, 0x101, 0x65c5, + 0x101, 0x6ffe, 0x101, 0x792a, 0x101, 0x95ad, 0x101, 0x9a6a, + 0x101, 0x9e97, 0x101, 0x9ece, 0x101, 0x529b, 0x101, 0x66c6, + 0x101, 0x6b77, 0x101, 0x8f62, 0x101, 0x5e74, 0x101, 0x6190, + 0x101, 0x6200, 0x101, 0x649a, 0x101, 0x6f23, 0x101, 0x7149, + 0x101, 0x7489, 0x101, 0x79ca, 0x101, 0x7df4, 0x101, 0x806f, + 0x101, 0x8f26, 0x101, 0x84ee, 0x101, 0x9023, 0x101, 0x934a, + 0x101, 0x5217, 0x101, 0x52a3, 0x101, 0x54bd, 0x101, 0x70c8, + 0x101, 0x88c2, 0x101, 0x8aaa, 0x101, 0x5ec9, 0x101, 0x5ff5, + 0x101, 0x637b, 0x101, 0x6bae, 0x101, 0x7c3e, 0x101, 0x7375, + 0x101, 0x4ee4, 0x101, 0x56f9, 0x101, 0x5be7, 0x101, 0x5dba, + 0x101, 0x601c, 0x101, 0x73b2, 0x101, 0x7469, 0x101, 0x7f9a, + 0x101, 0x8046, 0x101, 0x9234, 0x101, 0x96f6, 0x101, 0x9748, + 0x101, 0x9818, 0x101, 0x4f8b, 0x101, 0x79ae, 0x101, 0x91b4, + 0x101, 0x96b8, 0x101, 0x60e1, 0x101, 0x4e86, 0x101, 0x50da, + 0x101, 0x5bee, 0x101, 0x5c3f, 0x101, 0x6599, 0x101, 0x6a02, + 0x101, 0x71ce, 0x101, 0x7642, 0x101, 0x84fc, 0x101, 0x907c, + 0x101, 0x9f8d, 0x101, 0x6688, 0x101, 0x962e, 0x101, 0x5289, + 0x101, 0x677b, 0x101, 0x67f3, 0x101, 0x6d41, 0x101, 0x6e9c, + 0x101, 0x7409, 0x101, 0x7559, 0x101, 0x786b, 0x101, 0x7d10, + 0x101, 0x985e, 0x101, 0x516d, 0x101, 0x622e, 0x101, 0x9678, + 0x101, 0x502b, 0x101, 0x5d19, 0x101, 0x6dea, 0x101, 0x8f2a, + 0x101, 0x5f8b, 0x101, 0x6144, 0x101, 0x6817, 0x101, 0x7387, + 0x101, 0x9686, 0x101, 0x5229, 0x101, 0x540f, 0x101, 0x5c65, + 0x101, 0x6613, 0x101, 0x674e, 0x101, 0x68a8, 0x101, 0x6ce5, + 0x101, 0x7406, 0x101, 0x75e2, 0x101, 0x7f79, 0x101, 0x88cf, + 0x101, 0x88e1, 0x101, 0x91cc, 0x101, 0x96e2, 0x101, 0x533f, + 0x101, 0x6eba, 0x101, 0x541d, 0x101, 0x71d0, 0x101, 0x7498, + 0x101, 0x85fa, 0x101, 0x96a3, 0x101, 0x9c57, 0x101, 0x9e9f, + 0x101, 0x6797, 0x101, 0x6dcb, 0x101, 0x81e8, 0x101, 0x7acb, + 0x101, 0x7b20, 0x101, 0x7c92, 0x101, 0x72c0, 0x101, 0x7099, + 0x101, 0x8b58, 0x101, 0x4ec0, 0x101, 0x8336, 0x101, 0x523a, + 0x101, 0x5207, 0x101, 0x5ea6, 0x101, 0x62d3, 0x101, 0x7cd6, + 0x101, 0x5b85, 0x101, 0x6d1e, 0x101, 0x66b4, 0x101, 0x8f3b, + 0x101, 0x884c, 0x101, 0x964d, 0x101, 0x898b, 0x101, 0x5ed3, + 0x101, 0x5140, 0x101, 0x55c0, 0x101, 0x585a, 0x101, 0x6674, + 0x101, 0x51de, 0x101, 0x732a, 0x101, 0x76ca, 0x101, 0x793c, + 0x101, 0x795e, 0x101, 0x7965, 0x101, 0x798f, 0x101, 0x9756, + 0x101, 0x7cbe, 0x101, 0x7fbd, 0x101, 0x8612, 0x101, 0x8af8, + 0x101, 0x9038, 0x101, 0x90fd, 0x101, 0x98ef, 0x101, 0x98fc, + 0x101, 0x9928, 0x101, 0x9db4, 0x101, 0x4fae, 0x101, 0x50e7, + 0x101, 0x514d, 0x101, 0x52c9, 0x101, 0x52e4, 0x101, 0x5351, + 0x101, 0x559d, 0x101, 0x5606, 0x101, 0x5668, 0x101, 0x5840, + 0x101, 0x58a8, 0x101, 0x5c64, 0x101, 0x5c6e, 0x101, 0x6094, + 0x101, 0x6168, 0x101, 0x618e, 0x101, 0x61f2, 0x101, 0x654f, + 0x101, 0x65e2, 0x101, 0x6691, 0x101, 0x6885, 0x101, 0x6d77, + 0x101, 0x6e1a, 0x101, 0x6f22, 0x101, 0x716e, 0x101, 0x722b, + 0x101, 0x7422, 0x101, 0x7891, 0x101, 0x793e, 0x101, 0x7949, + 0x101, 0x7948, 0x101, 0x7950, 0x101, 0x7956, 0x101, 0x795d, + 0x101, 0x798d, 0x101, 0x798e, 0x101, 0x7a40, 0x101, 0x7a81, + 0x101, 0x7bc0, 0x101, 0x7df4, 0x101, 0x7e09, 0x101, 0x7e41, + 0x101, 0x7f72, 0x101, 0x8005, 0x101, 0x81ed, 0x101, 0x8279, + 0x101, 0x8279, 0x101, 0x8457, 0x101, 0x8910, 0x101, 0x8996, + 0x101, 0x8b01, 0x101, 0x8b39, 0x101, 0x8cd3, 0x101, 0x8d08, + 0x101, 0x8fb6, 0x101, 0x9038, 0x101, 0x96e3, 0x101, 0x97ff, + 0x101, 0x983b, 0x101, 0x4e26, 0x101, 0x51b5, 0x101, 0x5168, + 0x101, 0x4f80, 0x101, 0x5145, 0x101, 0x5180, 0x101, 0x52c7, + 0x101, 0x52fa, 0x101, 0x559d, 0x101, 0x5555, 0x101, 0x5599, + 0x101, 0x55e2, 0x101, 0x585a, 0x101, 0x58b3, 0x101, 0x5944, + 0x101, 0x5954, 0x101, 0x5a62, 0x101, 0x5b28, 0x101, 0x5ed2, + 0x101, 0x5ed9, 0x101, 0x5f69, 0x101, 0x5fad, 0x101, 0x60d8, + 0x101, 0x614e, 0x101, 0x6108, 0x101, 0x618e, 0x101, 0x6160, + 0x101, 0x61f2, 0x101, 0x6234, 0x101, 0x63c4, 0x101, 0x641c, + 0x101, 0x6452, 0x101, 0x6556, 0x101, 0x6674, 0x101, 0x6717, + 0x101, 0x671b, 0x101, 0x6756, 0x101, 0x6b79, 0x101, 0x6bba, + 0x101, 0x6d41, 0x101, 0x6edb, 0x101, 0x6ecb, 0x101, 0x6f22, + 0x101, 0x701e, 0x101, 0x716e, 0x101, 0x77a7, 0x101, 0x7235, + 0x101, 0x72af, 0x101, 0x732a, 0x101, 0x7471, 0x101, 0x7506, + 0x101, 0x753b, 0x101, 0x761d, 0x101, 0x761f, 0x101, 0x76ca, + 0x101, 0x76db, 0x101, 0x76f4, 0x101, 0x774a, 0x101, 0x7740, + 0x101, 0x78cc, 0x101, 0x7ab1, 0x101, 0x7bc0, 0x101, 0x7c7b, + 0x101, 0x7d5b, 0x101, 0x7df4, 0x101, 0x7f3e, 0x101, 0x8005, + 0x101, 0x8352, 0x101, 0x83ef, 0x101, 0x8779, 0x101, 0x8941, + 0x101, 0x8986, 0x101, 0x8996, 0x101, 0x8abf, 0x101, 0x8af8, + 0x101, 0x8acb, 0x101, 0x8b01, 0x101, 0x8afe, 0x101, 0x8aed, + 0x101, 0x8b39, 0x101, 0x8b8a, 0x101, 0x8d08, 0x101, 0x8f38, + 0x101, 0x9072, 0x101, 0x9199, 0x101, 0x9276, 0x101, 0x967c, + 0x101, 0x96e3, 0x101, 0x9756, 0x101, 0x97db, 0x101, 0x97ff, + 0x101, 0x980b, 0x101, 0x983b, 0x101, 0x9b12, 0x101, 0x9f9c, + 0x201, 0xd84a, 0xdc4a, 0x201, 0xd84a, 0xdc44, 0x201, 0xd84c, + 0xdfd5, 0x101, 0x3b9d, 0x101, 0x4018, 0x101, 0x4039, 0x201, + 0xd854, 0xde49, 0x201, 0xd857, 0xdcd0, 0x201, 0xd85f, 0xded3, + 0x101, 0x9f43, 0x101, 0x9f8e, 0x210, 0x66, 0x66, 0x210, + 0x66, 0x69, 0x210, 0x66, 0x6c, 0x310, 0x66, 0x66, + 0x69, 0x310, 0x66, 0x66, 0x6c, 0x210, 0x17f, 0x74, + 0x210, 0x73, 0x74, 0x210, 0x574, 0x576, 0x210, 0x574, + 0x565, 0x210, 0x574, 0x56b, 0x210, 0x57e, 0x576, 0x210, + 0x574, 0x56d, 0x201, 0x5d9, 0x5b4, 0x201, 0x5f2, 0x5b7, + 0x102, 0x5e2, 0x102, 0x5d0, 0x102, 0x5d3, 0x102, 0x5d4, + 0x102, 0x5db, 0x102, 0x5dc, 0x102, 0x5dd, 0x102, 0x5e8, + 0x102, 0x5ea, 0x102, 0x2b, 0x201, 0x5e9, 0x5c1, 0x201, + 0x5e9, 0x5c2, 0x201, 0xfb49, 0x5c1, 0x201, 0xfb49, 0x5c2, + 0x201, 0x5d0, 0x5b7, 0x201, 0x5d0, 0x5b8, 0x201, 0x5d0, + 0x5bc, 0x201, 0x5d1, 0x5bc, 0x201, 0x5d2, 0x5bc, 0x201, + 0x5d3, 0x5bc, 0x201, 0x5d4, 0x5bc, 0x201, 0x5d5, 0x5bc, + 0x201, 0x5d6, 0x5bc, 0x201, 0x5d8, 0x5bc, 0x201, 0x5d9, + 0x5bc, 0x201, 0x5da, 0x5bc, 0x201, 0x5db, 0x5bc, 0x201, + 0x5dc, 0x5bc, 0x201, 0x5de, 0x5bc, 0x201, 0x5e0, 0x5bc, + 0x201, 0x5e1, 0x5bc, 0x201, 0x5e3, 0x5bc, 0x201, 0x5e4, + 0x5bc, 0x201, 0x5e6, 0x5bc, 0x201, 0x5e7, 0x5bc, 0x201, + 0x5e8, 0x5bc, 0x201, 0x5e9, 0x5bc, 0x201, 0x5ea, 0x5bc, + 0x201, 0x5d5, 0x5b9, 0x201, 0x5d1, 0x5bf, 0x201, 0x5db, + 0x5bf, 0x201, 0x5e4, 0x5bf, 0x210, 0x5d0, 0x5dc, 0x107, + 0x671, 0x106, 0x671, 0x107, 0x67b, 0x106, 0x67b, 0x104, + 0x67b, 0x105, 0x67b, 0x107, 0x67e, 0x106, 0x67e, 0x104, + 0x67e, 0x105, 0x67e, 0x107, 0x680, 0x106, 0x680, 0x104, + 0x680, 0x105, 0x680, 0x107, 0x67a, 0x106, 0x67a, 0x104, + 0x67a, 0x105, 0x67a, 0x107, 0x67f, 0x106, 0x67f, 0x104, + 0x67f, 0x105, 0x67f, 0x107, 0x679, 0x106, 0x679, 0x104, + 0x679, 0x105, 0x679, 0x107, 0x6a4, 0x106, 0x6a4, 0x104, + 0x6a4, 0x105, 0x6a4, 0x107, 0x6a6, 0x106, 0x6a6, 0x104, + 0x6a6, 0x105, 0x6a6, 0x107, 0x684, 0x106, 0x684, 0x104, + 0x684, 0x105, 0x684, 0x107, 0x683, 0x106, 0x683, 0x104, + 0x683, 0x105, 0x683, 0x107, 0x686, 0x106, 0x686, 0x104, + 0x686, 0x105, 0x686, 0x107, 0x687, 0x106, 0x687, 0x104, + 0x687, 0x105, 0x687, 0x107, 0x68d, 0x106, 0x68d, 0x107, + 0x68c, 0x106, 0x68c, 0x107, 0x68e, 0x106, 0x68e, 0x107, + 0x688, 0x106, 0x688, 0x107, 0x698, 0x106, 0x698, 0x107, + 0x691, 0x106, 0x691, 0x107, 0x6a9, 0x106, 0x6a9, 0x104, + 0x6a9, 0x105, 0x6a9, 0x107, 0x6af, 0x106, 0x6af, 0x104, + 0x6af, 0x105, 0x6af, 0x107, 0x6b3, 0x106, 0x6b3, 0x104, + 0x6b3, 0x105, 0x6b3, 0x107, 0x6b1, 0x106, 0x6b1, 0x104, + 0x6b1, 0x105, 0x6b1, 0x107, 0x6ba, 0x106, 0x6ba, 0x107, + 0x6bb, 0x106, 0x6bb, 0x104, 0x6bb, 0x105, 0x6bb, 0x107, + 0x6c0, 0x106, 0x6c0, 0x107, 0x6c1, 0x106, 0x6c1, 0x104, + 0x6c1, 0x105, 0x6c1, 0x107, 0x6be, 0x106, 0x6be, 0x104, + 0x6be, 0x105, 0x6be, 0x107, 0x6d2, 0x106, 0x6d2, 0x107, + 0x6d3, 0x106, 0x6d3, 0x107, 0x6ad, 0x106, 0x6ad, 0x104, + 0x6ad, 0x105, 0x6ad, 0x107, 0x6c7, 0x106, 0x6c7, 0x107, + 0x6c6, 0x106, 0x6c6, 0x107, 0x6c8, 0x106, 0x6c8, 0x107, + 0x677, 0x107, 0x6cb, 0x106, 0x6cb, 0x107, 0x6c5, 0x106, + 0x6c5, 0x107, 0x6c9, 0x106, 0x6c9, 0x107, 0x6d0, 0x106, + 0x6d0, 0x104, 0x6d0, 0x105, 0x6d0, 0x104, 0x649, 0x105, + 0x649, 0x207, 0x626, 0x627, 0x206, 0x626, 0x627, 0x207, + 0x626, 0x6d5, 0x206, 0x626, 0x6d5, 0x207, 0x626, 0x648, + 0x206, 0x626, 0x648, 0x207, 0x626, 0x6c7, 0x206, 0x626, + 0x6c7, 0x207, 0x626, 0x6c6, 0x206, 0x626, 0x6c6, 0x207, + 0x626, 0x6c8, 0x206, 0x626, 0x6c8, 0x207, 0x626, 0x6d0, + 0x206, 0x626, 0x6d0, 0x204, 0x626, 0x6d0, 0x207, 0x626, + 0x649, 0x206, 0x626, 0x649, 0x204, 0x626, 0x649, 0x107, + 0x6cc, 0x106, 0x6cc, 0x104, 0x6cc, 0x105, 0x6cc, 0x207, + 0x626, 0x62c, 0x207, 0x626, 0x62d, 0x207, 0x626, 0x645, + 0x207, 0x626, 0x649, 0x207, 0x626, 0x64a, 0x207, 0x628, + 0x62c, 0x207, 0x628, 0x62d, 0x207, 0x628, 0x62e, 0x207, + 0x628, 0x645, 0x207, 0x628, 0x649, 0x207, 0x628, 0x64a, + 0x207, 0x62a, 0x62c, 0x207, 0x62a, 0x62d, 0x207, 0x62a, + 0x62e, 0x207, 0x62a, 0x645, 0x207, 0x62a, 0x649, 0x207, + 0x62a, 0x64a, 0x207, 0x62b, 0x62c, 0x207, 0x62b, 0x645, + 0x207, 0x62b, 0x649, 0x207, 0x62b, 0x64a, 0x207, 0x62c, + 0x62d, 0x207, 0x62c, 0x645, 0x207, 0x62d, 0x62c, 0x207, + 0x62d, 0x645, 0x207, 0x62e, 0x62c, 0x207, 0x62e, 0x62d, + 0x207, 0x62e, 0x645, 0x207, 0x633, 0x62c, 0x207, 0x633, + 0x62d, 0x207, 0x633, 0x62e, 0x207, 0x633, 0x645, 0x207, + 0x635, 0x62d, 0x207, 0x635, 0x645, 0x207, 0x636, 0x62c, + 0x207, 0x636, 0x62d, 0x207, 0x636, 0x62e, 0x207, 0x636, + 0x645, 0x207, 0x637, 0x62d, 0x207, 0x637, 0x645, 0x207, + 0x638, 0x645, 0x207, 0x639, 0x62c, 0x207, 0x639, 0x645, + 0x207, 0x63a, 0x62c, 0x207, 0x63a, 0x645, 0x207, 0x641, + 0x62c, 0x207, 0x641, 0x62d, 0x207, 0x641, 0x62e, 0x207, + 0x641, 0x645, 0x207, 0x641, 0x649, 0x207, 0x641, 0x64a, + 0x207, 0x642, 0x62d, 0x207, 0x642, 0x645, 0x207, 0x642, + 0x649, 0x207, 0x642, 0x64a, 0x207, 0x643, 0x627, 0x207, + 0x643, 0x62c, 0x207, 0x643, 0x62d, 0x207, 0x643, 0x62e, + 0x207, 0x643, 0x644, 0x207, 0x643, 0x645, 0x207, 0x643, + 0x649, 0x207, 0x643, 0x64a, 0x207, 0x644, 0x62c, 0x207, + 0x644, 0x62d, 0x207, 0x644, 0x62e, 0x207, 0x644, 0x645, + 0x207, 0x644, 0x649, 0x207, 0x644, 0x64a, 0x207, 0x645, + 0x62c, 0x207, 0x645, 0x62d, 0x207, 0x645, 0x62e, 0x207, + 0x645, 0x645, 0x207, 0x645, 0x649, 0x207, 0x645, 0x64a, + 0x207, 0x646, 0x62c, 0x207, 0x646, 0x62d, 0x207, 0x646, + 0x62e, 0x207, 0x646, 0x645, 0x207, 0x646, 0x649, 0x207, + 0x646, 0x64a, 0x207, 0x647, 0x62c, 0x207, 0x647, 0x645, + 0x207, 0x647, 0x649, 0x207, 0x647, 0x64a, 0x207, 0x64a, + 0x62c, 0x207, 0x64a, 0x62d, 0x207, 0x64a, 0x62e, 0x207, + 0x64a, 0x645, 0x207, 0x64a, 0x649, 0x207, 0x64a, 0x64a, + 0x207, 0x630, 0x670, 0x207, 0x631, 0x670, 0x207, 0x649, + 0x670, 0x307, 0x20, 0x64c, 0x651, 0x307, 0x20, 0x64d, + 0x651, 0x307, 0x20, 0x64e, 0x651, 0x307, 0x20, 0x64f, + 0x651, 0x307, 0x20, 0x650, 0x651, 0x307, 0x20, 0x651, + 0x670, 0x206, 0x626, 0x631, 0x206, 0x626, 0x632, 0x206, + 0x626, 0x645, 0x206, 0x626, 0x646, 0x206, 0x626, 0x649, + 0x206, 0x626, 0x64a, 0x206, 0x628, 0x631, 0x206, 0x628, + 0x632, 0x206, 0x628, 0x645, 0x206, 0x628, 0x646, 0x206, + 0x628, 0x649, 0x206, 0x628, 0x64a, 0x206, 0x62a, 0x631, + 0x206, 0x62a, 0x632, 0x206, 0x62a, 0x645, 0x206, 0x62a, + 0x646, 0x206, 0x62a, 0x649, 0x206, 0x62a, 0x64a, 0x206, + 0x62b, 0x631, 0x206, 0x62b, 0x632, 0x206, 0x62b, 0x645, + 0x206, 0x62b, 0x646, 0x206, 0x62b, 0x649, 0x206, 0x62b, + 0x64a, 0x206, 0x641, 0x649, 0x206, 0x641, 0x64a, 0x206, + 0x642, 0x649, 0x206, 0x642, 0x64a, 0x206, 0x643, 0x627, + 0x206, 0x643, 0x644, 0x206, 0x643, 0x645, 0x206, 0x643, + 0x649, 0x206, 0x643, 0x64a, 0x206, 0x644, 0x645, 0x206, + 0x644, 0x649, 0x206, 0x644, 0x64a, 0x206, 0x645, 0x627, + 0x206, 0x645, 0x645, 0x206, 0x646, 0x631, 0x206, 0x646, + 0x632, 0x206, 0x646, 0x645, 0x206, 0x646, 0x646, 0x206, + 0x646, 0x649, 0x206, 0x646, 0x64a, 0x206, 0x649, 0x670, + 0x206, 0x64a, 0x631, 0x206, 0x64a, 0x632, 0x206, 0x64a, + 0x645, 0x206, 0x64a, 0x646, 0x206, 0x64a, 0x649, 0x206, + 0x64a, 0x64a, 0x204, 0x626, 0x62c, 0x204, 0x626, 0x62d, + 0x204, 0x626, 0x62e, 0x204, 0x626, 0x645, 0x204, 0x626, + 0x647, 0x204, 0x628, 0x62c, 0x204, 0x628, 0x62d, 0x204, + 0x628, 0x62e, 0x204, 0x628, 0x645, 0x204, 0x628, 0x647, + 0x204, 0x62a, 0x62c, 0x204, 0x62a, 0x62d, 0x204, 0x62a, + 0x62e, 0x204, 0x62a, 0x645, 0x204, 0x62a, 0x647, 0x204, + 0x62b, 0x645, 0x204, 0x62c, 0x62d, 0x204, 0x62c, 0x645, + 0x204, 0x62d, 0x62c, 0x204, 0x62d, 0x645, 0x204, 0x62e, + 0x62c, 0x204, 0x62e, 0x645, 0x204, 0x633, 0x62c, 0x204, + 0x633, 0x62d, 0x204, 0x633, 0x62e, 0x204, 0x633, 0x645, + 0x204, 0x635, 0x62d, 0x204, 0x635, 0x62e, 0x204, 0x635, + 0x645, 0x204, 0x636, 0x62c, 0x204, 0x636, 0x62d, 0x204, + 0x636, 0x62e, 0x204, 0x636, 0x645, 0x204, 0x637, 0x62d, + 0x204, 0x638, 0x645, 0x204, 0x639, 0x62c, 0x204, 0x639, + 0x645, 0x204, 0x63a, 0x62c, 0x204, 0x63a, 0x645, 0x204, + 0x641, 0x62c, 0x204, 0x641, 0x62d, 0x204, 0x641, 0x62e, + 0x204, 0x641, 0x645, 0x204, 0x642, 0x62d, 0x204, 0x642, + 0x645, 0x204, 0x643, 0x62c, 0x204, 0x643, 0x62d, 0x204, + 0x643, 0x62e, 0x204, 0x643, 0x644, 0x204, 0x643, 0x645, + 0x204, 0x644, 0x62c, 0x204, 0x644, 0x62d, 0x204, 0x644, + 0x62e, 0x204, 0x644, 0x645, 0x204, 0x644, 0x647, 0x204, + 0x645, 0x62c, 0x204, 0x645, 0x62d, 0x204, 0x645, 0x62e, + 0x204, 0x645, 0x645, 0x204, 0x646, 0x62c, 0x204, 0x646, + 0x62d, 0x204, 0x646, 0x62e, 0x204, 0x646, 0x645, 0x204, + 0x646, 0x647, 0x204, 0x647, 0x62c, 0x204, 0x647, 0x645, + 0x204, 0x647, 0x670, 0x204, 0x64a, 0x62c, 0x204, 0x64a, + 0x62d, 0x204, 0x64a, 0x62e, 0x204, 0x64a, 0x645, 0x204, + 0x64a, 0x647, 0x205, 0x626, 0x645, 0x205, 0x626, 0x647, + 0x205, 0x628, 0x645, 0x205, 0x628, 0x647, 0x205, 0x62a, + 0x645, 0x205, 0x62a, 0x647, 0x205, 0x62b, 0x645, 0x205, + 0x62b, 0x647, 0x205, 0x633, 0x645, 0x205, 0x633, 0x647, + 0x205, 0x634, 0x645, 0x205, 0x634, 0x647, 0x205, 0x643, + 0x644, 0x205, 0x643, 0x645, 0x205, 0x644, 0x645, 0x205, + 0x646, 0x645, 0x205, 0x646, 0x647, 0x205, 0x64a, 0x645, + 0x205, 0x64a, 0x647, 0x305, 0x640, 0x64e, 0x651, 0x305, + 0x640, 0x64f, 0x651, 0x305, 0x640, 0x650, 0x651, 0x207, + 0x637, 0x649, 0x207, 0x637, 0x64a, 0x207, 0x639, 0x649, + 0x207, 0x639, 0x64a, 0x207, 0x63a, 0x649, 0x207, 0x63a, + 0x64a, 0x207, 0x633, 0x649, 0x207, 0x633, 0x64a, 0x207, + 0x634, 0x649, 0x207, 0x634, 0x64a, 0x207, 0x62d, 0x649, + 0x207, 0x62d, 0x64a, 0x207, 0x62c, 0x649, 0x207, 0x62c, + 0x64a, 0x207, 0x62e, 0x649, 0x207, 0x62e, 0x64a, 0x207, + 0x635, 0x649, 0x207, 0x635, 0x64a, 0x207, 0x636, 0x649, + 0x207, 0x636, 0x64a, 0x207, 0x634, 0x62c, 0x207, 0x634, + 0x62d, 0x207, 0x634, 0x62e, 0x207, 0x634, 0x645, 0x207, + 0x634, 0x631, 0x207, 0x633, 0x631, 0x207, 0x635, 0x631, + 0x207, 0x636, 0x631, 0x206, 0x637, 0x649, 0x206, 0x637, + 0x64a, 0x206, 0x639, 0x649, 0x206, 0x639, 0x64a, 0x206, + 0x63a, 0x649, 0x206, 0x63a, 0x64a, 0x206, 0x633, 0x649, + 0x206, 0x633, 0x64a, 0x206, 0x634, 0x649, 0x206, 0x634, + 0x64a, 0x206, 0x62d, 0x649, 0x206, 0x62d, 0x64a, 0x206, + 0x62c, 0x649, 0x206, 0x62c, 0x64a, 0x206, 0x62e, 0x649, + 0x206, 0x62e, 0x64a, 0x206, 0x635, 0x649, 0x206, 0x635, + 0x64a, 0x206, 0x636, 0x649, 0x206, 0x636, 0x64a, 0x206, + 0x634, 0x62c, 0x206, 0x634, 0x62d, 0x206, 0x634, 0x62e, + 0x206, 0x634, 0x645, 0x206, 0x634, 0x631, 0x206, 0x633, + 0x631, 0x206, 0x635, 0x631, 0x206, 0x636, 0x631, 0x204, + 0x634, 0x62c, 0x204, 0x634, 0x62d, 0x204, 0x634, 0x62e, + 0x204, 0x634, 0x645, 0x204, 0x633, 0x647, 0x204, 0x634, + 0x647, 0x204, 0x637, 0x645, 0x205, 0x633, 0x62c, 0x205, + 0x633, 0x62d, 0x205, 0x633, 0x62e, 0x205, 0x634, 0x62c, + 0x205, 0x634, 0x62d, 0x205, 0x634, 0x62e, 0x205, 0x637, + 0x645, 0x205, 0x638, 0x645, 0x206, 0x627, 0x64b, 0x207, + 0x627, 0x64b, 0x304, 0x62a, 0x62c, 0x645, 0x306, 0x62a, + 0x62d, 0x62c, 0x304, 0x62a, 0x62d, 0x62c, 0x304, 0x62a, + 0x62d, 0x645, 0x304, 0x62a, 0x62e, 0x645, 0x304, 0x62a, + 0x645, 0x62c, 0x304, 0x62a, 0x645, 0x62d, 0x304, 0x62a, + 0x645, 0x62e, 0x306, 0x62c, 0x645, 0x62d, 0x304, 0x62c, + 0x645, 0x62d, 0x306, 0x62d, 0x645, 0x64a, 0x306, 0x62d, + 0x645, 0x649, 0x304, 0x633, 0x62d, 0x62c, 0x304, 0x633, + 0x62c, 0x62d, 0x306, 0x633, 0x62c, 0x649, 0x306, 0x633, + 0x645, 0x62d, 0x304, 0x633, 0x645, 0x62d, 0x304, 0x633, + 0x645, 0x62c, 0x306, 0x633, 0x645, 0x645, 0x304, 0x633, + 0x645, 0x645, 0x306, 0x635, 0x62d, 0x62d, 0x304, 0x635, + 0x62d, 0x62d, 0x306, 0x635, 0x645, 0x645, 0x306, 0x634, + 0x62d, 0x645, 0x304, 0x634, 0x62d, 0x645, 0x306, 0x634, + 0x62c, 0x64a, 0x306, 0x634, 0x645, 0x62e, 0x304, 0x634, + 0x645, 0x62e, 0x306, 0x634, 0x645, 0x645, 0x304, 0x634, + 0x645, 0x645, 0x306, 0x636, 0x62d, 0x649, 0x306, 0x636, + 0x62e, 0x645, 0x304, 0x636, 0x62e, 0x645, 0x306, 0x637, + 0x645, 0x62d, 0x304, 0x637, 0x645, 0x62d, 0x304, 0x637, + 0x645, 0x645, 0x306, 0x637, 0x645, 0x64a, 0x306, 0x639, + 0x62c, 0x645, 0x306, 0x639, 0x645, 0x645, 0x304, 0x639, + 0x645, 0x645, 0x306, 0x639, 0x645, 0x649, 0x306, 0x63a, + 0x645, 0x645, 0x306, 0x63a, 0x645, 0x64a, 0x306, 0x63a, + 0x645, 0x649, 0x306, 0x641, 0x62e, 0x645, 0x304, 0x641, + 0x62e, 0x645, 0x306, 0x642, 0x645, 0x62d, 0x306, 0x642, + 0x645, 0x645, 0x306, 0x644, 0x62d, 0x645, 0x306, 0x644, + 0x62d, 0x64a, 0x306, 0x644, 0x62d, 0x649, 0x304, 0x644, + 0x62c, 0x62c, 0x306, 0x644, 0x62c, 0x62c, 0x306, 0x644, + 0x62e, 0x645, 0x304, 0x644, 0x62e, 0x645, 0x306, 0x644, + 0x645, 0x62d, 0x304, 0x644, 0x645, 0x62d, 0x304, 0x645, + 0x62d, 0x62c, 0x304, 0x645, 0x62d, 0x645, 0x306, 0x645, + 0x62d, 0x64a, 0x304, 0x645, 0x62c, 0x62d, 0x304, 0x645, + 0x62c, 0x645, 0x304, 0x645, 0x62e, 0x62c, 0x304, 0x645, + 0x62e, 0x645, 0x304, 0x645, 0x62c, 0x62e, 0x304, 0x647, + 0x645, 0x62c, 0x304, 0x647, 0x645, 0x645, 0x304, 0x646, + 0x62d, 0x645, 0x306, 0x646, 0x62d, 0x649, 0x306, 0x646, + 0x62c, 0x645, 0x304, 0x646, 0x62c, 0x645, 0x306, 0x646, + 0x62c, 0x649, 0x306, 0x646, 0x645, 0x64a, 0x306, 0x646, + 0x645, 0x649, 0x306, 0x64a, 0x645, 0x645, 0x304, 0x64a, + 0x645, 0x645, 0x306, 0x628, 0x62e, 0x64a, 0x306, 0x62a, + 0x62c, 0x64a, 0x306, 0x62a, 0x62c, 0x649, 0x306, 0x62a, + 0x62e, 0x64a, 0x306, 0x62a, 0x62e, 0x649, 0x306, 0x62a, + 0x645, 0x64a, 0x306, 0x62a, 0x645, 0x649, 0x306, 0x62c, + 0x645, 0x64a, 0x306, 0x62c, 0x62d, 0x649, 0x306, 0x62c, + 0x645, 0x649, 0x306, 0x633, 0x62e, 0x649, 0x306, 0x635, + 0x62d, 0x64a, 0x306, 0x634, 0x62d, 0x64a, 0x306, 0x636, + 0x62d, 0x64a, 0x306, 0x644, 0x62c, 0x64a, 0x306, 0x644, + 0x645, 0x64a, 0x306, 0x64a, 0x62d, 0x64a, 0x306, 0x64a, + 0x62c, 0x64a, 0x306, 0x64a, 0x645, 0x64a, 0x306, 0x645, + 0x645, 0x64a, 0x306, 0x642, 0x645, 0x64a, 0x306, 0x646, + 0x62d, 0x64a, 0x304, 0x642, 0x645, 0x62d, 0x304, 0x644, + 0x62d, 0x645, 0x306, 0x639, 0x645, 0x64a, 0x306, 0x643, + 0x645, 0x64a, 0x304, 0x646, 0x62c, 0x62d, 0x306, 0x645, + 0x62e, 0x64a, 0x304, 0x644, 0x62c, 0x645, 0x306, 0x643, + 0x645, 0x645, 0x306, 0x644, 0x62c, 0x645, 0x306, 0x646, + 0x62c, 0x62d, 0x306, 0x62c, 0x62d, 0x64a, 0x306, 0x62d, + 0x62c, 0x64a, 0x306, 0x645, 0x62c, 0x64a, 0x306, 0x641, + 0x645, 0x64a, 0x306, 0x628, 0x62d, 0x64a, 0x304, 0x643, + 0x645, 0x645, 0x304, 0x639, 0x62c, 0x645, 0x304, 0x635, + 0x645, 0x645, 0x306, 0x633, 0x62e, 0x64a, 0x306, 0x646, + 0x62c, 0x64a, 0x307, 0x635, 0x644, 0x6d2, 0x307, 0x642, + 0x644, 0x6d2, 0x407, 0x627, 0x644, 0x644, 0x647, 0x407, + 0x627, 0x643, 0x628, 0x631, 0x407, 0x645, 0x62d, 0x645, + 0x62f, 0x407, 0x635, 0x644, 0x639, 0x645, 0x407, 0x631, + 0x633, 0x648, 0x644, 0x407, 0x639, 0x644, 0x64a, 0x647, + 0x407, 0x648, 0x633, 0x644, 0x645, 0x307, 0x635, 0x644, + 0x649, 0x1207, 0x635, 0x644, 0x649, 0x20, 0x627, 0x644, + 0x644, 0x647, 0x20, 0x639, 0x644, 0x64a, 0x647, 0x20, + 0x648, 0x633, 0x644, 0x645, 0x807, 0x62c, 0x644, 0x20, + 0x62c, 0x644, 0x627, 0x644, 0x647, 0x407, 0x631, 0x6cc, + 0x627, 0x644, 0x10b, 0x2c, 0x10b, 0x3001, 0x10b, 0x3002, + 0x10b, 0x3a, 0x10b, 0x3b, 0x10b, 0x21, 0x10b, 0x3f, + 0x10b, 0x3016, 0x10b, 0x3017, 0x10b, 0x2026, 0x10b, 0x2025, + 0x10b, 0x2014, 0x10b, 0x2013, 0x10b, 0x5f, 0x10b, 0x5f, + 0x10b, 0x28, 0x10b, 0x29, 0x10b, 0x7b, 0x10b, 0x7d, + 0x10b, 0x3014, 0x10b, 0x3015, 0x10b, 0x3010, 0x10b, 0x3011, + 0x10b, 0x300a, 0x10b, 0x300b, 0x10b, 0x3008, 0x10b, 0x3009, + 0x10b, 0x300c, 0x10b, 0x300d, 0x10b, 0x300e, 0x10b, 0x300f, + 0x10b, 0x5b, 0x10b, 0x5d, 0x110, 0x203e, 0x110, 0x203e, + 0x110, 0x203e, 0x110, 0x203e, 0x110, 0x5f, 0x110, 0x5f, + 0x110, 0x5f, 0x10e, 0x2c, 0x10e, 0x3001, 0x10e, 0x2e, + 0x10e, 0x3b, 0x10e, 0x3a, 0x10e, 0x3f, 0x10e, 0x21, + 0x10e, 0x2014, 0x10e, 0x28, 0x10e, 0x29, 0x10e, 0x7b, + 0x10e, 0x7d, 0x10e, 0x3014, 0x10e, 0x3015, 0x10e, 0x23, + 0x10e, 0x26, 0x10e, 0x2a, 0x10e, 0x2b, 0x10e, 0x2d, + 0x10e, 0x3c, 0x10e, 0x3e, 0x10e, 0x3d, 0x10e, 0x5c, + 0x10e, 0x24, 0x10e, 0x25, 0x10e, 0x40, 0x207, 0x20, + 0x64b, 0x205, 0x640, 0x64b, 0x207, 0x20, 0x64c, 0x207, + 0x20, 0x64d, 0x207, 0x20, 0x64e, 0x205, 0x640, 0x64e, + 0x207, 0x20, 0x64f, 0x205, 0x640, 0x64f, 0x207, 0x20, + 0x650, 0x205, 0x640, 0x650, 0x207, 0x20, 0x651, 0x205, + 0x640, 0x651, 0x207, 0x20, 0x652, 0x205, 0x640, 0x652, + 0x107, 0x621, 0x107, 0x622, 0x106, 0x622, 0x107, 0x623, + 0x106, 0x623, 0x107, 0x624, 0x106, 0x624, 0x107, 0x625, + 0x106, 0x625, 0x107, 0x626, 0x106, 0x626, 0x104, 0x626, + 0x105, 0x626, 0x107, 0x627, 0x106, 0x627, 0x107, 0x628, + 0x106, 0x628, 0x104, 0x628, 0x105, 0x628, 0x107, 0x629, + 0x106, 0x629, 0x107, 0x62a, 0x106, 0x62a, 0x104, 0x62a, + 0x105, 0x62a, 0x107, 0x62b, 0x106, 0x62b, 0x104, 0x62b, + 0x105, 0x62b, 0x107, 0x62c, 0x106, 0x62c, 0x104, 0x62c, + 0x105, 0x62c, 0x107, 0x62d, 0x106, 0x62d, 0x104, 0x62d, + 0x105, 0x62d, 0x107, 0x62e, 0x106, 0x62e, 0x104, 0x62e, + 0x105, 0x62e, 0x107, 0x62f, 0x106, 0x62f, 0x107, 0x630, + 0x106, 0x630, 0x107, 0x631, 0x106, 0x631, 0x107, 0x632, + 0x106, 0x632, 0x107, 0x633, 0x106, 0x633, 0x104, 0x633, + 0x105, 0x633, 0x107, 0x634, 0x106, 0x634, 0x104, 0x634, + 0x105, 0x634, 0x107, 0x635, 0x106, 0x635, 0x104, 0x635, + 0x105, 0x635, 0x107, 0x636, 0x106, 0x636, 0x104, 0x636, + 0x105, 0x636, 0x107, 0x637, 0x106, 0x637, 0x104, 0x637, + 0x105, 0x637, 0x107, 0x638, 0x106, 0x638, 0x104, 0x638, + 0x105, 0x638, 0x107, 0x639, 0x106, 0x639, 0x104, 0x639, + 0x105, 0x639, 0x107, 0x63a, 0x106, 0x63a, 0x104, 0x63a, + 0x105, 0x63a, 0x107, 0x641, 0x106, 0x641, 0x104, 0x641, + 0x105, 0x641, 0x107, 0x642, 0x106, 0x642, 0x104, 0x642, + 0x105, 0x642, 0x107, 0x643, 0x106, 0x643, 0x104, 0x643, + 0x105, 0x643, 0x107, 0x644, 0x106, 0x644, 0x104, 0x644, + 0x105, 0x644, 0x107, 0x645, 0x106, 0x645, 0x104, 0x645, + 0x105, 0x645, 0x107, 0x646, 0x106, 0x646, 0x104, 0x646, + 0x105, 0x646, 0x107, 0x647, 0x106, 0x647, 0x104, 0x647, + 0x105, 0x647, 0x107, 0x648, 0x106, 0x648, 0x107, 0x649, + 0x106, 0x649, 0x107, 0x64a, 0x106, 0x64a, 0x104, 0x64a, + 0x105, 0x64a, 0x207, 0x644, 0x622, 0x206, 0x644, 0x622, + 0x207, 0x644, 0x623, 0x206, 0x644, 0x623, 0x207, 0x644, + 0x625, 0x206, 0x644, 0x625, 0x207, 0x644, 0x627, 0x206, + 0x644, 0x627, 0x10c, 0x21, 0x10c, 0x22, 0x10c, 0x23, + 0x10c, 0x24, 0x10c, 0x25, 0x10c, 0x26, 0x10c, 0x27, + 0x10c, 0x28, 0x10c, 0x29, 0x10c, 0x2a, 0x10c, 0x2b, + 0x10c, 0x2c, 0x10c, 0x2d, 0x10c, 0x2e, 0x10c, 0x2f, + 0x10c, 0x30, 0x10c, 0x31, 0x10c, 0x32, 0x10c, 0x33, + 0x10c, 0x34, 0x10c, 0x35, 0x10c, 0x36, 0x10c, 0x37, + 0x10c, 0x38, 0x10c, 0x39, 0x10c, 0x3a, 0x10c, 0x3b, + 0x10c, 0x3c, 0x10c, 0x3d, 0x10c, 0x3e, 0x10c, 0x3f, + 0x10c, 0x40, 0x10c, 0x41, 0x10c, 0x42, 0x10c, 0x43, + 0x10c, 0x44, 0x10c, 0x45, 0x10c, 0x46, 0x10c, 0x47, + 0x10c, 0x48, 0x10c, 0x49, 0x10c, 0x4a, 0x10c, 0x4b, + 0x10c, 0x4c, 0x10c, 0x4d, 0x10c, 0x4e, 0x10c, 0x4f, + 0x10c, 0x50, 0x10c, 0x51, 0x10c, 0x52, 0x10c, 0x53, + 0x10c, 0x54, 0x10c, 0x55, 0x10c, 0x56, 0x10c, 0x57, + 0x10c, 0x58, 0x10c, 0x59, 0x10c, 0x5a, 0x10c, 0x5b, + 0x10c, 0x5c, 0x10c, 0x5d, 0x10c, 0x5e, 0x10c, 0x5f, + 0x10c, 0x60, 0x10c, 0x61, 0x10c, 0x62, 0x10c, 0x63, + 0x10c, 0x64, 0x10c, 0x65, 0x10c, 0x66, 0x10c, 0x67, + 0x10c, 0x68, 0x10c, 0x69, 0x10c, 0x6a, 0x10c, 0x6b, + 0x10c, 0x6c, 0x10c, 0x6d, 0x10c, 0x6e, 0x10c, 0x6f, + 0x10c, 0x70, 0x10c, 0x71, 0x10c, 0x72, 0x10c, 0x73, + 0x10c, 0x74, 0x10c, 0x75, 0x10c, 0x76, 0x10c, 0x77, + 0x10c, 0x78, 0x10c, 0x79, 0x10c, 0x7a, 0x10c, 0x7b, + 0x10c, 0x7c, 0x10c, 0x7d, 0x10c, 0x7e, 0x10c, 0x2985, + 0x10c, 0x2986, 0x10d, 0x3002, 0x10d, 0x300c, 0x10d, 0x300d, + 0x10d, 0x3001, 0x10d, 0x30fb, 0x10d, 0x30f2, 0x10d, 0x30a1, + 0x10d, 0x30a3, 0x10d, 0x30a5, 0x10d, 0x30a7, 0x10d, 0x30a9, + 0x10d, 0x30e3, 0x10d, 0x30e5, 0x10d, 0x30e7, 0x10d, 0x30c3, + 0x10d, 0x30fc, 0x10d, 0x30a2, 0x10d, 0x30a4, 0x10d, 0x30a6, + 0x10d, 0x30a8, 0x10d, 0x30aa, 0x10d, 0x30ab, 0x10d, 0x30ad, + 0x10d, 0x30af, 0x10d, 0x30b1, 0x10d, 0x30b3, 0x10d, 0x30b5, + 0x10d, 0x30b7, 0x10d, 0x30b9, 0x10d, 0x30bb, 0x10d, 0x30bd, + 0x10d, 0x30bf, 0x10d, 0x30c1, 0x10d, 0x30c4, 0x10d, 0x30c6, + 0x10d, 0x30c8, 0x10d, 0x30ca, 0x10d, 0x30cb, 0x10d, 0x30cc, + 0x10d, 0x30cd, 0x10d, 0x30ce, 0x10d, 0x30cf, 0x10d, 0x30d2, + 0x10d, 0x30d5, 0x10d, 0x30d8, 0x10d, 0x30db, 0x10d, 0x30de, + 0x10d, 0x30df, 0x10d, 0x30e0, 0x10d, 0x30e1, 0x10d, 0x30e2, + 0x10d, 0x30e4, 0x10d, 0x30e6, 0x10d, 0x30e8, 0x10d, 0x30e9, + 0x10d, 0x30ea, 0x10d, 0x30eb, 0x10d, 0x30ec, 0x10d, 0x30ed, + 0x10d, 0x30ef, 0x10d, 0x30f3, 0x10d, 0x3099, 0x10d, 0x309a, + 0x10d, 0x3164, 0x10d, 0x3131, 0x10d, 0x3132, 0x10d, 0x3133, + 0x10d, 0x3134, 0x10d, 0x3135, 0x10d, 0x3136, 0x10d, 0x3137, + 0x10d, 0x3138, 0x10d, 0x3139, 0x10d, 0x313a, 0x10d, 0x313b, + 0x10d, 0x313c, 0x10d, 0x313d, 0x10d, 0x313e, 0x10d, 0x313f, + 0x10d, 0x3140, 0x10d, 0x3141, 0x10d, 0x3142, 0x10d, 0x3143, + 0x10d, 0x3144, 0x10d, 0x3145, 0x10d, 0x3146, 0x10d, 0x3147, + 0x10d, 0x3148, 0x10d, 0x3149, 0x10d, 0x314a, 0x10d, 0x314b, + 0x10d, 0x314c, 0x10d, 0x314d, 0x10d, 0x314e, 0x10d, 0x314f, + 0x10d, 0x3150, 0x10d, 0x3151, 0x10d, 0x3152, 0x10d, 0x3153, + 0x10d, 0x3154, 0x10d, 0x3155, 0x10d, 0x3156, 0x10d, 0x3157, + 0x10d, 0x3158, 0x10d, 0x3159, 0x10d, 0x315a, 0x10d, 0x315b, + 0x10d, 0x315c, 0x10d, 0x315d, 0x10d, 0x315e, 0x10d, 0x315f, + 0x10d, 0x3160, 0x10d, 0x3161, 0x10d, 0x3162, 0x10d, 0x3163, + 0x10c, 0xa2, 0x10c, 0xa3, 0x10c, 0xac, 0x10c, 0xaf, + 0x10c, 0xa6, 0x10c, 0xa5, 0x10c, 0x20a9, 0x10d, 0x2502, + 0x10d, 0x2190, 0x10d, 0x2191, 0x10d, 0x2192, 0x10d, 0x2193, + 0x10d, 0x25a0, 0x10d, 0x25cb, 0x401, 0xd834, 0xdd57, 0xd834, + 0xdd65, 0x401, 0xd834, 0xdd58, 0xd834, 0xdd65, 0x401, 0xd834, + 0xdd5f, 0xd834, 0xdd6e, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd6f, + 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd70, 0x401, 0xd834, 0xdd5f, + 0xd834, 0xdd71, 0x401, 0xd834, 0xdd5f, 0xd834, 0xdd72, 0x401, + 0xd834, 0xddb9, 0xd834, 0xdd65, 0x401, 0xd834, 0xddba, 0xd834, + 0xdd65, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6e, 0x401, 0xd834, + 0xddbc, 0xd834, 0xdd6e, 0x401, 0xd834, 0xddbb, 0xd834, 0xdd6f, + 0x401, 0xd834, 0xddbc, 0xd834, 0xdd6f, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, + 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, + 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, + 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, + 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, + 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, + 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, 0x4a, 0x102, + 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, 0x4e, 0x102, + 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, 0x52, 0x102, + 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, + 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, + 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, + 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, + 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, + 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, + 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, + 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, + 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x43, 0x102, + 0x44, 0x102, 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, 0x56, 0x102, + 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, 0x5a, 0x102, + 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, + 0x66, 0x102, 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, + 0x6b, 0x102, 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, + 0x47, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, + 0x4d, 0x102, 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, + 0x51, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, 0x64, 0x102, + 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, 0x68, 0x102, + 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, 0x6c, 0x102, + 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, 0x70, 0x102, + 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, 0x74, 0x102, + 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, 0x78, 0x102, + 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, 0x42, 0x102, + 0x44, 0x102, 0x45, 0x102, 0x46, 0x102, 0x47, 0x102, + 0x49, 0x102, 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, + 0x4d, 0x102, 0x4f, 0x102, 0x53, 0x102, 0x54, 0x102, + 0x55, 0x102, 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, + 0x59, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x41, 0x102, + 0x42, 0x102, 0x43, 0x102, 0x44, 0x102, 0x45, 0x102, + 0x46, 0x102, 0x47, 0x102, 0x48, 0x102, 0x49, 0x102, + 0x4a, 0x102, 0x4b, 0x102, 0x4c, 0x102, 0x4d, 0x102, + 0x4e, 0x102, 0x4f, 0x102, 0x50, 0x102, 0x51, 0x102, + 0x52, 0x102, 0x53, 0x102, 0x54, 0x102, 0x55, 0x102, + 0x56, 0x102, 0x57, 0x102, 0x58, 0x102, 0x59, 0x102, + 0x5a, 0x102, 0x61, 0x102, 0x62, 0x102, 0x63, 0x102, + 0x64, 0x102, 0x65, 0x102, 0x66, 0x102, 0x67, 0x102, + 0x68, 0x102, 0x69, 0x102, 0x6a, 0x102, 0x6b, 0x102, + 0x6c, 0x102, 0x6d, 0x102, 0x6e, 0x102, 0x6f, 0x102, + 0x70, 0x102, 0x71, 0x102, 0x72, 0x102, 0x73, 0x102, + 0x74, 0x102, 0x75, 0x102, 0x76, 0x102, 0x77, 0x102, + 0x78, 0x102, 0x79, 0x102, 0x7a, 0x102, 0x131, 0x102, + 0x237, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, + 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, + 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, + 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, + 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, + 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, + 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, + 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, + 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, + 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, + 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, + 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, + 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, + 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, + 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, + 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, + 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, + 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, + 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, + 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, + 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, + 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, + 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, + 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, + 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, + 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, + 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, + 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, + 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, + 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, + 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, + 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, + 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, + 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, + 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, + 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, + 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, + 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, + 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, + 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, + 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, + 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, + 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, + 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x391, 0x102, + 0x392, 0x102, 0x393, 0x102, 0x394, 0x102, 0x395, 0x102, + 0x396, 0x102, 0x397, 0x102, 0x398, 0x102, 0x399, 0x102, + 0x39a, 0x102, 0x39b, 0x102, 0x39c, 0x102, 0x39d, 0x102, + 0x39e, 0x102, 0x39f, 0x102, 0x3a0, 0x102, 0x3a1, 0x102, + 0x3f4, 0x102, 0x3a3, 0x102, 0x3a4, 0x102, 0x3a5, 0x102, + 0x3a6, 0x102, 0x3a7, 0x102, 0x3a8, 0x102, 0x3a9, 0x102, + 0x2207, 0x102, 0x3b1, 0x102, 0x3b2, 0x102, 0x3b3, 0x102, + 0x3b4, 0x102, 0x3b5, 0x102, 0x3b6, 0x102, 0x3b7, 0x102, + 0x3b8, 0x102, 0x3b9, 0x102, 0x3ba, 0x102, 0x3bb, 0x102, + 0x3bc, 0x102, 0x3bd, 0x102, 0x3be, 0x102, 0x3bf, 0x102, + 0x3c0, 0x102, 0x3c1, 0x102, 0x3c2, 0x102, 0x3c3, 0x102, + 0x3c4, 0x102, 0x3c5, 0x102, 0x3c6, 0x102, 0x3c7, 0x102, + 0x3c8, 0x102, 0x3c9, 0x102, 0x2202, 0x102, 0x3f5, 0x102, + 0x3d1, 0x102, 0x3f0, 0x102, 0x3d5, 0x102, 0x3f1, 0x102, + 0x3d6, 0x102, 0x391, 0x102, 0x392, 0x102, 0x393, 0x102, + 0x394, 0x102, 0x395, 0x102, 0x396, 0x102, 0x397, 0x102, + 0x398, 0x102, 0x399, 0x102, 0x39a, 0x102, 0x39b, 0x102, + 0x39c, 0x102, 0x39d, 0x102, 0x39e, 0x102, 0x39f, 0x102, + 0x3a0, 0x102, 0x3a1, 0x102, 0x3f4, 0x102, 0x3a3, 0x102, + 0x3a4, 0x102, 0x3a5, 0x102, 0x3a6, 0x102, 0x3a7, 0x102, + 0x3a8, 0x102, 0x3a9, 0x102, 0x2207, 0x102, 0x3b1, 0x102, + 0x3b2, 0x102, 0x3b3, 0x102, 0x3b4, 0x102, 0x3b5, 0x102, + 0x3b6, 0x102, 0x3b7, 0x102, 0x3b8, 0x102, 0x3b9, 0x102, + 0x3ba, 0x102, 0x3bb, 0x102, 0x3bc, 0x102, 0x3bd, 0x102, + 0x3be, 0x102, 0x3bf, 0x102, 0x3c0, 0x102, 0x3c1, 0x102, + 0x3c2, 0x102, 0x3c3, 0x102, 0x3c4, 0x102, 0x3c5, 0x102, + 0x3c6, 0x102, 0x3c7, 0x102, 0x3c8, 0x102, 0x3c9, 0x102, + 0x2202, 0x102, 0x3f5, 0x102, 0x3d1, 0x102, 0x3f0, 0x102, + 0x3d5, 0x102, 0x3f1, 0x102, 0x3d6, 0x102, 0x3dc, 0x102, + 0x3dd, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, + 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, + 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, + 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, + 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, + 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, + 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, + 0x37, 0x102, 0x38, 0x102, 0x39, 0x102, 0x30, 0x102, + 0x31, 0x102, 0x32, 0x102, 0x33, 0x102, 0x34, 0x102, + 0x35, 0x102, 0x36, 0x102, 0x37, 0x102, 0x38, 0x102, + 0x39, 0x102, 0x30, 0x102, 0x31, 0x102, 0x32, 0x102, + 0x33, 0x102, 0x34, 0x102, 0x35, 0x102, 0x36, 0x102, + 0x37, 0x102, 0x38, 0x102, 0x39, 0x101, 0x4e3d, 0x101, + 0x4e38, 0x101, 0x4e41, 0x201, 0xd840, 0xdd22, 0x101, 0x4f60, + 0x101, 0x4fae, 0x101, 0x4fbb, 0x101, 0x5002, 0x101, 0x507a, + 0x101, 0x5099, 0x101, 0x50e7, 0x101, 0x50cf, 0x101, 0x349e, + 0x201, 0xd841, 0xde3a, 0x101, 0x514d, 0x101, 0x5154, 0x101, + 0x5164, 0x101, 0x5177, 0x201, 0xd841, 0xdd1c, 0x101, 0x34b9, + 0x101, 0x5167, 0x101, 0x518d, 0x201, 0xd841, 0xdd4b, 0x101, + 0x5197, 0x101, 0x51a4, 0x101, 0x4ecc, 0x101, 0x51ac, 0x101, + 0x51b5, 0x201, 0xd864, 0xdddf, 0x101, 0x51f5, 0x101, 0x5203, + 0x101, 0x34df, 0x101, 0x523b, 0x101, 0x5246, 0x101, 0x5272, + 0x101, 0x5277, 0x101, 0x3515, 0x101, 0x52c7, 0x101, 0x52c9, + 0x101, 0x52e4, 0x101, 0x52fa, 0x101, 0x5305, 0x101, 0x5306, + 0x101, 0x5317, 0x101, 0x5349, 0x101, 0x5351, 0x101, 0x535a, + 0x101, 0x5373, 0x101, 0x537d, 0x101, 0x537f, 0x101, 0x537f, + 0x101, 0x537f, 0x201, 0xd842, 0xde2c, 0x101, 0x7070, 0x101, + 0x53ca, 0x101, 0x53df, 0x201, 0xd842, 0xdf63, 0x101, 0x53eb, + 0x101, 0x53f1, 0x101, 0x5406, 0x101, 0x549e, 0x101, 0x5438, + 0x101, 0x5448, 0x101, 0x5468, 0x101, 0x54a2, 0x101, 0x54f6, + 0x101, 0x5510, 0x101, 0x5553, 0x101, 0x5563, 0x101, 0x5584, + 0x101, 0x5584, 0x101, 0x5599, 0x101, 0x55ab, 0x101, 0x55b3, + 0x101, 0x55c2, 0x101, 0x5716, 0x101, 0x5606, 0x101, 0x5717, + 0x101, 0x5651, 0x101, 0x5674, 0x101, 0x5207, 0x101, 0x58ee, + 0x101, 0x57ce, 0x101, 0x57f4, 0x101, 0x580d, 0x101, 0x578b, + 0x101, 0x5832, 0x101, 0x5831, 0x101, 0x58ac, 0x201, 0xd845, + 0xdce4, 0x101, 0x58f2, 0x101, 0x58f7, 0x101, 0x5906, 0x101, + 0x591a, 0x101, 0x5922, 0x101, 0x5962, 0x201, 0xd845, 0xdea8, + 0x201, 0xd845, 0xdeea, 0x101, 0x59ec, 0x101, 0x5a1b, 0x101, + 0x5a27, 0x101, 0x59d8, 0x101, 0x5a66, 0x101, 0x36ee, 0x101, + 0x36fc, 0x101, 0x5b08, 0x101, 0x5b3e, 0x101, 0x5b3e, 0x201, + 0xd846, 0xddc8, 0x101, 0x5bc3, 0x101, 0x5bd8, 0x101, 0x5be7, + 0x101, 0x5bf3, 0x201, 0xd846, 0xdf18, 0x101, 0x5bff, 0x101, + 0x5c06, 0x101, 0x5f53, 0x101, 0x5c22, 0x101, 0x3781, 0x101, + 0x5c60, 0x101, 0x5c6e, 0x101, 0x5cc0, 0x101, 0x5c8d, 0x201, + 0xd847, 0xdde4, 0x101, 0x5d43, 0x201, 0xd847, 0xdde6, 0x101, + 0x5d6e, 0x101, 0x5d6b, 0x101, 0x5d7c, 0x101, 0x5de1, 0x101, + 0x5de2, 0x101, 0x382f, 0x101, 0x5dfd, 0x101, 0x5e28, 0x101, + 0x5e3d, 0x101, 0x5e69, 0x101, 0x3862, 0x201, 0xd848, 0xdd83, + 0x101, 0x387c, 0x101, 0x5eb0, 0x101, 0x5eb3, 0x101, 0x5eb6, + 0x101, 0x5eca, 0x201, 0xd868, 0xdf92, 0x101, 0x5efe, 0x201, + 0xd848, 0xdf31, 0x201, 0xd848, 0xdf31, 0x101, 0x8201, 0x101, + 0x5f22, 0x101, 0x5f22, 0x101, 0x38c7, 0x201, 0xd84c, 0xdeb8, + 0x201, 0xd858, 0xddda, 0x101, 0x5f62, 0x101, 0x5f6b, 0x101, + 0x38e3, 0x101, 0x5f9a, 0x101, 0x5fcd, 0x101, 0x5fd7, 0x101, + 0x5ff9, 0x101, 0x6081, 0x101, 0x393a, 0x101, 0x391c, 0x101, + 0x6094, 0x201, 0xd849, 0xded4, 0x101, 0x60c7, 0x101, 0x6148, + 0x101, 0x614c, 0x101, 0x614e, 0x101, 0x614c, 0x101, 0x617a, + 0x101, 0x618e, 0x101, 0x61b2, 0x101, 0x61a4, 0x101, 0x61af, + 0x101, 0x61de, 0x101, 0x61f2, 0x101, 0x61f6, 0x101, 0x6210, + 0x101, 0x621b, 0x101, 0x625d, 0x101, 0x62b1, 0x101, 0x62d4, + 0x101, 0x6350, 0x201, 0xd84a, 0xdf0c, 0x101, 0x633d, 0x101, + 0x62fc, 0x101, 0x6368, 0x101, 0x6383, 0x101, 0x63e4, 0x201, + 0xd84a, 0xdff1, 0x101, 0x6422, 0x101, 0x63c5, 0x101, 0x63a9, + 0x101, 0x3a2e, 0x101, 0x6469, 0x101, 0x647e, 0x101, 0x649d, + 0x101, 0x6477, 0x101, 0x3a6c, 0x101, 0x654f, 0x101, 0x656c, + 0x201, 0xd84c, 0xdc0a, 0x101, 0x65e3, 0x101, 0x66f8, 0x101, + 0x6649, 0x101, 0x3b19, 0x101, 0x6691, 0x101, 0x3b08, 0x101, + 0x3ae4, 0x101, 0x5192, 0x101, 0x5195, 0x101, 0x6700, 0x101, + 0x669c, 0x101, 0x80ad, 0x101, 0x43d9, 0x101, 0x6717, 0x101, + 0x671b, 0x101, 0x6721, 0x101, 0x675e, 0x101, 0x6753, 0x201, + 0xd84c, 0xdfc3, 0x101, 0x3b49, 0x101, 0x67fa, 0x101, 0x6785, + 0x101, 0x6852, 0x101, 0x6885, 0x201, 0xd84d, 0xdc6d, 0x101, + 0x688e, 0x101, 0x681f, 0x101, 0x6914, 0x101, 0x3b9d, 0x101, + 0x6942, 0x101, 0x69a3, 0x101, 0x69ea, 0x101, 0x6aa8, 0x201, + 0xd84d, 0xdea3, 0x101, 0x6adb, 0x101, 0x3c18, 0x101, 0x6b21, + 0x201, 0xd84e, 0xdca7, 0x101, 0x6b54, 0x101, 0x3c4e, 0x101, + 0x6b72, 0x101, 0x6b9f, 0x101, 0x6bba, 0x101, 0x6bbb, 0x201, + 0xd84e, 0xde8d, 0x201, 0xd847, 0xdd0b, 0x201, 0xd84e, 0xdefa, + 0x101, 0x6c4e, 0x201, 0xd84f, 0xdcbc, 0x101, 0x6cbf, 0x101, + 0x6ccd, 0x101, 0x6c67, 0x101, 0x6d16, 0x101, 0x6d3e, 0x101, + 0x6d77, 0x101, 0x6d41, 0x101, 0x6d69, 0x101, 0x6d78, 0x101, + 0x6d85, 0x201, 0xd84f, 0xdd1e, 0x101, 0x6d34, 0x101, 0x6e2f, + 0x101, 0x6e6e, 0x101, 0x3d33, 0x101, 0x6ecb, 0x101, 0x6ec7, + 0x201, 0xd84f, 0xded1, 0x101, 0x6df9, 0x101, 0x6f6e, 0x201, + 0xd84f, 0xdf5e, 0x201, 0xd84f, 0xdf8e, 0x101, 0x6fc6, 0x101, + 0x7039, 0x101, 0x701e, 0x101, 0x701b, 0x101, 0x3d96, 0x101, + 0x704a, 0x101, 0x707d, 0x101, 0x7077, 0x101, 0x70ad, 0x201, + 0xd841, 0xdd25, 0x101, 0x7145, 0x201, 0xd850, 0xde63, 0x101, + 0x719c, 0x201, 0xd850, 0xdfab, 0x101, 0x7228, 0x101, 0x7235, + 0x101, 0x7250, 0x201, 0xd851, 0xde08, 0x101, 0x7280, 0x101, + 0x7295, 0x201, 0xd851, 0xdf35, 0x201, 0xd852, 0xdc14, 0x101, + 0x737a, 0x101, 0x738b, 0x101, 0x3eac, 0x101, 0x73a5, 0x101, + 0x3eb8, 0x101, 0x3eb8, 0x101, 0x7447, 0x101, 0x745c, 0x101, + 0x7471, 0x101, 0x7485, 0x101, 0x74ca, 0x101, 0x3f1b, 0x101, + 0x7524, 0x201, 0xd853, 0xdc36, 0x101, 0x753e, 0x201, 0xd853, + 0xdc92, 0x101, 0x7570, 0x201, 0xd848, 0xdd9f, 0x101, 0x7610, + 0x201, 0xd853, 0xdfa1, 0x201, 0xd853, 0xdfb8, 0x201, 0xd854, + 0xdc44, 0x101, 0x3ffc, 0x101, 0x4008, 0x101, 0x76f4, 0x201, + 0xd854, 0xdcf3, 0x201, 0xd854, 0xdcf2, 0x201, 0xd854, 0xdd19, + 0x201, 0xd854, 0xdd33, 0x101, 0x771e, 0x101, 0x771f, 0x101, + 0x771f, 0x101, 0x774a, 0x101, 0x4039, 0x101, 0x778b, 0x101, + 0x4046, 0x101, 0x4096, 0x201, 0xd855, 0xdc1d, 0x101, 0x784e, + 0x101, 0x788c, 0x101, 0x78cc, 0x101, 0x40e3, 0x201, 0xd855, + 0xde26, 0x101, 0x7956, 0x201, 0xd855, 0xde9a, 0x201, 0xd855, + 0xdec5, 0x101, 0x798f, 0x101, 0x79eb, 0x101, 0x412f, 0x101, + 0x7a40, 0x101, 0x7a4a, 0x101, 0x7a4f, 0x201, 0xd856, 0xdd7c, + 0x201, 0xd856, 0xdea7, 0x201, 0xd856, 0xdea7, 0x101, 0x7aee, + 0x101, 0x4202, 0x201, 0xd856, 0xdfab, 0x101, 0x7bc6, 0x101, + 0x7bc9, 0x101, 0x4227, 0x201, 0xd857, 0xdc80, 0x101, 0x7cd2, + 0x101, 0x42a0, 0x101, 0x7ce8, 0x101, 0x7ce3, 0x101, 0x7d00, + 0x201, 0xd857, 0xdf86, 0x101, 0x7d63, 0x101, 0x4301, 0x101, + 0x7dc7, 0x101, 0x7e02, 0x101, 0x7e45, 0x101, 0x4334, 0x201, + 0xd858, 0xde28, 0x201, 0xd858, 0xde47, 0x101, 0x4359, 0x201, + 0xd858, 0xded9, 0x101, 0x7f7a, 0x201, 0xd858, 0xdf3e, 0x101, + 0x7f95, 0x101, 0x7ffa, 0x101, 0x8005, 0x201, 0xd859, 0xdcda, + 0x201, 0xd859, 0xdd23, 0x101, 0x8060, 0x201, 0xd859, 0xdda8, + 0x101, 0x8070, 0x201, 0xd84c, 0xdf5f, 0x101, 0x43d5, 0x101, + 0x80b2, 0x101, 0x8103, 0x101, 0x440b, 0x101, 0x813e, 0x101, + 0x5ab5, 0x201, 0xd859, 0xdfa7, 0x201, 0xd859, 0xdfb5, 0x201, + 0xd84c, 0xdf93, 0x201, 0xd84c, 0xdf9c, 0x101, 0x8201, 0x101, + 0x8204, 0x101, 0x8f9e, 0x101, 0x446b, 0x101, 0x8291, 0x101, + 0x828b, 0x101, 0x829d, 0x101, 0x52b3, 0x101, 0x82b1, 0x101, + 0x82b3, 0x101, 0x82bd, 0x101, 0x82e6, 0x201, 0xd85a, 0xdf3c, + 0x101, 0x82e5, 0x101, 0x831d, 0x101, 0x8363, 0x101, 0x83ad, + 0x101, 0x8323, 0x101, 0x83bd, 0x101, 0x83e7, 0x101, 0x8457, + 0x101, 0x8353, 0x101, 0x83ca, 0x101, 0x83cc, 0x101, 0x83dc, + 0x201, 0xd85b, 0xdc36, 0x201, 0xd85b, 0xdd6b, 0x201, 0xd85b, + 0xdcd5, 0x101, 0x452b, 0x101, 0x84f1, 0x101, 0x84f3, 0x101, + 0x8516, 0x201, 0xd85c, 0xdfca, 0x101, 0x8564, 0x201, 0xd85b, + 0xdf2c, 0x101, 0x455d, 0x101, 0x4561, 0x201, 0xd85b, 0xdfb1, + 0x201, 0xd85c, 0xdcd2, 0x101, 0x456b, 0x101, 0x8650, 0x101, + 0x865c, 0x101, 0x8667, 0x101, 0x8669, 0x101, 0x86a9, 0x101, + 0x8688, 0x101, 0x870e, 0x101, 0x86e2, 0x101, 0x8779, 0x101, + 0x8728, 0x101, 0x876b, 0x101, 0x8786, 0x101, 0x45d7, 0x101, + 0x87e1, 0x101, 0x8801, 0x101, 0x45f9, 0x101, 0x8860, 0x101, + 0x8863, 0x201, 0xd85d, 0xde67, 0x101, 0x88d7, 0x101, 0x88de, + 0x101, 0x4635, 0x101, 0x88fa, 0x101, 0x34bb, 0x201, 0xd85e, + 0xdcae, 0x201, 0xd85e, 0xdd66, 0x101, 0x46be, 0x101, 0x46c7, + 0x101, 0x8aa0, 0x101, 0x8aed, 0x101, 0x8b8a, 0x101, 0x8c55, + 0x201, 0xd85f, 0xdca8, 0x101, 0x8cab, 0x101, 0x8cc1, 0x101, + 0x8d1b, 0x101, 0x8d77, 0x201, 0xd85f, 0xdf2f, 0x201, 0xd842, + 0xdc04, 0x101, 0x8dcb, 0x101, 0x8dbc, 0x101, 0x8df0, 0x201, + 0xd842, 0xdcde, 0x101, 0x8ed4, 0x101, 0x8f38, 0x201, 0xd861, + 0xddd2, 0x201, 0xd861, 0xdded, 0x101, 0x9094, 0x101, 0x90f1, + 0x101, 0x9111, 0x201, 0xd861, 0xdf2e, 0x101, 0x911b, 0x101, + 0x9238, 0x101, 0x92d7, 0x101, 0x92d8, 0x101, 0x927c, 0x101, + 0x93f9, 0x101, 0x9415, 0x201, 0xd862, 0xdffa, 0x101, 0x958b, + 0x101, 0x4995, 0x101, 0x95b7, 0x201, 0xd863, 0xdd77, 0x101, + 0x49e6, 0x101, 0x96c3, 0x101, 0x5db2, 0x101, 0x9723, 0x201, + 0xd864, 0xdd45, 0x201, 0xd864, 0xde1a, 0x101, 0x4a6e, 0x101, + 0x4a76, 0x101, 0x97e0, 0x201, 0xd865, 0xdc0a, 0x101, 0x4ab2, + 0x201, 0xd865, 0xdc96, 0x101, 0x980b, 0x101, 0x980b, 0x101, + 0x9829, 0x201, 0xd865, 0xddb6, 0x101, 0x98e2, 0x101, 0x4b33, + 0x101, 0x9929, 0x101, 0x99a7, 0x101, 0x99c2, 0x101, 0x99fe, + 0x101, 0x4bce, 0x201, 0xd866, 0xdf30, 0x101, 0x9b12, 0x101, + 0x9c40, 0x101, 0x9cfd, 0x101, 0x4cce, 0x101, 0x4ced, 0x101, + 0x9d67, 0x201, 0xd868, 0xdcce, 0x101, 0x4cf8, 0x201, 0xd868, + 0xdd05, 0x201, 0xd868, 0xde0e, 0x201, 0xd868, 0xde91, 0x101, + 0x9ebb, 0x101, 0x4d56, 0x101, 0x9ef9, 0x101, 0x9efe, 0x101, + 0x9f05, 0x101, 0x9f0f, 0x101, 0x9f16, 0x101, 0x9f3b, 0x201, + 0xd869, 0xde00, }; static const unsigned short uc_ligature_trie[] = { // 0 - 0x3100 - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 424, 456, 488, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 520, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 552, 392, 392, 392, 584, 616, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 648, 680, 392, 392, 712, 744, 392, - 392, 392, 776, 392, 392, 392, 808, 392, - 392, 840, 872, 392, 392, 392, 904, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - - 392, 936, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 968, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 392, 392, 392, 392, 392, - - 392, 392, 392, 392, 1000, 392, 392, 392, - - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0x0, 0xa9, 0x194, 0x1d5, 0x20e, 0xffff, 0x267, 0x2a8, - 0x305, 0x372, 0x3a3, 0x3b0, 0x3bd, 0xffff, 0xffff, 0x408, - 0xffff, 0x425, 0xffff, 0x43e, 0x45b, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x47c, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0x485, 0x4da, 0x4df, 0x4e4, 0x4ed, - 0x51a, 0xffff, 0xffff, 0xffff, 0xffff, 0x52f, 0x548, 0xffff, - 0x54d, 0x55a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0x57d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0x5d6, 0xffff, 0xffff, 0x611, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0x690, 0x693, 0x6a0, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0x6a3, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6aa, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6ad, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b0, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b3, 0x6b6, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b9, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6be, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c3, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0x6c6, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c9, 0x6d0, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d3, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d8, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0x6db, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e0, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e3, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e6, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e9, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0x700, 0x761, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 424, 456, 488, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 520, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 552, 392, 392, 392, 584, 616, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 648, 680, 392, 392, 712, 744, 392, + 392, 392, 776, 392, 392, 392, 808, 392, + 392, 840, 872, 392, 392, 392, 904, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + + 392, 936, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 968, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, + + 392, 392, 392, 392, 1000, 392, 392, 392, + + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0x0, 0xa9, 0x194, 0x1d5, 0x20e, 0xffff, 0x267, 0x2a8, + 0x305, 0x372, 0x3a3, 0x3b0, 0x3bd, 0xffff, 0xffff, 0x408, + 0xffff, 0x425, 0xffff, 0x43e, 0x45b, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x47c, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0x485, 0x4da, 0x4df, 0x4e4, 0x4ed, + 0x51a, 0xffff, 0xffff, 0xffff, 0xffff, 0x52f, 0x548, 0xffff, + 0x54d, 0x55a, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x57d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0x5d6, 0xffff, 0xffff, 0x611, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0x690, 0x693, 0x6a0, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0x6a3, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6aa, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6ad, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b0, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b3, 0x6b6, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6b9, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6be, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c3, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0x6c6, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6c9, 0x6d0, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d3, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6d8, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x6db, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e0, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e3, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e6, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x6e9, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0x700, 0x761, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, }; #define GET_LIGATURE_INDEX(u2) (u2 < 0x3100 ? uc_ligature_trie[uc_ligature_trie[u2>>5] + (u2 & 0x1f)] : 0xffff); static const unsigned short uc_ligature_map [] = { - 0x54, 0x41, 0xc0, 0x45, 0xc8, 0x49, 0xcc, 0x4e, - 0x1f8, 0x4f, 0xd2, 0x55, 0xd9, 0x57, 0x1e80, 0x59, - 0x1ef2, 0x61, 0xe0, 0x65, 0xe8, 0x69, 0xec, 0x6e, - 0x1f9, 0x6f, 0xf2, 0x75, 0xf9, 0x77, 0x1e81, 0x79, - 0x1ef3, 0xa8, 0x1fed, 0xc2, 0x1ea6, 0xca, 0x1ec0, 0xd4, - 0x1ed2, 0xdc, 0x1db, 0xe2, 0x1ea7, 0xea, 0x1ec1, 0xf4, - 0x1ed3, 0xfc, 0x1dc, 0x102, 0x1eb0, 0x103, 0x1eb1, 0x112, - 0x1e14, 0x113, 0x1e15, 0x14c, 0x1e50, 0x14d, 0x1e51, 0x1a0, - 0x1edc, 0x1a1, 0x1edd, 0x1af, 0x1eea, 0x1b0, 0x1eeb, 0x391, - 0x1fba, 0x395, 0x1fc8, 0x397, 0x1fca, 0x399, 0x1fda, 0x39f, - 0x1ff8, 0x3a5, 0x1fea, 0x3a9, 0x1ffa, 0x3b1, 0x1f70, 0x3b5, - 0x1f72, 0x3b7, 0x1f74, 0x3b9, 0x1f76, 0x3bf, 0x1f78, 0x3c5, - 0x1f7a, 0x3c9, 0x1f7c, 0x3ca, 0x1fd2, 0x3cb, 0x1fe2, 0x415, - 0x400, 0x418, 0x40d, 0x435, 0x450, 0x438, 0x45d, 0x1f00, - 0x1f02, 0x1f01, 0x1f03, 0x1f08, 0x1f0a, 0x1f09, 0x1f0b, 0x1f10, - 0x1f12, 0x1f11, 0x1f13, 0x1f18, 0x1f1a, 0x1f19, 0x1f1b, 0x1f20, - 0x1f22, 0x1f21, 0x1f23, 0x1f28, 0x1f2a, 0x1f29, 0x1f2b, 0x1f30, - 0x1f32, 0x1f31, 0x1f33, 0x1f38, 0x1f3a, 0x1f39, 0x1f3b, 0x1f40, - 0x1f42, 0x1f41, 0x1f43, 0x1f48, 0x1f4a, 0x1f49, 0x1f4b, 0x1f50, - 0x1f52, 0x1f51, 0x1f53, 0x1f59, 0x1f5b, 0x1f60, 0x1f62, 0x1f61, - 0x1f63, 0x1f68, 0x1f6a, 0x1f69, 0x1f6b, 0x1fbf, 0x1fcd, 0x1ffe, - 0x1fdd, 0x75, 0x41, 0xc1, 0x43, 0x106, 0x45, 0xc9, - 0x47, 0x1f4, 0x49, 0xcd, 0x4b, 0x1e30, 0x4c, 0x139, - 0x4d, 0x1e3e, 0x4e, 0x143, 0x4f, 0xd3, 0x50, 0x1e54, - 0x52, 0x154, 0x53, 0x15a, 0x55, 0xda, 0x57, 0x1e82, - 0x59, 0xdd, 0x5a, 0x179, 0x61, 0xe1, 0x63, 0x107, - 0x65, 0xe9, 0x67, 0x1f5, 0x69, 0xed, 0x6b, 0x1e31, - 0x6c, 0x13a, 0x6d, 0x1e3f, 0x6e, 0x144, 0x6f, 0xf3, - 0x70, 0x1e55, 0x72, 0x155, 0x73, 0x15b, 0x75, 0xfa, - 0x77, 0x1e83, 0x79, 0xfd, 0x7a, 0x17a, 0xa8, 0x385, - 0xc2, 0x1ea4, 0xc5, 0x1fa, 0xc6, 0x1fc, 0xc7, 0x1e08, - 0xca, 0x1ebe, 0xcf, 0x1e2e, 0xd4, 0x1ed0, 0xd5, 0x1e4c, - 0xd8, 0x1fe, 0xdc, 0x1d7, 0xe2, 0x1ea5, 0xe5, 0x1fb, - 0xe6, 0x1fd, 0xe7, 0x1e09, 0xea, 0x1ebf, 0xef, 0x1e2f, - 0xf4, 0x1ed1, 0xf5, 0x1e4d, 0xf8, 0x1ff, 0xfc, 0x1d8, - 0x102, 0x1eae, 0x103, 0x1eaf, 0x112, 0x1e16, 0x113, 0x1e17, - 0x14c, 0x1e52, 0x14d, 0x1e53, 0x168, 0x1e78, 0x169, 0x1e79, - 0x1a0, 0x1eda, 0x1a1, 0x1edb, 0x1af, 0x1ee8, 0x1b0, 0x1ee9, - 0x391, 0x386, 0x395, 0x388, 0x397, 0x389, 0x399, 0x38a, - 0x39f, 0x38c, 0x3a5, 0x38e, 0x3a9, 0x38f, 0x3b1, 0x3ac, - 0x3b5, 0x3ad, 0x3b7, 0x3ae, 0x3b9, 0x3af, 0x3bf, 0x3cc, - 0x3c5, 0x3cd, 0x3c9, 0x3ce, 0x3ca, 0x390, 0x3cb, 0x3b0, - 0x3d2, 0x3d3, 0x413, 0x403, 0x41a, 0x40c, 0x433, 0x453, - 0x43a, 0x45c, 0x1f00, 0x1f04, 0x1f01, 0x1f05, 0x1f08, 0x1f0c, - 0x1f09, 0x1f0d, 0x1f10, 0x1f14, 0x1f11, 0x1f15, 0x1f18, 0x1f1c, - 0x1f19, 0x1f1d, 0x1f20, 0x1f24, 0x1f21, 0x1f25, 0x1f28, 0x1f2c, - 0x1f29, 0x1f2d, 0x1f30, 0x1f34, 0x1f31, 0x1f35, 0x1f38, 0x1f3c, - 0x1f39, 0x1f3d, 0x1f40, 0x1f44, 0x1f41, 0x1f45, 0x1f48, 0x1f4c, - 0x1f49, 0x1f4d, 0x1f50, 0x1f54, 0x1f51, 0x1f55, 0x1f59, 0x1f5d, - 0x1f60, 0x1f64, 0x1f61, 0x1f65, 0x1f68, 0x1f6c, 0x1f69, 0x1f6d, - 0x1fbf, 0x1fce, 0x1ffe, 0x1fde, 0x20, 0x41, 0xc2, 0x43, - 0x108, 0x45, 0xca, 0x47, 0x11c, 0x48, 0x124, 0x49, - 0xce, 0x4a, 0x134, 0x4f, 0xd4, 0x53, 0x15c, 0x55, - 0xdb, 0x57, 0x174, 0x59, 0x176, 0x5a, 0x1e90, 0x61, - 0xe2, 0x63, 0x109, 0x65, 0xea, 0x67, 0x11d, 0x68, - 0x125, 0x69, 0xee, 0x6a, 0x135, 0x6f, 0xf4, 0x73, - 0x15d, 0x75, 0xfb, 0x77, 0x175, 0x79, 0x177, 0x7a, - 0x1e91, 0x1ea0, 0x1eac, 0x1ea1, 0x1ead, 0x1eb8, 0x1ec6, 0x1eb9, - 0x1ec7, 0x1ecc, 0x1ed8, 0x1ecd, 0x1ed9, 0x1c, 0x41, 0xc3, - 0x45, 0x1ebc, 0x49, 0x128, 0x4e, 0xd1, 0x4f, 0xd5, - 0x55, 0x168, 0x56, 0x1e7c, 0x59, 0x1ef8, 0x61, 0xe3, - 0x65, 0x1ebd, 0x69, 0x129, 0x6e, 0xf1, 0x6f, 0xf5, - 0x75, 0x169, 0x76, 0x1e7d, 0x79, 0x1ef9, 0xc2, 0x1eaa, - 0xca, 0x1ec4, 0xd4, 0x1ed6, 0xe2, 0x1eab, 0xea, 0x1ec5, - 0xf4, 0x1ed7, 0x102, 0x1eb4, 0x103, 0x1eb5, 0x1a0, 0x1ee0, - 0x1a1, 0x1ee1, 0x1af, 0x1eee, 0x1b0, 0x1eef, 0x2c, 0x41, - 0x100, 0x45, 0x112, 0x47, 0x1e20, 0x49, 0x12a, 0x4f, - 0x14c, 0x55, 0x16a, 0x59, 0x232, 0x61, 0x101, 0x65, - 0x113, 0x67, 0x1e21, 0x69, 0x12b, 0x6f, 0x14d, 0x75, - 0x16b, 0x79, 0x233, 0xc4, 0x1de, 0xc6, 0x1e2, 0xd5, - 0x22c, 0xd6, 0x22a, 0xdc, 0x1d5, 0xe4, 0x1df, 0xe6, - 0x1e3, 0xf5, 0x22d, 0xf6, 0x22b, 0xfc, 0x1d6, 0x1ea, - 0x1ec, 0x1eb, 0x1ed, 0x226, 0x1e0, 0x227, 0x1e1, 0x22e, - 0x230, 0x22f, 0x231, 0x391, 0x1fb9, 0x399, 0x1fd9, 0x3a5, - 0x1fe9, 0x3b1, 0x1fb1, 0x3b9, 0x1fd1, 0x3c5, 0x1fe1, 0x418, - 0x4e2, 0x423, 0x4ee, 0x438, 0x4e3, 0x443, 0x4ef, 0x1e36, - 0x1e38, 0x1e37, 0x1e39, 0x1e5a, 0x1e5c, 0x1e5b, 0x1e5d, 0x20, - 0x41, 0x102, 0x45, 0x114, 0x47, 0x11e, 0x49, 0x12c, - 0x4f, 0x14e, 0x55, 0x16c, 0x61, 0x103, 0x65, 0x115, - 0x67, 0x11f, 0x69, 0x12d, 0x6f, 0x14f, 0x75, 0x16d, - 0x228, 0x1e1c, 0x229, 0x1e1d, 0x391, 0x1fb8, 0x399, 0x1fd8, - 0x3a5, 0x1fe8, 0x3b1, 0x1fb0, 0x3b9, 0x1fd0, 0x3c5, 0x1fe0, - 0x410, 0x4d0, 0x415, 0x4d6, 0x416, 0x4c1, 0x418, 0x419, - 0x423, 0x40e, 0x430, 0x4d1, 0x435, 0x4d7, 0x436, 0x4c2, - 0x438, 0x439, 0x443, 0x45e, 0x1ea0, 0x1eb6, 0x1ea1, 0x1eb7, - 0x2e, 0x41, 0x226, 0x42, 0x1e02, 0x43, 0x10a, 0x44, - 0x1e0a, 0x45, 0x116, 0x46, 0x1e1e, 0x47, 0x120, 0x48, - 0x1e22, 0x49, 0x130, 0x4d, 0x1e40, 0x4e, 0x1e44, 0x4f, - 0x22e, 0x50, 0x1e56, 0x52, 0x1e58, 0x53, 0x1e60, 0x54, - 0x1e6a, 0x57, 0x1e86, 0x58, 0x1e8a, 0x59, 0x1e8e, 0x5a, - 0x17b, 0x61, 0x227, 0x62, 0x1e03, 0x63, 0x10b, 0x64, - 0x1e0b, 0x65, 0x117, 0x66, 0x1e1f, 0x67, 0x121, 0x68, - 0x1e23, 0x6d, 0x1e41, 0x6e, 0x1e45, 0x6f, 0x22f, 0x70, - 0x1e57, 0x72, 0x1e59, 0x73, 0x1e61, 0x74, 0x1e6b, 0x77, - 0x1e87, 0x78, 0x1e8b, 0x79, 0x1e8f, 0x7a, 0x17c, 0x15a, - 0x1e64, 0x15b, 0x1e65, 0x160, 0x1e66, 0x161, 0x1e67, 0x17f, - 0x1e9b, 0x1e62, 0x1e68, 0x1e63, 0x1e69, 0x36, 0x41, 0xc4, - 0x45, 0xcb, 0x48, 0x1e26, 0x49, 0xcf, 0x4f, 0xd6, - 0x55, 0xdc, 0x57, 0x1e84, 0x58, 0x1e8c, 0x59, 0x178, - 0x61, 0xe4, 0x65, 0xeb, 0x68, 0x1e27, 0x69, 0xef, - 0x6f, 0xf6, 0x74, 0x1e97, 0x75, 0xfc, 0x77, 0x1e85, - 0x78, 0x1e8d, 0x79, 0xff, 0xd5, 0x1e4e, 0xf5, 0x1e4f, - 0x16a, 0x1e7a, 0x16b, 0x1e7b, 0x399, 0x3aa, 0x3a5, 0x3ab, - 0x3b9, 0x3ca, 0x3c5, 0x3cb, 0x3d2, 0x3d4, 0x406, 0x407, - 0x410, 0x4d2, 0x415, 0x401, 0x416, 0x4dc, 0x417, 0x4de, - 0x418, 0x4e4, 0x41e, 0x4e6, 0x423, 0x4f0, 0x427, 0x4f4, - 0x42b, 0x4f8, 0x42d, 0x4ec, 0x430, 0x4d3, 0x435, 0x451, - 0x436, 0x4dd, 0x437, 0x4df, 0x438, 0x4e5, 0x43e, 0x4e7, - 0x443, 0x4f1, 0x447, 0x4f5, 0x44b, 0x4f9, 0x44d, 0x4ed, - 0x456, 0x457, 0x4d8, 0x4da, 0x4d9, 0x4db, 0x4e8, 0x4ea, - 0x4e9, 0x4eb, 0x18, 0x41, 0x1ea2, 0x45, 0x1eba, 0x49, - 0x1ec8, 0x4f, 0x1ece, 0x55, 0x1ee6, 0x59, 0x1ef6, 0x61, - 0x1ea3, 0x65, 0x1ebb, 0x69, 0x1ec9, 0x6f, 0x1ecf, 0x75, - 0x1ee7, 0x79, 0x1ef7, 0xc2, 0x1ea8, 0xca, 0x1ec2, 0xd4, - 0x1ed4, 0xe2, 0x1ea9, 0xea, 0x1ec3, 0xf4, 0x1ed5, 0x102, - 0x1eb2, 0x103, 0x1eb3, 0x1a0, 0x1ede, 0x1a1, 0x1edf, 0x1af, - 0x1eec, 0x1b0, 0x1eed, 0x6, 0x41, 0xc5, 0x55, 0x16e, - 0x61, 0xe5, 0x75, 0x16f, 0x77, 0x1e98, 0x79, 0x1e99, - 0x6, 0x4f, 0x150, 0x55, 0x170, 0x6f, 0x151, 0x75, - 0x171, 0x423, 0x4f2, 0x443, 0x4f3, 0x25, 0x41, 0x1cd, - 0x43, 0x10c, 0x44, 0x10e, 0x45, 0x11a, 0x47, 0x1e6, - 0x48, 0x21e, 0x49, 0x1cf, 0x4b, 0x1e8, 0x4c, 0x13d, - 0x4e, 0x147, 0x4f, 0x1d1, 0x52, 0x158, 0x53, 0x160, - 0x54, 0x164, 0x55, 0x1d3, 0x5a, 0x17d, 0x61, 0x1ce, - 0x63, 0x10d, 0x64, 0x10f, 0x65, 0x11b, 0x67, 0x1e7, - 0x68, 0x21f, 0x69, 0x1d0, 0x6a, 0x1f0, 0x6b, 0x1e9, - 0x6c, 0x13e, 0x6e, 0x148, 0x6f, 0x1d2, 0x72, 0x159, - 0x73, 0x161, 0x74, 0x165, 0x75, 0x1d4, 0x7a, 0x17e, - 0xdc, 0x1d9, 0xfc, 0x1da, 0x1b7, 0x1ee, 0x292, 0x1ef, - 0xe, 0x41, 0x200, 0x45, 0x204, 0x49, 0x208, 0x4f, - 0x20c, 0x52, 0x210, 0x55, 0x214, 0x61, 0x201, 0x65, - 0x205, 0x69, 0x209, 0x6f, 0x20d, 0x72, 0x211, 0x75, - 0x215, 0x474, 0x476, 0x475, 0x477, 0xc, 0x41, 0x202, - 0x45, 0x206, 0x49, 0x20a, 0x4f, 0x20e, 0x52, 0x212, - 0x55, 0x216, 0x61, 0x203, 0x65, 0x207, 0x69, 0x20b, - 0x6f, 0x20f, 0x72, 0x213, 0x75, 0x217, 0xe, 0x391, - 0x1f08, 0x395, 0x1f18, 0x397, 0x1f28, 0x399, 0x1f38, 0x39f, - 0x1f48, 0x3a9, 0x1f68, 0x3b1, 0x1f00, 0x3b5, 0x1f10, 0x3b7, - 0x1f20, 0x3b9, 0x1f30, 0x3bf, 0x1f40, 0x3c1, 0x1fe4, 0x3c5, - 0x1f50, 0x3c9, 0x1f60, 0x10, 0x391, 0x1f09, 0x395, 0x1f19, - 0x397, 0x1f29, 0x399, 0x1f39, 0x39f, 0x1f49, 0x3a1, 0x1fec, - 0x3a5, 0x1f59, 0x3a9, 0x1f69, 0x3b1, 0x1f01, 0x3b5, 0x1f11, - 0x3b7, 0x1f21, 0x3b9, 0x1f31, 0x3bf, 0x1f41, 0x3c1, 0x1fe5, - 0x3c5, 0x1f51, 0x3c9, 0x1f61, 0x4, 0x4f, 0x1a0, 0x55, - 0x1af, 0x6f, 0x1a1, 0x75, 0x1b0, 0x2a, 0x41, 0x1ea0, - 0x42, 0x1e04, 0x44, 0x1e0c, 0x45, 0x1eb8, 0x48, 0x1e24, - 0x49, 0x1eca, 0x4b, 0x1e32, 0x4c, 0x1e36, 0x4d, 0x1e42, - 0x4e, 0x1e46, 0x4f, 0x1ecc, 0x52, 0x1e5a, 0x53, 0x1e62, - 0x54, 0x1e6c, 0x55, 0x1ee4, 0x56, 0x1e7e, 0x57, 0x1e88, - 0x59, 0x1ef4, 0x5a, 0x1e92, 0x61, 0x1ea1, 0x62, 0x1e05, - 0x64, 0x1e0d, 0x65, 0x1eb9, 0x68, 0x1e25, 0x69, 0x1ecb, - 0x6b, 0x1e33, 0x6c, 0x1e37, 0x6d, 0x1e43, 0x6e, 0x1e47, - 0x6f, 0x1ecd, 0x72, 0x1e5b, 0x73, 0x1e63, 0x74, 0x1e6d, - 0x75, 0x1ee5, 0x76, 0x1e7f, 0x77, 0x1e89, 0x79, 0x1ef5, - 0x7a, 0x1e93, 0x1a0, 0x1ee2, 0x1a1, 0x1ee3, 0x1af, 0x1ef0, - 0x1b0, 0x1ef1, 0x2, 0x55, 0x1e72, 0x75, 0x1e73, 0x2, - 0x41, 0x1e00, 0x61, 0x1e01, 0x4, 0x53, 0x218, 0x54, - 0x21a, 0x73, 0x219, 0x74, 0x21b, 0x16, 0x43, 0xc7, - 0x44, 0x1e10, 0x45, 0x228, 0x47, 0x122, 0x48, 0x1e28, - 0x4b, 0x136, 0x4c, 0x13b, 0x4e, 0x145, 0x52, 0x156, - 0x53, 0x15e, 0x54, 0x162, 0x63, 0xe7, 0x64, 0x1e11, - 0x65, 0x229, 0x67, 0x123, 0x68, 0x1e29, 0x6b, 0x137, - 0x6c, 0x13c, 0x6e, 0x146, 0x72, 0x157, 0x73, 0x15f, - 0x74, 0x163, 0xa, 0x41, 0x104, 0x45, 0x118, 0x49, - 0x12e, 0x4f, 0x1ea, 0x55, 0x172, 0x61, 0x105, 0x65, - 0x119, 0x69, 0x12f, 0x6f, 0x1eb, 0x75, 0x173, 0xc, - 0x44, 0x1e12, 0x45, 0x1e18, 0x4c, 0x1e3c, 0x4e, 0x1e4a, - 0x54, 0x1e70, 0x55, 0x1e76, 0x64, 0x1e13, 0x65, 0x1e19, - 0x6c, 0x1e3d, 0x6e, 0x1e4b, 0x74, 0x1e71, 0x75, 0x1e77, - 0x2, 0x48, 0x1e2a, 0x68, 0x1e2b, 0x6, 0x45, 0x1e1a, - 0x49, 0x1e2c, 0x55, 0x1e74, 0x65, 0x1e1b, 0x69, 0x1e2d, - 0x75, 0x1e75, 0x11, 0x42, 0x1e06, 0x44, 0x1e0e, 0x4b, - 0x1e34, 0x4c, 0x1e3a, 0x4e, 0x1e48, 0x52, 0x1e5e, 0x54, - 0x1e6e, 0x5a, 0x1e94, 0x62, 0x1e07, 0x64, 0x1e0f, 0x68, - 0x1e96, 0x6b, 0x1e35, 0x6c, 0x1e3b, 0x6e, 0x1e49, 0x72, - 0x1e5f, 0x74, 0x1e6f, 0x7a, 0x1e95, 0x2c, 0x3c, 0x226e, - 0x3d, 0x2260, 0x3e, 0x226f, 0x2190, 0x219a, 0x2192, 0x219b, - 0x2194, 0x21ae, 0x21d0, 0x21cd, 0x21d2, 0x21cf, 0x21d4, 0x21ce, - 0x2203, 0x2204, 0x2208, 0x2209, 0x220b, 0x220c, 0x2223, 0x2224, - 0x2225, 0x2226, 0x223c, 0x2241, 0x2243, 0x2244, 0x2245, 0x2247, - 0x2248, 0x2249, 0x224d, 0x226d, 0x2261, 0x2262, 0x2264, 0x2270, - 0x2265, 0x2271, 0x2272, 0x2274, 0x2273, 0x2275, 0x2276, 0x2278, - 0x2277, 0x2279, 0x227a, 0x2280, 0x227b, 0x2281, 0x227c, 0x22e0, - 0x227d, 0x22e1, 0x2282, 0x2284, 0x2283, 0x2285, 0x2286, 0x2288, - 0x2287, 0x2289, 0x2291, 0x22e2, 0x2292, 0x22e3, 0x22a2, 0x22ac, - 0x22a8, 0x22ad, 0x22a9, 0x22ae, 0x22ab, 0x22af, 0x22b2, 0x22ea, - 0x22b3, 0x22eb, 0x22b4, 0x22ec, 0x22b5, 0x22ed, 0x1d, 0xa8, - 0x1fc1, 0x3b1, 0x1fb6, 0x3b7, 0x1fc6, 0x3b9, 0x1fd6, 0x3c5, - 0x1fe6, 0x3c9, 0x1ff6, 0x3ca, 0x1fd7, 0x3cb, 0x1fe7, 0x1f00, - 0x1f06, 0x1f01, 0x1f07, 0x1f08, 0x1f0e, 0x1f09, 0x1f0f, 0x1f20, - 0x1f26, 0x1f21, 0x1f27, 0x1f28, 0x1f2e, 0x1f29, 0x1f2f, 0x1f30, - 0x1f36, 0x1f31, 0x1f37, 0x1f38, 0x1f3e, 0x1f39, 0x1f3f, 0x1f50, - 0x1f56, 0x1f51, 0x1f57, 0x1f59, 0x1f5f, 0x1f60, 0x1f66, 0x1f61, - 0x1f67, 0x1f68, 0x1f6e, 0x1f69, 0x1f6f, 0x1fbf, 0x1fcf, 0x1ffe, - 0x1fdf, 0x3f, 0x391, 0x1fbc, 0x397, 0x1fcc, 0x3a9, 0x1ffc, - 0x3ac, 0x1fb4, 0x3ae, 0x1fc4, 0x3b1, 0x1fb3, 0x3b7, 0x1fc3, - 0x3c9, 0x1ff3, 0x3ce, 0x1ff4, 0x1f00, 0x1f80, 0x1f01, 0x1f81, - 0x1f02, 0x1f82, 0x1f03, 0x1f83, 0x1f04, 0x1f84, 0x1f05, 0x1f85, - 0x1f06, 0x1f86, 0x1f07, 0x1f87, 0x1f08, 0x1f88, 0x1f09, 0x1f89, - 0x1f0a, 0x1f8a, 0x1f0b, 0x1f8b, 0x1f0c, 0x1f8c, 0x1f0d, 0x1f8d, - 0x1f0e, 0x1f8e, 0x1f0f, 0x1f8f, 0x1f20, 0x1f90, 0x1f21, 0x1f91, - 0x1f22, 0x1f92, 0x1f23, 0x1f93, 0x1f24, 0x1f94, 0x1f25, 0x1f95, - 0x1f26, 0x1f96, 0x1f27, 0x1f97, 0x1f28, 0x1f98, 0x1f29, 0x1f99, - 0x1f2a, 0x1f9a, 0x1f2b, 0x1f9b, 0x1f2c, 0x1f9c, 0x1f2d, 0x1f9d, - 0x1f2e, 0x1f9e, 0x1f2f, 0x1f9f, 0x1f60, 0x1fa0, 0x1f61, 0x1fa1, - 0x1f62, 0x1fa2, 0x1f63, 0x1fa3, 0x1f64, 0x1fa4, 0x1f65, 0x1fa5, - 0x1f66, 0x1fa6, 0x1f67, 0x1fa7, 0x1f68, 0x1fa8, 0x1f69, 0x1fa9, - 0x1f6a, 0x1faa, 0x1f6b, 0x1fab, 0x1f6c, 0x1fac, 0x1f6d, 0x1fad, - 0x1f6e, 0x1fae, 0x1f6f, 0x1faf, 0x1f70, 0x1fb2, 0x1f74, 0x1fc2, - 0x1f7c, 0x1ff2, 0x1fb6, 0x1fb7, 0x1fc6, 0x1fc7, 0x1ff6, 0x1ff7, - 0x1, 0x627, 0x622, 0x6, 0x627, 0x623, 0x648, 0x624, - 0x64a, 0x626, 0x6c1, 0x6c2, 0x6d2, 0x6d3, 0x6d5, 0x6c0, - 0x1, 0x627, 0x625, 0x3, 0x928, 0x929, 0x930, 0x931, - 0x933, 0x934, 0x1, 0x9c7, 0x9cb, 0x1, 0x9c7, 0x9cc, - 0x1, 0xb47, 0xb4b, 0x1, 0xb47, 0xb48, 0x1, 0xb47, - 0xb4c, 0x2, 0xbc6, 0xbca, 0xbc7, 0xbcb, 0x2, 0xb92, - 0xb94, 0xbc6, 0xbcc, 0x1, 0xc46, 0xc48, 0x1, 0xcc6, - 0xcca, 0x3, 0xcbf, 0xcc0, 0xcc6, 0xcc7, 0xcca, 0xccb, - 0x1, 0xcc6, 0xcc8, 0x2, 0xd46, 0xd4a, 0xd47, 0xd4b, - 0x1, 0xd46, 0xd4c, 0x2, 0xdd9, 0xdda, 0xddc, 0xddd, - 0x1, 0xdd9, 0xddc, 0x1, 0xdd9, 0xdde, 0x1, 0x1025, - 0x1026, 0xb, 0x1b05, 0x1b06, 0x1b07, 0x1b08, 0x1b09, 0x1b0a, - 0x1b0b, 0x1b0c, 0x1b0d, 0x1b0e, 0x1b11, 0x1b12, 0x1b3a, 0x1b3b, - 0x1b3c, 0x1b3d, 0x1b3e, 0x1b40, 0x1b3f, 0x1b41, 0x1b42, 0x1b43, - 0x30, 0x3046, 0x3094, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, - 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, - 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, - 0x3060, 0x3061, 0x3062, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, - 0x3069, 0x306f, 0x3070, 0x3072, 0x3073, 0x3075, 0x3076, 0x3078, - 0x3079, 0x307b, 0x307c, 0x309d, 0x309e, 0x30a6, 0x30f4, 0x30ab, - 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3, - 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb, - 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c4, - 0x30c5, 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30cf, 0x30d0, 0x30d2, - 0x30d3, 0x30d5, 0x30d6, 0x30d8, 0x30d9, 0x30db, 0x30dc, 0x30ef, - 0x30f7, 0x30f0, 0x30f8, 0x30f1, 0x30f9, 0x30f2, 0x30fa, 0x30fd, - 0x30fe, 0xa, 0x306f, 0x3071, 0x3072, 0x3074, 0x3075, 0x3077, - 0x3078, 0x307a, 0x307b, 0x307d, 0x30cf, 0x30d1, 0x30d2, 0x30d4, - 0x30d5, 0x30d7, 0x30d8, 0x30da, 0x30db, 0x30dd, + 0x54, 0x41, 0xc0, 0x45, 0xc8, 0x49, 0xcc, 0x4e, + 0x1f8, 0x4f, 0xd2, 0x55, 0xd9, 0x57, 0x1e80, 0x59, + 0x1ef2, 0x61, 0xe0, 0x65, 0xe8, 0x69, 0xec, 0x6e, + 0x1f9, 0x6f, 0xf2, 0x75, 0xf9, 0x77, 0x1e81, 0x79, + 0x1ef3, 0xa8, 0x1fed, 0xc2, 0x1ea6, 0xca, 0x1ec0, 0xd4, + 0x1ed2, 0xdc, 0x1db, 0xe2, 0x1ea7, 0xea, 0x1ec1, 0xf4, + 0x1ed3, 0xfc, 0x1dc, 0x102, 0x1eb0, 0x103, 0x1eb1, 0x112, + 0x1e14, 0x113, 0x1e15, 0x14c, 0x1e50, 0x14d, 0x1e51, 0x1a0, + 0x1edc, 0x1a1, 0x1edd, 0x1af, 0x1eea, 0x1b0, 0x1eeb, 0x391, + 0x1fba, 0x395, 0x1fc8, 0x397, 0x1fca, 0x399, 0x1fda, 0x39f, + 0x1ff8, 0x3a5, 0x1fea, 0x3a9, 0x1ffa, 0x3b1, 0x1f70, 0x3b5, + 0x1f72, 0x3b7, 0x1f74, 0x3b9, 0x1f76, 0x3bf, 0x1f78, 0x3c5, + 0x1f7a, 0x3c9, 0x1f7c, 0x3ca, 0x1fd2, 0x3cb, 0x1fe2, 0x415, + 0x400, 0x418, 0x40d, 0x435, 0x450, 0x438, 0x45d, 0x1f00, + 0x1f02, 0x1f01, 0x1f03, 0x1f08, 0x1f0a, 0x1f09, 0x1f0b, 0x1f10, + 0x1f12, 0x1f11, 0x1f13, 0x1f18, 0x1f1a, 0x1f19, 0x1f1b, 0x1f20, + 0x1f22, 0x1f21, 0x1f23, 0x1f28, 0x1f2a, 0x1f29, 0x1f2b, 0x1f30, + 0x1f32, 0x1f31, 0x1f33, 0x1f38, 0x1f3a, 0x1f39, 0x1f3b, 0x1f40, + 0x1f42, 0x1f41, 0x1f43, 0x1f48, 0x1f4a, 0x1f49, 0x1f4b, 0x1f50, + 0x1f52, 0x1f51, 0x1f53, 0x1f59, 0x1f5b, 0x1f60, 0x1f62, 0x1f61, + 0x1f63, 0x1f68, 0x1f6a, 0x1f69, 0x1f6b, 0x1fbf, 0x1fcd, 0x1ffe, + 0x1fdd, 0x75, 0x41, 0xc1, 0x43, 0x106, 0x45, 0xc9, + 0x47, 0x1f4, 0x49, 0xcd, 0x4b, 0x1e30, 0x4c, 0x139, + 0x4d, 0x1e3e, 0x4e, 0x143, 0x4f, 0xd3, 0x50, 0x1e54, + 0x52, 0x154, 0x53, 0x15a, 0x55, 0xda, 0x57, 0x1e82, + 0x59, 0xdd, 0x5a, 0x179, 0x61, 0xe1, 0x63, 0x107, + 0x65, 0xe9, 0x67, 0x1f5, 0x69, 0xed, 0x6b, 0x1e31, + 0x6c, 0x13a, 0x6d, 0x1e3f, 0x6e, 0x144, 0x6f, 0xf3, + 0x70, 0x1e55, 0x72, 0x155, 0x73, 0x15b, 0x75, 0xfa, + 0x77, 0x1e83, 0x79, 0xfd, 0x7a, 0x17a, 0xa8, 0x385, + 0xc2, 0x1ea4, 0xc5, 0x1fa, 0xc6, 0x1fc, 0xc7, 0x1e08, + 0xca, 0x1ebe, 0xcf, 0x1e2e, 0xd4, 0x1ed0, 0xd5, 0x1e4c, + 0xd8, 0x1fe, 0xdc, 0x1d7, 0xe2, 0x1ea5, 0xe5, 0x1fb, + 0xe6, 0x1fd, 0xe7, 0x1e09, 0xea, 0x1ebf, 0xef, 0x1e2f, + 0xf4, 0x1ed1, 0xf5, 0x1e4d, 0xf8, 0x1ff, 0xfc, 0x1d8, + 0x102, 0x1eae, 0x103, 0x1eaf, 0x112, 0x1e16, 0x113, 0x1e17, + 0x14c, 0x1e52, 0x14d, 0x1e53, 0x168, 0x1e78, 0x169, 0x1e79, + 0x1a0, 0x1eda, 0x1a1, 0x1edb, 0x1af, 0x1ee8, 0x1b0, 0x1ee9, + 0x391, 0x386, 0x395, 0x388, 0x397, 0x389, 0x399, 0x38a, + 0x39f, 0x38c, 0x3a5, 0x38e, 0x3a9, 0x38f, 0x3b1, 0x3ac, + 0x3b5, 0x3ad, 0x3b7, 0x3ae, 0x3b9, 0x3af, 0x3bf, 0x3cc, + 0x3c5, 0x3cd, 0x3c9, 0x3ce, 0x3ca, 0x390, 0x3cb, 0x3b0, + 0x3d2, 0x3d3, 0x413, 0x403, 0x41a, 0x40c, 0x433, 0x453, + 0x43a, 0x45c, 0x1f00, 0x1f04, 0x1f01, 0x1f05, 0x1f08, 0x1f0c, + 0x1f09, 0x1f0d, 0x1f10, 0x1f14, 0x1f11, 0x1f15, 0x1f18, 0x1f1c, + 0x1f19, 0x1f1d, 0x1f20, 0x1f24, 0x1f21, 0x1f25, 0x1f28, 0x1f2c, + 0x1f29, 0x1f2d, 0x1f30, 0x1f34, 0x1f31, 0x1f35, 0x1f38, 0x1f3c, + 0x1f39, 0x1f3d, 0x1f40, 0x1f44, 0x1f41, 0x1f45, 0x1f48, 0x1f4c, + 0x1f49, 0x1f4d, 0x1f50, 0x1f54, 0x1f51, 0x1f55, 0x1f59, 0x1f5d, + 0x1f60, 0x1f64, 0x1f61, 0x1f65, 0x1f68, 0x1f6c, 0x1f69, 0x1f6d, + 0x1fbf, 0x1fce, 0x1ffe, 0x1fde, 0x20, 0x41, 0xc2, 0x43, + 0x108, 0x45, 0xca, 0x47, 0x11c, 0x48, 0x124, 0x49, + 0xce, 0x4a, 0x134, 0x4f, 0xd4, 0x53, 0x15c, 0x55, + 0xdb, 0x57, 0x174, 0x59, 0x176, 0x5a, 0x1e90, 0x61, + 0xe2, 0x63, 0x109, 0x65, 0xea, 0x67, 0x11d, 0x68, + 0x125, 0x69, 0xee, 0x6a, 0x135, 0x6f, 0xf4, 0x73, + 0x15d, 0x75, 0xfb, 0x77, 0x175, 0x79, 0x177, 0x7a, + 0x1e91, 0x1ea0, 0x1eac, 0x1ea1, 0x1ead, 0x1eb8, 0x1ec6, 0x1eb9, + 0x1ec7, 0x1ecc, 0x1ed8, 0x1ecd, 0x1ed9, 0x1c, 0x41, 0xc3, + 0x45, 0x1ebc, 0x49, 0x128, 0x4e, 0xd1, 0x4f, 0xd5, + 0x55, 0x168, 0x56, 0x1e7c, 0x59, 0x1ef8, 0x61, 0xe3, + 0x65, 0x1ebd, 0x69, 0x129, 0x6e, 0xf1, 0x6f, 0xf5, + 0x75, 0x169, 0x76, 0x1e7d, 0x79, 0x1ef9, 0xc2, 0x1eaa, + 0xca, 0x1ec4, 0xd4, 0x1ed6, 0xe2, 0x1eab, 0xea, 0x1ec5, + 0xf4, 0x1ed7, 0x102, 0x1eb4, 0x103, 0x1eb5, 0x1a0, 0x1ee0, + 0x1a1, 0x1ee1, 0x1af, 0x1eee, 0x1b0, 0x1eef, 0x2c, 0x41, + 0x100, 0x45, 0x112, 0x47, 0x1e20, 0x49, 0x12a, 0x4f, + 0x14c, 0x55, 0x16a, 0x59, 0x232, 0x61, 0x101, 0x65, + 0x113, 0x67, 0x1e21, 0x69, 0x12b, 0x6f, 0x14d, 0x75, + 0x16b, 0x79, 0x233, 0xc4, 0x1de, 0xc6, 0x1e2, 0xd5, + 0x22c, 0xd6, 0x22a, 0xdc, 0x1d5, 0xe4, 0x1df, 0xe6, + 0x1e3, 0xf5, 0x22d, 0xf6, 0x22b, 0xfc, 0x1d6, 0x1ea, + 0x1ec, 0x1eb, 0x1ed, 0x226, 0x1e0, 0x227, 0x1e1, 0x22e, + 0x230, 0x22f, 0x231, 0x391, 0x1fb9, 0x399, 0x1fd9, 0x3a5, + 0x1fe9, 0x3b1, 0x1fb1, 0x3b9, 0x1fd1, 0x3c5, 0x1fe1, 0x418, + 0x4e2, 0x423, 0x4ee, 0x438, 0x4e3, 0x443, 0x4ef, 0x1e36, + 0x1e38, 0x1e37, 0x1e39, 0x1e5a, 0x1e5c, 0x1e5b, 0x1e5d, 0x20, + 0x41, 0x102, 0x45, 0x114, 0x47, 0x11e, 0x49, 0x12c, + 0x4f, 0x14e, 0x55, 0x16c, 0x61, 0x103, 0x65, 0x115, + 0x67, 0x11f, 0x69, 0x12d, 0x6f, 0x14f, 0x75, 0x16d, + 0x228, 0x1e1c, 0x229, 0x1e1d, 0x391, 0x1fb8, 0x399, 0x1fd8, + 0x3a5, 0x1fe8, 0x3b1, 0x1fb0, 0x3b9, 0x1fd0, 0x3c5, 0x1fe0, + 0x410, 0x4d0, 0x415, 0x4d6, 0x416, 0x4c1, 0x418, 0x419, + 0x423, 0x40e, 0x430, 0x4d1, 0x435, 0x4d7, 0x436, 0x4c2, + 0x438, 0x439, 0x443, 0x45e, 0x1ea0, 0x1eb6, 0x1ea1, 0x1eb7, + 0x2e, 0x41, 0x226, 0x42, 0x1e02, 0x43, 0x10a, 0x44, + 0x1e0a, 0x45, 0x116, 0x46, 0x1e1e, 0x47, 0x120, 0x48, + 0x1e22, 0x49, 0x130, 0x4d, 0x1e40, 0x4e, 0x1e44, 0x4f, + 0x22e, 0x50, 0x1e56, 0x52, 0x1e58, 0x53, 0x1e60, 0x54, + 0x1e6a, 0x57, 0x1e86, 0x58, 0x1e8a, 0x59, 0x1e8e, 0x5a, + 0x17b, 0x61, 0x227, 0x62, 0x1e03, 0x63, 0x10b, 0x64, + 0x1e0b, 0x65, 0x117, 0x66, 0x1e1f, 0x67, 0x121, 0x68, + 0x1e23, 0x6d, 0x1e41, 0x6e, 0x1e45, 0x6f, 0x22f, 0x70, + 0x1e57, 0x72, 0x1e59, 0x73, 0x1e61, 0x74, 0x1e6b, 0x77, + 0x1e87, 0x78, 0x1e8b, 0x79, 0x1e8f, 0x7a, 0x17c, 0x15a, + 0x1e64, 0x15b, 0x1e65, 0x160, 0x1e66, 0x161, 0x1e67, 0x17f, + 0x1e9b, 0x1e62, 0x1e68, 0x1e63, 0x1e69, 0x36, 0x41, 0xc4, + 0x45, 0xcb, 0x48, 0x1e26, 0x49, 0xcf, 0x4f, 0xd6, + 0x55, 0xdc, 0x57, 0x1e84, 0x58, 0x1e8c, 0x59, 0x178, + 0x61, 0xe4, 0x65, 0xeb, 0x68, 0x1e27, 0x69, 0xef, + 0x6f, 0xf6, 0x74, 0x1e97, 0x75, 0xfc, 0x77, 0x1e85, + 0x78, 0x1e8d, 0x79, 0xff, 0xd5, 0x1e4e, 0xf5, 0x1e4f, + 0x16a, 0x1e7a, 0x16b, 0x1e7b, 0x399, 0x3aa, 0x3a5, 0x3ab, + 0x3b9, 0x3ca, 0x3c5, 0x3cb, 0x3d2, 0x3d4, 0x406, 0x407, + 0x410, 0x4d2, 0x415, 0x401, 0x416, 0x4dc, 0x417, 0x4de, + 0x418, 0x4e4, 0x41e, 0x4e6, 0x423, 0x4f0, 0x427, 0x4f4, + 0x42b, 0x4f8, 0x42d, 0x4ec, 0x430, 0x4d3, 0x435, 0x451, + 0x436, 0x4dd, 0x437, 0x4df, 0x438, 0x4e5, 0x43e, 0x4e7, + 0x443, 0x4f1, 0x447, 0x4f5, 0x44b, 0x4f9, 0x44d, 0x4ed, + 0x456, 0x457, 0x4d8, 0x4da, 0x4d9, 0x4db, 0x4e8, 0x4ea, + 0x4e9, 0x4eb, 0x18, 0x41, 0x1ea2, 0x45, 0x1eba, 0x49, + 0x1ec8, 0x4f, 0x1ece, 0x55, 0x1ee6, 0x59, 0x1ef6, 0x61, + 0x1ea3, 0x65, 0x1ebb, 0x69, 0x1ec9, 0x6f, 0x1ecf, 0x75, + 0x1ee7, 0x79, 0x1ef7, 0xc2, 0x1ea8, 0xca, 0x1ec2, 0xd4, + 0x1ed4, 0xe2, 0x1ea9, 0xea, 0x1ec3, 0xf4, 0x1ed5, 0x102, + 0x1eb2, 0x103, 0x1eb3, 0x1a0, 0x1ede, 0x1a1, 0x1edf, 0x1af, + 0x1eec, 0x1b0, 0x1eed, 0x6, 0x41, 0xc5, 0x55, 0x16e, + 0x61, 0xe5, 0x75, 0x16f, 0x77, 0x1e98, 0x79, 0x1e99, + 0x6, 0x4f, 0x150, 0x55, 0x170, 0x6f, 0x151, 0x75, + 0x171, 0x423, 0x4f2, 0x443, 0x4f3, 0x25, 0x41, 0x1cd, + 0x43, 0x10c, 0x44, 0x10e, 0x45, 0x11a, 0x47, 0x1e6, + 0x48, 0x21e, 0x49, 0x1cf, 0x4b, 0x1e8, 0x4c, 0x13d, + 0x4e, 0x147, 0x4f, 0x1d1, 0x52, 0x158, 0x53, 0x160, + 0x54, 0x164, 0x55, 0x1d3, 0x5a, 0x17d, 0x61, 0x1ce, + 0x63, 0x10d, 0x64, 0x10f, 0x65, 0x11b, 0x67, 0x1e7, + 0x68, 0x21f, 0x69, 0x1d0, 0x6a, 0x1f0, 0x6b, 0x1e9, + 0x6c, 0x13e, 0x6e, 0x148, 0x6f, 0x1d2, 0x72, 0x159, + 0x73, 0x161, 0x74, 0x165, 0x75, 0x1d4, 0x7a, 0x17e, + 0xdc, 0x1d9, 0xfc, 0x1da, 0x1b7, 0x1ee, 0x292, 0x1ef, + 0xe, 0x41, 0x200, 0x45, 0x204, 0x49, 0x208, 0x4f, + 0x20c, 0x52, 0x210, 0x55, 0x214, 0x61, 0x201, 0x65, + 0x205, 0x69, 0x209, 0x6f, 0x20d, 0x72, 0x211, 0x75, + 0x215, 0x474, 0x476, 0x475, 0x477, 0xc, 0x41, 0x202, + 0x45, 0x206, 0x49, 0x20a, 0x4f, 0x20e, 0x52, 0x212, + 0x55, 0x216, 0x61, 0x203, 0x65, 0x207, 0x69, 0x20b, + 0x6f, 0x20f, 0x72, 0x213, 0x75, 0x217, 0xe, 0x391, + 0x1f08, 0x395, 0x1f18, 0x397, 0x1f28, 0x399, 0x1f38, 0x39f, + 0x1f48, 0x3a9, 0x1f68, 0x3b1, 0x1f00, 0x3b5, 0x1f10, 0x3b7, + 0x1f20, 0x3b9, 0x1f30, 0x3bf, 0x1f40, 0x3c1, 0x1fe4, 0x3c5, + 0x1f50, 0x3c9, 0x1f60, 0x10, 0x391, 0x1f09, 0x395, 0x1f19, + 0x397, 0x1f29, 0x399, 0x1f39, 0x39f, 0x1f49, 0x3a1, 0x1fec, + 0x3a5, 0x1f59, 0x3a9, 0x1f69, 0x3b1, 0x1f01, 0x3b5, 0x1f11, + 0x3b7, 0x1f21, 0x3b9, 0x1f31, 0x3bf, 0x1f41, 0x3c1, 0x1fe5, + 0x3c5, 0x1f51, 0x3c9, 0x1f61, 0x4, 0x4f, 0x1a0, 0x55, + 0x1af, 0x6f, 0x1a1, 0x75, 0x1b0, 0x2a, 0x41, 0x1ea0, + 0x42, 0x1e04, 0x44, 0x1e0c, 0x45, 0x1eb8, 0x48, 0x1e24, + 0x49, 0x1eca, 0x4b, 0x1e32, 0x4c, 0x1e36, 0x4d, 0x1e42, + 0x4e, 0x1e46, 0x4f, 0x1ecc, 0x52, 0x1e5a, 0x53, 0x1e62, + 0x54, 0x1e6c, 0x55, 0x1ee4, 0x56, 0x1e7e, 0x57, 0x1e88, + 0x59, 0x1ef4, 0x5a, 0x1e92, 0x61, 0x1ea1, 0x62, 0x1e05, + 0x64, 0x1e0d, 0x65, 0x1eb9, 0x68, 0x1e25, 0x69, 0x1ecb, + 0x6b, 0x1e33, 0x6c, 0x1e37, 0x6d, 0x1e43, 0x6e, 0x1e47, + 0x6f, 0x1ecd, 0x72, 0x1e5b, 0x73, 0x1e63, 0x74, 0x1e6d, + 0x75, 0x1ee5, 0x76, 0x1e7f, 0x77, 0x1e89, 0x79, 0x1ef5, + 0x7a, 0x1e93, 0x1a0, 0x1ee2, 0x1a1, 0x1ee3, 0x1af, 0x1ef0, + 0x1b0, 0x1ef1, 0x2, 0x55, 0x1e72, 0x75, 0x1e73, 0x2, + 0x41, 0x1e00, 0x61, 0x1e01, 0x4, 0x53, 0x218, 0x54, + 0x21a, 0x73, 0x219, 0x74, 0x21b, 0x16, 0x43, 0xc7, + 0x44, 0x1e10, 0x45, 0x228, 0x47, 0x122, 0x48, 0x1e28, + 0x4b, 0x136, 0x4c, 0x13b, 0x4e, 0x145, 0x52, 0x156, + 0x53, 0x15e, 0x54, 0x162, 0x63, 0xe7, 0x64, 0x1e11, + 0x65, 0x229, 0x67, 0x123, 0x68, 0x1e29, 0x6b, 0x137, + 0x6c, 0x13c, 0x6e, 0x146, 0x72, 0x157, 0x73, 0x15f, + 0x74, 0x163, 0xa, 0x41, 0x104, 0x45, 0x118, 0x49, + 0x12e, 0x4f, 0x1ea, 0x55, 0x172, 0x61, 0x105, 0x65, + 0x119, 0x69, 0x12f, 0x6f, 0x1eb, 0x75, 0x173, 0xc, + 0x44, 0x1e12, 0x45, 0x1e18, 0x4c, 0x1e3c, 0x4e, 0x1e4a, + 0x54, 0x1e70, 0x55, 0x1e76, 0x64, 0x1e13, 0x65, 0x1e19, + 0x6c, 0x1e3d, 0x6e, 0x1e4b, 0x74, 0x1e71, 0x75, 0x1e77, + 0x2, 0x48, 0x1e2a, 0x68, 0x1e2b, 0x6, 0x45, 0x1e1a, + 0x49, 0x1e2c, 0x55, 0x1e74, 0x65, 0x1e1b, 0x69, 0x1e2d, + 0x75, 0x1e75, 0x11, 0x42, 0x1e06, 0x44, 0x1e0e, 0x4b, + 0x1e34, 0x4c, 0x1e3a, 0x4e, 0x1e48, 0x52, 0x1e5e, 0x54, + 0x1e6e, 0x5a, 0x1e94, 0x62, 0x1e07, 0x64, 0x1e0f, 0x68, + 0x1e96, 0x6b, 0x1e35, 0x6c, 0x1e3b, 0x6e, 0x1e49, 0x72, + 0x1e5f, 0x74, 0x1e6f, 0x7a, 0x1e95, 0x2c, 0x3c, 0x226e, + 0x3d, 0x2260, 0x3e, 0x226f, 0x2190, 0x219a, 0x2192, 0x219b, + 0x2194, 0x21ae, 0x21d0, 0x21cd, 0x21d2, 0x21cf, 0x21d4, 0x21ce, + 0x2203, 0x2204, 0x2208, 0x2209, 0x220b, 0x220c, 0x2223, 0x2224, + 0x2225, 0x2226, 0x223c, 0x2241, 0x2243, 0x2244, 0x2245, 0x2247, + 0x2248, 0x2249, 0x224d, 0x226d, 0x2261, 0x2262, 0x2264, 0x2270, + 0x2265, 0x2271, 0x2272, 0x2274, 0x2273, 0x2275, 0x2276, 0x2278, + 0x2277, 0x2279, 0x227a, 0x2280, 0x227b, 0x2281, 0x227c, 0x22e0, + 0x227d, 0x22e1, 0x2282, 0x2284, 0x2283, 0x2285, 0x2286, 0x2288, + 0x2287, 0x2289, 0x2291, 0x22e2, 0x2292, 0x22e3, 0x22a2, 0x22ac, + 0x22a8, 0x22ad, 0x22a9, 0x22ae, 0x22ab, 0x22af, 0x22b2, 0x22ea, + 0x22b3, 0x22eb, 0x22b4, 0x22ec, 0x22b5, 0x22ed, 0x1d, 0xa8, + 0x1fc1, 0x3b1, 0x1fb6, 0x3b7, 0x1fc6, 0x3b9, 0x1fd6, 0x3c5, + 0x1fe6, 0x3c9, 0x1ff6, 0x3ca, 0x1fd7, 0x3cb, 0x1fe7, 0x1f00, + 0x1f06, 0x1f01, 0x1f07, 0x1f08, 0x1f0e, 0x1f09, 0x1f0f, 0x1f20, + 0x1f26, 0x1f21, 0x1f27, 0x1f28, 0x1f2e, 0x1f29, 0x1f2f, 0x1f30, + 0x1f36, 0x1f31, 0x1f37, 0x1f38, 0x1f3e, 0x1f39, 0x1f3f, 0x1f50, + 0x1f56, 0x1f51, 0x1f57, 0x1f59, 0x1f5f, 0x1f60, 0x1f66, 0x1f61, + 0x1f67, 0x1f68, 0x1f6e, 0x1f69, 0x1f6f, 0x1fbf, 0x1fcf, 0x1ffe, + 0x1fdf, 0x3f, 0x391, 0x1fbc, 0x397, 0x1fcc, 0x3a9, 0x1ffc, + 0x3ac, 0x1fb4, 0x3ae, 0x1fc4, 0x3b1, 0x1fb3, 0x3b7, 0x1fc3, + 0x3c9, 0x1ff3, 0x3ce, 0x1ff4, 0x1f00, 0x1f80, 0x1f01, 0x1f81, + 0x1f02, 0x1f82, 0x1f03, 0x1f83, 0x1f04, 0x1f84, 0x1f05, 0x1f85, + 0x1f06, 0x1f86, 0x1f07, 0x1f87, 0x1f08, 0x1f88, 0x1f09, 0x1f89, + 0x1f0a, 0x1f8a, 0x1f0b, 0x1f8b, 0x1f0c, 0x1f8c, 0x1f0d, 0x1f8d, + 0x1f0e, 0x1f8e, 0x1f0f, 0x1f8f, 0x1f20, 0x1f90, 0x1f21, 0x1f91, + 0x1f22, 0x1f92, 0x1f23, 0x1f93, 0x1f24, 0x1f94, 0x1f25, 0x1f95, + 0x1f26, 0x1f96, 0x1f27, 0x1f97, 0x1f28, 0x1f98, 0x1f29, 0x1f99, + 0x1f2a, 0x1f9a, 0x1f2b, 0x1f9b, 0x1f2c, 0x1f9c, 0x1f2d, 0x1f9d, + 0x1f2e, 0x1f9e, 0x1f2f, 0x1f9f, 0x1f60, 0x1fa0, 0x1f61, 0x1fa1, + 0x1f62, 0x1fa2, 0x1f63, 0x1fa3, 0x1f64, 0x1fa4, 0x1f65, 0x1fa5, + 0x1f66, 0x1fa6, 0x1f67, 0x1fa7, 0x1f68, 0x1fa8, 0x1f69, 0x1fa9, + 0x1f6a, 0x1faa, 0x1f6b, 0x1fab, 0x1f6c, 0x1fac, 0x1f6d, 0x1fad, + 0x1f6e, 0x1fae, 0x1f6f, 0x1faf, 0x1f70, 0x1fb2, 0x1f74, 0x1fc2, + 0x1f7c, 0x1ff2, 0x1fb6, 0x1fb7, 0x1fc6, 0x1fc7, 0x1ff6, 0x1ff7, + 0x1, 0x627, 0x622, 0x6, 0x627, 0x623, 0x648, 0x624, + 0x64a, 0x626, 0x6c1, 0x6c2, 0x6d2, 0x6d3, 0x6d5, 0x6c0, + 0x1, 0x627, 0x625, 0x3, 0x928, 0x929, 0x930, 0x931, + 0x933, 0x934, 0x1, 0x9c7, 0x9cb, 0x1, 0x9c7, 0x9cc, + 0x1, 0xb47, 0xb4b, 0x1, 0xb47, 0xb48, 0x1, 0xb47, + 0xb4c, 0x2, 0xbc6, 0xbca, 0xbc7, 0xbcb, 0x2, 0xb92, + 0xb94, 0xbc6, 0xbcc, 0x1, 0xc46, 0xc48, 0x1, 0xcc6, + 0xcca, 0x3, 0xcbf, 0xcc0, 0xcc6, 0xcc7, 0xcca, 0xccb, + 0x1, 0xcc6, 0xcc8, 0x2, 0xd46, 0xd4a, 0xd47, 0xd4b, + 0x1, 0xd46, 0xd4c, 0x2, 0xdd9, 0xdda, 0xddc, 0xddd, + 0x1, 0xdd9, 0xddc, 0x1, 0xdd9, 0xdde, 0x1, 0x1025, + 0x1026, 0xb, 0x1b05, 0x1b06, 0x1b07, 0x1b08, 0x1b09, 0x1b0a, + 0x1b0b, 0x1b0c, 0x1b0d, 0x1b0e, 0x1b11, 0x1b12, 0x1b3a, 0x1b3b, + 0x1b3c, 0x1b3d, 0x1b3e, 0x1b40, 0x1b3f, 0x1b41, 0x1b42, 0x1b43, + 0x30, 0x3046, 0x3094, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, + 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, + 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, + 0x3060, 0x3061, 0x3062, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306f, 0x3070, 0x3072, 0x3073, 0x3075, 0x3076, 0x3078, + 0x3079, 0x307b, 0x307c, 0x309d, 0x309e, 0x30a6, 0x30f4, 0x30ab, + 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3, + 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb, + 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c4, + 0x30c5, 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30cf, 0x30d0, 0x30d2, + 0x30d3, 0x30d5, 0x30d6, 0x30d8, 0x30d9, 0x30db, 0x30dc, 0x30ef, + 0x30f7, 0x30f0, 0x30f8, 0x30f1, 0x30f9, 0x30f2, 0x30fa, 0x30fd, + 0x30fe, 0xa, 0x306f, 0x3071, 0x3072, 0x3074, 0x3075, 0x3077, + 0x3078, 0x307a, 0x307b, 0x307d, 0x30cf, 0x30d1, 0x30d2, 0x30d4, + 0x30d5, 0x30d7, 0x30d8, 0x30da, 0x30db, 0x30dd, }; struct NormalizationCorrection { diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h index ce426e7..625dee7 100644 --- a/src/corelib/tools/qunicodetables_p.h +++ b/src/corelib/tools/qunicodetables_p.h @@ -81,8 +81,8 @@ namespace QUnicodeTables { ushort wordBreak : 8; ushort sentenceBreak : 8; }; - Q_CORE_EXPORT const Properties* QT_FASTCALL properties(uint ucs4); - Q_CORE_EXPORT const Properties* QT_FASTCALL properties(ushort ucs2); + Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4); + Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2); // See http://www.unicode.org/reports/tr24/tr24-5.html -- cgit v0.12 From 9da6a1d34f1d06879ba9d72e9ad15bf261aea8c9 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 1 Jul 2009 13:29:58 +0200 Subject: Doc: correcting typo Correcting typos Task-number: 257225 --- src/gui/itemviews/qitemdelegate.cpp | 2 +- src/gui/itemviews/qstyleditemdelegate.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 264fa37..2dd5540 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -574,7 +574,7 @@ void QItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) con } /*! - Gets data drom the \a editor widget and stores it in the specified + Gets data from the \a editor widget and stores it in the specified \a model at the item \a index. The default implementation gets the value to be stored in the data diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index e528e58..edca724 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -508,7 +508,7 @@ void QStyledItemDelegate::setEditorData(QWidget *editor, const QModelIndex &inde } /*! - Gets data drom the \a editor widget and stores it in the specified + Gets data from the \a editor widget and stores it in the specified \a model at the item \a index. The default implementation gets the value to be stored in the data -- cgit v0.12 From f3a6f4dc01f9d6c5c167a94ae49acff35ccc0c11 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Jul 2009 13:53:28 +0200 Subject: Fixed the build on Windows after regenerating the unicode tables. Reviewed-by: trustme --- src/corelib/tools/qunicodetables.cpp | 4 ++-- util/unicode/main.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp index 0387181..c103016 100644 --- a/src/corelib/tools/qunicodetables.cpp +++ b/src/corelib/tools/qunicodetables.cpp @@ -4336,13 +4336,13 @@ static inline const QUnicodeTables::Properties *qGetProp(ushort ucs2) return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(uint ucs4) +Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(uint ucs4) { int index = GET_PROP_INDEX(ucs4); return uc_properties + index; } -Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(ushort ucs2) +Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(ushort ucs2) { int index = GET_PROP_INDEX_UCS2(ucs2); return uc_properties + index; diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index 3c32e6d..c24486b 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -2052,13 +2052,13 @@ static QByteArray createPropertyInfo() " return uc_properties + index;\n" "}\n" "\n" - "Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(uint ucs4)\n" + "Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(uint ucs4)\n" "{\n" " int index = GET_PROP_INDEX(ucs4);\n" " return uc_properties + index;\n" "}\n" "\n" - "Q_CORE_EXPORT const QUnicodeTables::Properties *QUnicodeTables::properties(ushort ucs2)\n" + "Q_CORE_EXPORT const QUnicodeTables::Properties * QT_FASTCALL QUnicodeTables::properties(ushort ucs2)\n" "{\n" " int index = GET_PROP_INDEX_UCS2(ucs2);\n" " return uc_properties + index;\n" -- cgit v0.12 From fe889557bcf3f4744205ba65b330276b5dc41c61 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 1 Jul 2009 13:57:46 +0200 Subject: Doc: clearifying docs - QProgressDialog Clearifying details on a warning about a function call (setValue()) Task-number: qtp 4.5Workarea --- src/gui/dialogs/qprogressdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/qprogressdialog.cpp b/src/gui/dialogs/qprogressdialog.cpp index 959cdbc..580794b 100644 --- a/src/gui/dialogs/qprogressdialog.cpp +++ b/src/gui/dialogs/qprogressdialog.cpp @@ -626,7 +626,7 @@ int QProgressDialog::value() const \warning If the progress dialog is modal (see QProgressDialog::QProgressDialog()), - this function calls QApplication::processEvents(), so take care that + setValue() calls QApplication::processEvents(), so take care that this does not cause undesirable re-entrancy in your code. For example, don't use a QProgressDialog inside a paintEvent()! -- cgit v0.12 From 145e17f6cc405dd935451f0151b1a8a451c78f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 1 Jul 2009 14:01:54 +0200 Subject: Compiler warning. --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9de6598..8fdf651 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -297,8 +297,8 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() allItemsIgnoreHoverEvents(true), allItemsUseDefaultCursor(true), painterStateProtection(true), - style(0), sortCacheEnabled(false), + style(0), allItemsIgnoreTouchEvents(true) { } -- cgit v0.12 From f6872e6b7a18b946c7428916c7096b82560a9cc6 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Jul 2009 14:18:57 +0200 Subject: Do not start Assistant without at least an empty page. Noticed while looking into task 256903, since in case there are no recent shown pages,we would start Assistant only showning the search. Task-number: 256903 Reviewed-by: kh --- tools/assistant/tools/assistant/centralwidget.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 385f0bb..64c2a80 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -427,8 +427,11 @@ void CentralWidget::setLastShownPages() QString::SkipEmptyParts); const int pageCount = lastShownPageList.count(); - if (pageCount == 0 && usesDefaultCollection) { - setSource(QUrl(QLatin1String("help"))); + if (pageCount == 0) { + if (usesDefaultCollection) + setSource(QUrl(QLatin1String("help"))); + else + setSource(QUrl(QLatin1String("about:blank"))); return; } -- cgit v0.12 From 1813a6d2bc0ba611cecd2d74dea75cd4644a9f95 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Jul 2009 14:49:10 +0200 Subject: Sync with QtCreator. --- tools/assistant/tools/assistant/centralwidget.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 64c2a80..a384544 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -286,6 +286,10 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) CentralWidget::~CentralWidget() { +#ifndef QT_NO_PRINTER + delete printer; +#endif + QHelpEngineCore engine(collectionFile, 0); if (!engine.setupData()) return; @@ -357,10 +361,10 @@ void CentralWidget::findNext() void CentralWidget::nextPage() { - if(tabWidget->currentIndex() < tabWidget->count() -1) - tabWidget->setCurrentIndex(tabWidget->currentIndex() +1); - else - tabWidget->setCurrentIndex(0); + int index = tabWidget->currentIndex() + 1; + if (index >= tabWidget->count()) + index = 0; + tabWidget->setCurrentIndex(index); } void CentralWidget::resetZoom() @@ -376,10 +380,9 @@ void CentralWidget::resetZoom() void CentralWidget::previousPage() { int index = tabWidget->currentIndex() -1; - if(index >= 0) - tabWidget->setCurrentIndex(index); - else - tabWidget->setCurrentIndex(tabWidget->count() -1); + if (index < 0) + index = tabWidget->count() -1; + tabWidget->setCurrentIndex(index); } void CentralWidget::findPrevious() @@ -400,7 +403,8 @@ void CentralWidget::closeTab() void CentralWidget::setSource(const QUrl &url) { HelpViewer *viewer = currentHelpViewer(); - HelpViewer *lastViewer = qobject_cast(tabWidget->widget(lastTabPage)); + HelpViewer *lastViewer = + qobject_cast(tabWidget->widget(lastTabPage)); if (!viewer && !lastViewer) { viewer = new HelpViewer(helpEngine, this); -- cgit v0.12 From 7c6ae7d93b2fe7fb3054798ad77b411608801388 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Jul 2009 15:05:49 +0200 Subject: Sync with QtCreator. Reviewed-by: kh --- .../assistant/tools/assistant/bookmarkmanager.cpp | 54 +++++++++++++++++++--- tools/assistant/tools/assistant/bookmarkmanager.h | 8 ++++ tools/assistant/tools/assistant/mainwindow.cpp | 37 +++++++++++++-- tools/assistant/tools/assistant/mainwindow.h | 5 ++ 4 files changed, 94 insertions(+), 10 deletions(-) diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp index 3bca573..250262e 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.cpp +++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp @@ -347,7 +347,7 @@ void BookmarkWidget::filterChanged() filterBookmarkModel->setFilterRegExp(regExp); - QModelIndex index = treeView->indexAt(QPoint(1, 1)); + const QModelIndex &index = treeView->indexAt(QPoint(1, 1)); if (index.isValid()) treeView->setCurrentIndex(index); @@ -445,9 +445,10 @@ void BookmarkWidget::setup(bool showButtons) treeView = new TreeView(this); vlayout->addWidget(treeView); - QString system = QLatin1String("win"); #ifdef Q_OS_MAC - system = QLatin1String("mac"); +# define SYSTEM "mac" +#else +# define SYSTEM "win" #endif if (showButtons) { @@ -458,8 +459,8 @@ void BookmarkWidget::setup(bool showButtons) addButton = new QToolButton(this); addButton->setText(tr("Add")); - addButton->setIcon(QIcon(QString::fromUtf8( - ":/trolltech/assistant/images/%1/addtab.png").arg(system))); + addButton->setIcon(QIcon(QLatin1String(":/trolltech/assistant/images/" + SYSTEM "/addtab.png"))); addButton->setAutoRaise(true); addButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hlayout->addWidget(addButton); @@ -467,8 +468,8 @@ void BookmarkWidget::setup(bool showButtons) removeButton = new QToolButton(this); removeButton->setText(tr("Remove")); - removeButton->setIcon(QIcon(QString::fromUtf8( - ":/trolltech/assistant/images/%1/closetab.png").arg(system))); + removeButton->setIcon(QIcon(QLatin1String(":/trolltech/assistant/images/" + SYSTEM "/closetab.png"))); removeButton->setAutoRaise(true); removeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hlayout->addWidget(removeButton); @@ -626,6 +627,10 @@ BookmarkManager::BookmarkManager(QHelpEngineCore *_helpEngine) connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(itemChanged(QStandardItem*))); + connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this, + SIGNAL(bookmarksChanged())); + connect(treeModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SIGNAL(bookmarksChanged())); } BookmarkManager::~BookmarkManager() @@ -736,6 +741,41 @@ void BookmarkManager::addNewBookmark(const QModelIndex &index, else treeModel->appendRow(item); listModel->appendRow(item->clone()); + emit bookmarksChanged(); +} + +void BookmarkManager::fillBookmarkMenu(QMenu *menu) +{ + if (!menu || !treeModel) + return; + + map.clear(); + fillBookmarkMenu(menu, treeModel->invisibleRootItem()); +} + +void BookmarkManager::fillBookmarkMenu(QMenu *menu, QStandardItem *root) +{ + for (int i = 0; i < root->rowCount(); ++i) { + QStandardItem *item = root->child(i); + if (item && item->data(Qt::UserRole + 10) + .toString() == QLatin1String("Folder")) { + QMenu* newMenu = menu->addMenu(folderIcon, item->text()); + if (item->rowCount() > 0) + fillBookmarkMenu(newMenu, item); + } else { + map.insert(menu->addAction(item->text()), item->index()); + } + } +} + +QUrl BookmarkManager::urlForAction(QAction* action) const +{ + if (map.contains(action)) { + const QModelIndex &index = map.value(action); + if (QStandardItem* item = treeModel->itemFromIndex(index)) + return QUrl(item->data(Qt::UserRole + 10).toString()); + } + return QUrl(); } void BookmarkManager::itemChanged(QStandardItem *item) diff --git a/tools/assistant/tools/assistant/bookmarkmanager.h b/tools/assistant/tools/assistant/bookmarkmanager.h index bf7af41..33db5b6 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.h +++ b/tools/assistant/tools/assistant/bookmarkmanager.h @@ -183,6 +183,12 @@ public: const QString &url); void setupBookmarkModels(); + void fillBookmarkMenu(QMenu *menu); + QUrl urlForAction(QAction* action) const; + +signals: + void bookmarksChanged(); + private slots: void itemChanged(QStandardItem *item); @@ -191,6 +197,7 @@ private: void removeBookmarkFolderItems(QStandardItem *item); void readBookmarksRecursive(const QStandardItem *item, QDataStream &stream, const qint32 depth) const; + void fillBookmarkMenu(QMenu *menu, QStandardItem *root); private: QString oldText; @@ -200,6 +207,7 @@ private: BookmarkModel *listModel; QStandardItem *renameItem; QHelpEngineCore *helpEngine; + QMap map; }; QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 5b3e731..0340297 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -137,7 +137,14 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent) if (initHelpDB()) { setupFilterToolbar(); setupAddressToolbar(); + m_bookmarkManager->setupBookmarkModels(); + m_bookmarkMenu->addSeparator(); + m_bookmarkManager->fillBookmarkMenu(m_bookmarkMenu); + connect(m_bookmarkMenu, SIGNAL(triggered(QAction*)), this, + SLOT(showBookmark(QAction*))); + connect(m_bookmarkManager, SIGNAL(bookmarksChanged()), this, + SLOT(updateBookmarkMenu())); setWindowTitle(m_helpEngine->customValue(QLatin1String("WindowTitle"), defWindowTitle).toString()); @@ -370,6 +377,29 @@ void MainWindow::checkInitState() } } +void MainWindow::updateBookmarkMenu() +{ + if (m_bookmarkManager) { + m_bookmarkMenu->removeAction(m_bookmarkMenuAction); + + m_bookmarkMenu->clear(); + + m_bookmarkMenu->addAction(m_bookmarkMenuAction); + m_bookmarkMenu->addSeparator(); + + m_bookmarkManager->fillBookmarkMenu(m_bookmarkMenu); + } +} + +void MainWindow::showBookmark(QAction *action) +{ + if (m_bookmarkManager) { + const QUrl &url = m_bookmarkManager->urlForAction(action); + if (url.isValid()) + m_centralWidget->setSource(url); + } +} + void MainWindow::insertLastPages() { if (m_cmdLine->url().isValid()) @@ -495,9 +525,10 @@ void MainWindow::setupActions() tmp->setShortcuts(QList() << QKeySequence(tr("Ctrl+Alt+Left")) << QKeySequence(Qt::CTRL + Qt::Key_PageUp)); - menu = menuBar()->addMenu(tr("&Bookmarks")); - tmp = menu->addAction(tr("Add Bookmark..."), this, SLOT(addBookmark())); - tmp->setShortcut(tr("CTRL+D")); + m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks")); + m_bookmarkMenuAction = m_bookmarkMenu->addAction(tr("Add Bookmark..."), + this, SLOT(addBookmark())); + m_bookmarkMenuAction->setShortcut(tr("CTRL+D")); menu = menuBar()->addMenu(tr("&Help")); m_aboutAction = menu->addAction(tr("About..."), this, SLOT(showAboutDialog())); diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h index 9ab3185..f7df724 100644 --- a/tools/assistant/tools/assistant/mainwindow.h +++ b/tools/assistant/tools/assistant/mainwindow.h @@ -119,6 +119,9 @@ private slots: void qtDocumentationInstalled(bool newDocsInstalled); void checkInitState(); + void updateBookmarkMenu(); + void showBookmark(QAction *action); + private: bool initHelpDB(); void setupActions(); @@ -157,6 +160,8 @@ private: QMenu *m_viewMenu; QMenu *m_toolBarMenu; + QMenu *m_bookmarkMenu; + QAction *m_bookmarkMenuAction; CmdLineParser *m_cmdLine; -- cgit v0.12 From f4a95e6d6e4c046ac4857cbd54f9488d3b67ce5a Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 1 Jul 2009 17:09:17 +0200 Subject: Fix a regression with extended style option items. We basically passed an unitialized transform to construct the styleoptions for items that use the useExtendedStyleOption flag. We had an auto-test to cover that but for some reason view.show() was removed by me so the auto-test did nothing. oops. Reviewed-by:bnilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 8 ++++---- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8fdf651..8a032f4 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4312,7 +4312,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (drawItem) { Q_ASSERT(!itemIsFullyTransparent); Q_ASSERT(itemHasContents); - item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion + ENSURE_TRANSFORM_PTR + item->d_ptr->initStyleOption(&styleOptionTmp, *transformPtr, exposedRegion ? *exposedRegion : QRegion(), exposedRegion == 0); const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape; @@ -4320,10 +4321,9 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (savePainter) painter->save(); - if (!itemHasChildren || !itemClipsChildrenToShape) { - ENSURE_TRANSFORM_PTR + if (!itemHasChildren || !itemClipsChildrenToShape) painter->setWorldTransform(*transformPtr); - } + if (itemClipsToShape) painter->setClipPath(item->shape(), Qt::IntersectClip); painter->setOpacity(opacity); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 7552f18..3f7a50b 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6837,9 +6837,11 @@ public: //Doesn't use the extended style option so the exposed rect is the boundingRect if (!(flags() & QGraphicsItem::ItemUsesExtendedStyleOption)) { QCOMPARE(option->exposedRect, boundingRect()); + QCOMPARE(option->matrix, QMatrix()); } else { QVERIFY(option->exposedRect != QRect()); QVERIFY(option->exposedRect != boundingRect()); + QCOMPARE(option->matrix, sceneTransform().toAffine()); } } QGraphicsRectItem::paint(painter, option, widget); @@ -6861,6 +6863,8 @@ void tst_QGraphicsItem::itemUsesExtendedStyleOption() scene.addItem(rect); rect->setPos(200, 200); QGraphicsView view(&scene); + rect->startTrack = false; + view.show(); QTest::qWait(500); rect->startTrack = true; rect->update(10, 10, 10, 10); -- cgit v0.12 From 2b9294a2b47c4a193ef83be60a07a3e61b8531b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 1 Jul 2009 17:30:46 +0200 Subject: Fixes broken BSP lookup in QGraphicsSceneBspTreeIndex. The chip demo was unbelievable slow, so I investigated and found out the bsp always returned almost all items in the tree (40 000 in this particular case). It did so because the tree was initialized with an empty sceneRect. The sceneRect was empty due to a lacking signal-slot connection, resulting in QGraphicsSceneBspTreeIndex::updateSceneRect never being invoked. Auto-test included. --- src/gui/graphicsview/qgraphicssceneindex.cpp | 17 ++++++++++++----- src/gui/graphicsview/qgraphicssceneindex_p.h | 3 ++- .../qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 13 +++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 2f2f05e..b317e8e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -303,24 +303,31 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe } } +void QGraphicsSceneIndexPrivate::init() +{ + if (!scene) + return; + + QObject::connect(scene, SIGNAL(sceneRectChanged(const QRectF&)), + q_func(), SLOT(updateSceneRect(const QRectF&))); +} + /*! Constructs an abstract scene index for a given \a scene. */ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) : QObject(*new QGraphicsSceneIndexPrivate(scene), scene) { - if (scene) { - connect(scene, SIGNAL(sceneRectChanged(const QRectF&)), - this, SLOT(updateSceneRect(const QRectF&))); - } + d_func()->init(); } /*! \internal */ -QGraphicsSceneIndex::QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene) +QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene) : QObject(dd, scene) { + d_func()->init(); } /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 122d7ae..aabfa79 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -114,7 +114,7 @@ protected: virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); - QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); + QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene); friend class QGraphicsScene; friend class QGraphicsScenePrivate; @@ -133,6 +133,7 @@ public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); ~QGraphicsSceneIndexPrivate(); + void init(); static bool itemCollidesWithPath(const QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode); void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index ac21e20..9d0675d 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -64,6 +64,7 @@ private slots: void overlappedItems(); void movingItems_data(); void movingItems(); + void connectedToSceneRectChanged(); private: void common_data(); @@ -214,6 +215,18 @@ void tst_QGraphicsSceneIndex::movingItems() QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 11); } +void tst_QGraphicsSceneIndex::connectedToSceneRectChanged() +{ + + class MyScene : public QGraphicsScene + { public: using QGraphicsScene::receivers; }; + + MyScene scene; // Uses QGraphicsSceneBspTreeIndex by default. + QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1); + + scene.setItemIndexMethod(QGraphicsScene::NoIndex); // QGraphicsSceneLinearIndex + QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1); +} QTEST_MAIN(tst_QGraphicsSceneIndex) #include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From 3e303b195a79d555b907a6badbe4df5d4b8686b4 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 1 Jul 2009 16:07:01 -0700 Subject: Code cleanup Move the code from QDirectFBPaintEnginePrivate::(end|begin) into QDirectFBPaintEngine::(end|begin) Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 84 ++++++++++------------ 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 40bec0e..bac9f09 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -244,9 +244,6 @@ public: inline void updateClip(); void systemStateChanged(); - void begin(QPaintDevice *device); - void end(); - static IDirectFBSurface *getSurface(const QImage &img, bool *release); #ifdef QT_DIRECTFB_IMAGECACHE @@ -299,7 +296,34 @@ QDirectFBPaintEngine::~QDirectFBPaintEngine() bool QDirectFBPaintEngine::begin(QPaintDevice *device) { Q_D(QDirectFBPaintEngine); - d->begin(device); + d->lastLockedHeight = -1; + if (device->devType() == QInternal::CustomRaster) { + d->dfbDevice = static_cast(device); + } else if (d->device->devType() == QInternal::Pixmap) { + QPixmapData *data = static_cast(device)->pixmapData(); + Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); + QDirectFBPixmapData *dfbPixmapData = static_cast(data); + d->dfbDevice = static_cast(dfbPixmapData); + } + + if (d->dfbDevice) + d->surface = d->dfbDevice->directFBSurface(); + + if (!d->surface) { + qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", + device->devType()); + } + d->lockedMemory = 0; + + d->surface->GetSize(d->surface, &d->fbWidth, &d->fbHeight); + + d->setTransform(QTransform()); + d->antialiased = false; + d->setOpacity(255); + d->setCompositionMode(state()->compositionMode()); + d->dirtyClip = true; + d->setPen(state()->pen); + const bool status = QRasterPaintEngine::begin(device); // XXX: QRasterPaintEngine::begin() resets the capabilities @@ -311,8 +335,14 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) bool QDirectFBPaintEngine::end() { Q_D(QDirectFBPaintEngine); - d->end(); - return QRasterPaintEngine::end(); + d->unlock(); + d->dfbDevice = 0; +#if (Q_DIRECTFB_VERSION >= 0x010000) + d->surface->ReleaseSource(d->surface); +#endif + d->surface->SetClip(d->surface, NULL); + d->surface = 0; + return true; } void QDirectFBPaintEngine::clipEnabledChanged() @@ -873,48 +903,6 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) } } -void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) -{ - lastLockedHeight = -1; - if (device->devType() == QInternal::CustomRaster) - dfbDevice = static_cast(device); - else if (device->devType() == QInternal::Pixmap) { - QPixmapData *data = static_cast(device)->pixmapData(); - Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); - QDirectFBPixmapData* dfbPixmapData = static_cast(data); - dfbDevice = static_cast(dfbPixmapData); - } - - if (dfbDevice) - surface = dfbDevice->directFBSurface(); - - if (!surface) { - qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", - device->devType()); - } - lockedMemory = 0; - - surface->GetSize(surface, &fbWidth, &fbHeight); - - setTransform(QTransform()); - antialiased = false; - setOpacity(255); - setCompositionMode(q->state()->compositionMode()); - dirtyClip = true; - setPen(q->state()->pen); -} - -void QDirectFBPaintEnginePrivate::end() -{ - lockedMemory = 0; - dfbDevice = 0; -#if (Q_DIRECTFB_VERSION >= 0x010000) - surface->ReleaseSource(surface); -#endif - surface->SetClip(surface, NULL); - surface = 0; -} - void QDirectFBPaintEnginePrivate::setPen(const QPen &p) { pen = p; -- cgit v0.12 From 765a6676e04b19a9af298096f9d4f0a6e571ccbd Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 1 Jul 2009 16:11:50 -0700 Subject: Make sure we check the right device Also. Make sure to call QRasterPaintEngine::end() Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index bac9f09..e4ce230 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -299,7 +299,7 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) d->lastLockedHeight = -1; if (device->devType() == QInternal::CustomRaster) { d->dfbDevice = static_cast(device); - } else if (d->device->devType() == QInternal::Pixmap) { + } else if (device->devType() == QInternal::Pixmap) { QPixmapData *data = static_cast(device)->pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbPixmapData = static_cast(data); @@ -342,7 +342,7 @@ bool QDirectFBPaintEngine::end() #endif d->surface->SetClip(d->surface, NULL); d->surface = 0; - return true; + return QRasterPaintEngine::end(); } void QDirectFBPaintEngine::clipEnabledChanged() -- cgit v0.12 From 35a4141f01ab9db910c85ccb89e76058aa3ac5cf Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 1 Jul 2009 17:58:49 -0700 Subject: We still need to Flip in NO_WM mode This ifdef was simply in the wrong place. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index 71e1fde..86ee62c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -364,6 +364,7 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, if (winOpacity != opacity) dfbWindow->SetOpacity(dfbWindow, winOpacity); } +#endif if (!(flipFlags & DSFLIP_BLIT)) { dfbSurface->Flip(dfbSurface, 0, flipFlags); } else { @@ -385,7 +386,6 @@ void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); } } -#endif #ifdef QT_DIRECTFB_TIMING enum { Secs = 3 }; ++frames; -- cgit v0.12 From a24b8166631a9b1d80f8205cd0e450824166a25d Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 2 Jul 2009 14:59:14 +1000 Subject: Get more autotests passing/fixed up. --- src/sql/drivers/oci/qsql_oci.cpp | 7 +++++-- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 4 ++++ tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index bbbbc22..8d34dd8 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -1588,9 +1588,12 @@ void QOCICols::getValues(QVector &v, int index) } else if ((d->precisionPolicy == QSql::LowPrecisionInt64) && (fld.typ == QVariant::LongLong)) { qint64 qll = 0; - OCINumberToInt(d->err, reinterpret_cast(fld.data), sizeof(qint64), + int r = OCINumberToInt(d->err, reinterpret_cast(fld.data), sizeof(qint64), OCI_NUMBER_SIGNED, &qll); - v[index + i] = qll; + if(r == OCI_SUCCESS) + v[index + i] = qll; + else + v[index + i] = QVariant(); break; } else if ((d->precisionPolicy == QSql::LowPrecisionInt32) && (fld.typ == QVariant::Int)) { diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index a2f4a66..91533dd 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -132,6 +132,10 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db ) if ( !db.isValid() ) return; QSqlQuery q( db ); + if (tst_Databases::isSqlServer(db)) { + QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON")); + QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF")); + } // please never ever change this table; otherwise fix all tests ;) if ( tst_Databases::isMSAccess( db ) ) { QVERIFY_SQL(q, exec( "create table " + qTableName( "qtest" ) + " ( id int not null, t_varchar varchar(40) not null," diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index a286fb9..28a2191 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -298,6 +298,7 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db) q.exec("set table_type=innodb"); if (tst_Databases::isSqlServer(db)) { QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON")); + QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF")); } // please never ever change this table; otherwise fix all tests ;) @@ -1244,7 +1245,7 @@ void tst_QSqlDatabase::recordSQLServer() FieldDef("varchar(20)", QVariant::String, QString("Blah1")), FieldDef("bigint", QVariant::LongLong, 12345), FieldDef("int", QVariant::Int, 123456), - FieldDef("tinyint", QVariant::Int, 255), + FieldDef("tinyint", QVariant::UInt, 255), #ifdef QT3_SUPPORT FieldDef("image", QVariant::ByteArray, Q3CString("Blah1")), #endif @@ -1359,11 +1360,13 @@ void tst_QSqlDatabase::bigIntField() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + QString drvName = db.driverName(); QSqlQuery q(db); q.setForwardOnly(true); + if (drvName.startsWith("QOCI")) + q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); - QString drvName = db.driverName(); if (drvName.startsWith("QMYSQL")) { QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + " (id int, t_s64bit bigint, t_u64bit bigint unsigned)")); } else if (drvName.startsWith("QPSQL") @@ -1372,6 +1375,8 @@ void tst_QSqlDatabase::bigIntField() QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + "(id int, t_s64bit bigint, t_u64bit bigint)")); } else if (drvName.startsWith("QOCI")) { QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + " (id int, t_s64bit int, t_u64bit int)")); + //} else if (drvName.startsWith("QIBASE")) { + // QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bigint") + " (id int, t_s64bit int64, t_u64bit int64)")); } else { QSKIP("no 64 bit integer support", SkipAll); } @@ -1401,10 +1406,15 @@ void tst_QSqlDatabase::bigIntField() } QVERIFY(q.exec("select * from " + qTableName("qtest_bigint") + " order by id")); QVERIFY(q.next()); + QCOMPARE(q.value(1).toDouble(), (double)ll); QCOMPARE(q.value(1).toLongLong(), ll); + if(drvName.startsWith("QOCI")) + QEXPECT_FAIL("", "Oracle driver lacks support for unsigned int64 types", Continue); QCOMPARE(q.value(2).toULongLong(), ull); QVERIFY(q.next()); QCOMPARE(q.value(1).toLongLong(), -ll); + if(drvName.startsWith("QOCI")) + QEXPECT_FAIL("", "Oracle driver lacks support for unsigned int64 types", Continue); QCOMPARE(q.value(2).toULongLong(), ull); } -- cgit v0.12 From 18055b3c3fe50337ee1af819839694674bdfb3ff Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 2 Jul 2009 15:00:03 +1000 Subject: Tinyint is unsigned, force it to such. Tinyint only supports 0-255, so mark it as unsigned despite sign flag, which have the time is inverted/wrong. --- src/sql/drivers/odbc/qsql_odbc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index e18a9eb..4f358ec 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -252,9 +252,11 @@ static QVariant::Type qDecodeODBCType(SQLSMALLINT sqltype, const T* p, bool isSi case SQL_SMALLINT: case SQL_INTEGER: case SQL_BIT: - case SQL_TINYINT: type = isSigned ? QVariant::Int : QVariant::UInt; break; + case SQL_TINYINT: + type = QVariant::UInt; + break; case SQL_BIGINT: type = isSigned ? QVariant::LongLong : QVariant::ULongLong; break; -- cgit v0.12 From cdfb2ed5096053314c0e23482609a1a491636ac1 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 10:16:20 +1000 Subject: Improve cetest error reporting. Reviewed-by: Michael Goddard --- .../qtestlib/wince/cetest/activesyncconnection.cpp | 6 ++-- tools/qtestlib/wince/cetest/remoteconnection.cpp | 32 ++++++++++++++++++++++ tools/qtestlib/wince/cetest/remoteconnection.h | 2 ++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index e8ca8f2..76e4a41 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -113,6 +113,8 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS CeCloseHandle(deviceHandle); return true; } + } else { + qWarning("Could not open %s: %s", qPrintable(localSource), qPrintable(file.errorString())); } return false; } @@ -120,7 +122,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS deleteFile(deviceDest); HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (deviceHandle == INVALID_HANDLE_VALUE) { - debugOutput(QString::fromLatin1(" Could not create target file"), 2); + qWarning("Could not create %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); return false; } @@ -144,7 +146,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS if (toWrite == 0) break; if (!CeWriteFile(deviceHandle, data.data() , toWrite, &written, NULL)) { - debugOutput(QString::fromLatin1(" Could not write File"), 2); + qWarning("Could not write to %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); return false; } currentPos += written; diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp index 547b211..75788e2 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.cpp +++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp @@ -41,6 +41,38 @@ #include "remoteconnection.h" +QByteArray strwinerror(DWORD errorcode) +{ + QByteArray out(512, 0); + + DWORD ok = FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM, + 0, + errorcode, + 0, + out.data(), + out.size(), + 0 + ); + + if (!ok) { + qsnprintf(out.data(), out.size(), + "(error %d; additionally, error %d while looking up error string)", + (int)errorcode, (int)GetLastError()); + } + else { + out.resize(qstrlen(out.constData())); + if (out.endsWith("\r\n")) + out.chop(2); + + /* Append error number to error message for good measure */ + out.append(" ("); + out.append(QByteArray::number((int)errorcode)); + out.append(")"); + } + return out; +} + AbstractRemoteConnection::AbstractRemoteConnection() { } diff --git a/tools/qtestlib/wince/cetest/remoteconnection.h b/tools/qtestlib/wince/cetest/remoteconnection.h index 9c3e63d..f517009 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.h +++ b/tools/qtestlib/wince/cetest/remoteconnection.h @@ -79,4 +79,6 @@ public: virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0; }; +QByteArray strwinerror(DWORD); + #endif -- cgit v0.12 From fb1fa68ae8555deeaeaf6f193c678269c85ffc4d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 11:42:25 +1000 Subject: Let QtRemote report the error code to cetest when creating the test process fails. This gives some hint to the user in the case of problems like missing DLLs, as opposed to silent failure. Reviewed-by: Michael Goddard --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 14 ++++++++++++-- tools/qtestlib/wince/remotelib/commands.cpp | 10 ++++++++-- tools/qtestlib/wince/remotelib/commands.h | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 76e4a41..99fac2c 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -382,6 +382,7 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo BYTE* output; IRAPIStream *stream; int returned = 0; + DWORD error = 0; HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); if (S_OK != res) { if (S_OK != CeGetLastError()) @@ -416,9 +417,18 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { qWarning(" Could not access return value of process"); } - result = true; - } + if (S_OK != stream->Read(&error, sizeof(error), &written)) { + qWarning(" Could not access error code"); + } + if (error) { + qWarning() << "Error on target:" << strwinerror(error); + result = false; + } + else { + result = true; + } + } if (returnValue) *returnValue = returned; diff --git a/tools/qtestlib/wince/remotelib/commands.cpp b/tools/qtestlib/wince/remotelib/commands.cpp index 3aed2d6..f2176dd 100644 --- a/tools/qtestlib/wince/remotelib/commands.cpp +++ b/tools/qtestlib/wince/remotelib/commands.cpp @@ -56,6 +56,7 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) wchar_t* arguments = 0; int timeout = -1; int returnValue = -2; + DWORD error = 0; if (S_OK != stream->Read(&appLength, sizeof(appLength), &bytesRead)) CLEAN_FAIL(-2); @@ -74,11 +75,13 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) if (S_OK != stream->Read(&timeout, sizeof(timeout), &bytesRead)) CLEAN_FAIL(-2); - bool result = qRemoteExecute(appName, arguments, &returnValue, timeout); + bool result = qRemoteExecute(appName, arguments, &returnValue, &error, timeout); if (timeout != 0) { if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) CLEAN_FAIL(-4); + if (S_OK != stream->Write(&error, sizeof(error), &bytesRead)) + CLEAN_FAIL(-5); } delete appName; delete arguments; @@ -90,13 +93,16 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) } -bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, int timeout) +bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, DWORD* error, int timeout) { + *error = 0; + if (!program) return false; PROCESS_INFORMATION pid; if (!CreateProcess(program, arguments, NULL, NULL, false, 0, NULL, NULL, NULL, &pid)) { + *error = GetLastError(); wprintf(L"Could not launch: %s\n", program); return false; } diff --git a/tools/qtestlib/wince/remotelib/commands.h b/tools/qtestlib/wince/remotelib/commands.h index 9f0b2e3..5275f2c 100644 --- a/tools/qtestlib/wince/remotelib/commands.h +++ b/tools/qtestlib/wince/remotelib/commands.h @@ -45,7 +45,7 @@ extern "C" { int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*); - bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , int timeout = -1); + bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1); } #endif -- cgit v0.12 From f126b8cc5733d2cd37dd2aad9119e482b0d4a0e6 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 08:39:57 +0200 Subject: doc: Corrected several qdoc warnings. --- src/gui/graphicsview/qgraphicssceneevent.cpp | 35 ++++++++++++++-------------- src/gui/itemviews/qheaderview.h | 2 +- src/gui/kernel/qapplication.cpp | 2 +- src/qt3support/widgets/q3datetimeedit.cpp | 7 +++--- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 7906fb8..338f12a 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1875,12 +1875,12 @@ void QGraphicsSceneGestureEvent::setGestures(const QSet &gestures) } /*! - Sets the accept flag of the all gestures inside the event object, - the equivalent of calling \l{QEvent::accept()}{accept()} or - \l{QEvent::setAccepted()}{setAccepted(true)}. + Sets the accept flag of the all gestures for the event object. + This is the equivalent of calling \l{QEvent::accept()} {accept()} + or \l{QEvent::setAccepted()}{setAccepted(true)}. - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent + Setting the accept flag indicates that the event receiver wants + the gesture. Unwanted gestures might be propagated to the parent widget. */ void QGraphicsSceneGestureEvent::acceptAll() @@ -1893,13 +1893,14 @@ void QGraphicsSceneGestureEvent::acceptAll() } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. + Sets the accept flag of the gesture specified by \a type. This is + equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> + \l{QGesture::accept()}{accept()} + + Setting the accept flag indicates that the event receiver + wants the gesture. Unwanted gestures might be propagated to the parent + widget. */ void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) { @@ -1908,13 +1909,13 @@ void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. + Sets the accept flag of the gesture specified by \a type. This is + equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> + \l{QGesture::accept()}{accept()} + + Setting the accept flag indicates that the event receiver wants the + gesture. Unwanted gestures might be propagated to the parent widget. */ void QGraphicsSceneGestureEvent::accept(const QString &type) { diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h index f752ae2..bf92667 100644 --- a/src/gui/itemviews/qheaderview.h +++ b/src/gui/itemviews/qheaderview.h @@ -221,7 +221,7 @@ protected: bool isIndexHidden(const QModelIndex &index) const; QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers); - void setSelection(const QRect&, QItemSelectionModel::SelectionFlags); + void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags); QRegion visualRegionForSelection(const QItemSelection &selection) const; void initStyleOption(QStyleOptionHeader *option) const; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 15ddce8..60c69cc 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5096,7 +5096,7 @@ void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) The delay allows to postpone widget's input event handling until gestures framework can successfully recognize a gesture. - \sa QWidget::grabGesture + \sa QWidget::grabGesture() */ void QApplication::setEventDeliveryDelayForGestures(int delay) { diff --git a/src/qt3support/widgets/q3datetimeedit.cpp b/src/qt3support/widgets/q3datetimeedit.cpp index 4872642..9c2f289 100644 --- a/src/qt3support/widgets/q3datetimeedit.cpp +++ b/src/qt3support/widgets/q3datetimeedit.cpp @@ -2648,13 +2648,12 @@ Q3DateTimeEdit::~Q3DateTimeEdit() } -/*! +/*! \fn void Q3DateTimeEdit::resizeEvent(QResizeEvent *event) \reimp - Intercepts and handles resize events which have special meaning - for the Q3DateTimeEdit. + Intercepts and handles the resize \a event, which hase a + special meaning for the Q3DateTimeEdit. */ - void Q3DateTimeEdit::resizeEvent(QResizeEvent *) { int dw = de->sizeHint().width(); -- cgit v0.12 From 058c4f1cfd0536779ec99f3d89bdd90bf52ae20e Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 12:58:51 +1000 Subject: Let cetest deploy libraries other than for Qt to make it usable for running unit tests for projects outside of Qt. Let cetest look in the paths given with `-L' in LIBS, and to deploy libraries whose names don't start with `Qt'. This also fixes deployment of Qt autotests which link against phonon (the only Qt library whose name doesn't start with `Qt'). Reviewed-by: mauricek --- tools/qtestlib/wince/cetest/deployment.cpp | 34 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/tools/qtestlib/wince/cetest/deployment.cpp b/tools/qtestlib/wince/cetest/deployment.cpp index fec2735..68f0197 100644 --- a/tools/qtestlib/wince/cetest/deployment.cpp +++ b/tools/qtestlib/wince/cetest/deployment.cpp @@ -125,13 +125,37 @@ void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &depl if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) { QStringList libs = project->values("LIBS"); QStringList qtLibs; + QStringList libPaths; foreach (QString item, libs) { - if (item.startsWith("-lQt")) { - qtLibs += project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + item.mid(2) + QLatin1String("4.dll"); + + if (item.startsWith("-L")) { + // -L -> a directory containing DLLs + libPaths << item.mid(2); + continue; + } + + QStringList libCandidates; + + if (item.startsWith("-l")) { + // -l -> a library located within one of the standard library paths + QString lib = item.mid(2); + + // Check if it's a Qt library first, then check in all paths given with -L. + // Note Qt libraries get a `4' appended to them, others don't. + libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll"); + foreach (QString const& libPath, libPaths) { + libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll"); + } } else { - QFileInfo info(item); - if (info.exists() && info.isAbsolute() && info.fileName().startsWith(QLatin1String("Qt"))) - qtLibs += info.dir().absoluteFilePath(info.fileName().replace(QLatin1String(".lib"), QLatin1String(".dll"))); + libCandidates << item.replace(".lib",".dll"); + } + + foreach (QString const& file, libCandidates) { + QFileInfo info(file); + if (info.exists()) { + qtLibs += info.dir().absoluteFilePath(info.fileName()); + break; + } } } for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) { -- cgit v0.12 From b4028f5a2195a432059ff26c288d772af47bc14d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 17:03:31 +1000 Subject: Fixed cetest compile. --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 99fac2c..0f98619 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -422,7 +422,7 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo } if (error) { - qWarning() << "Error on target:" << strwinerror(error); + qWarning("Error on target: %s", strwinerror(error).constData()); result = false; } else { -- cgit v0.12 From 5fc3fe2e3f04475ac8c0e3287af6042bd8b67c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 2 Jul 2009 09:56:13 +0200 Subject: Dont include untransformable graphics items twice. This revertes d39a62720ba67a0fa6e4e37519d22f14c7b7404e (we had to do it with the old implementation, but the new one have untransformable items included in the indexed list. The only difference is that untransformable items are also in the untransformable list; otherwise in the bsp tree). Auto-test included. --- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 1 - .../tst_qgraphicssceneindex.cpp | 39 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index ff9a3da..c8d755e 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -606,7 +606,6 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co itemList << item; } } - itemList += d->untransformableItems; if (order != -1) { //We sort descending order d->sortItems(&itemList, order, d->sortCacheEnabled); diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 9d0675d..3ce5b16 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -65,6 +65,7 @@ private slots: void movingItems_data(); void movingItems(); void connectedToSceneRectChanged(); + void items(); private: void common_data(); @@ -228,5 +229,43 @@ void tst_QGraphicsSceneIndex::connectedToSceneRectChanged() QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1); } +void tst_QGraphicsSceneIndex::items() +{ + QGraphicsScene scene; + QGraphicsItem *item1 = scene.addRect(0, 0, 10, 10); + QGraphicsItem *item2 = scene.addRect(10, 10, 10, 10); + QCOMPARE(scene.items().size(), 2); + + // Move from unindexed items into bsp tree. + QTest::qWait(50); + QCOMPARE(scene.items().size(), 2); + + // Add untransformable item. + QGraphicsItem *item3 = new QGraphicsRectItem(QRectF(20, 20, 10, 10)); + item3->setFlag(QGraphicsItem::ItemIgnoresTransformations); + scene.addItem(item3); + QCOMPARE(scene.items().size(), 3); + + // Move from unindexed items into untransformable items. + QTest::qWait(50); + QCOMPARE(scene.items().size(), 3); + + // Move from untransformable items into unindexed items. + item3->setFlag(QGraphicsItem::ItemIgnoresTransformations, false); + QCOMPARE(scene.items().size(), 3); + QTest::qWait(50); + QCOMPARE(scene.items().size(), 3); + + // Make all items untransformable. + item1->setFlag(QGraphicsItem::ItemIgnoresTransformations); + item2->setParentItem(item1); + item3->setParentItem(item2); + QCOMPARE(scene.items().size(), 3); + + // Move from unindexed items into untransformable items. + QTest::qWait(50); + QCOMPARE(scene.items().size(), 3); +} + QTEST_MAIN(tst_QGraphicsSceneIndex) #include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From 69083610b09aaabbff5e8a177fac713a6a6d46ba Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 10:38:08 +0200 Subject: doc: Corrected several qdoc warnings. --- src/gui/graphicsview/qgraphicssceneevent.cpp | 5 ++++- src/gui/kernel/qevent.cpp | 4 ++++ src/gui/kernel/qgesturerecognizer.cpp | 7 ++++--- src/qt3support/sql/q3datatable.cpp | 2 -- tools/qdoc3/test/qt-cpp-ignore.qdocconf | 3 ++- tools/qdoc3/test/qt-inc.qdocconf | 3 ++- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 338f12a..27a2d7e 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1892,8 +1892,11 @@ void QGraphicsSceneGestureEvent::acceptAll() setAccepted(true); } -/*! +/*! \fn void QGraphicsSceneGestureEvent::accept() + Calls QEvent::accept(). +*/ +/*! Sets the accept flag of the gesture specified by \a type. This is equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> \l{QGesture::accept()}{accept()} diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index e40ad9d..a7a7f2d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3628,6 +3628,10 @@ QSet QGestureEvent::cancelledGestures() const return m_cancelledGestures; } +/*! \fn void QGestureEvent::accept() + Calls QEvent::accept(). +*/ + /*! Sets the accept flag of the all gestures inside the event object, the equivalent of calling \l{QEvent::accept()}{accept()} or diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index c330663..30889d7 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -97,8 +97,8 @@ QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); This is a pure virtual function that needs to be implemented in subclasses. - Parses input \a event and returns the result, which specifies if - the event sequence is a gesture or not. + Parses input \a event and returns the result, which specifies + whether the event sequence is a gesture or not. */ /*! \fn QGesture* QGestureRecognizer::getGesture() @@ -123,7 +123,8 @@ QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); The gesture recognizer might emit the stateChanged() signal when the gesture state changes asynchronously, i.e. without any event - being filtered through filterEvent(). + being filtered through filterEvent(). \a result specifies whether + the event sequence is a gesture or not. */ QGestureRecognizerPrivate::QGestureRecognizerPrivate() diff --git a/src/qt3support/sql/q3datatable.cpp b/src/qt3support/sql/q3datatable.cpp index 638aff8..d8d3c2b 100644 --- a/src/qt3support/sql/q3datatable.cpp +++ b/src/qt3support/sql/q3datatable.cpp @@ -1726,8 +1726,6 @@ void Q3DataTable::repaintCell( int row, int col ) the content coordinate system. If \a selected is true the cell has been selected and would normally be rendered differently than an unselected cell. - - \sa QSql::isNull() */ void Q3DataTable::paintCell( QPainter * p, int row, int col, const QRect & cr, diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf index 9a18abe..709e336 100644 --- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf +++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf @@ -68,7 +68,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \ QT_END_NAMESPACE \ QT_END_INCLUDE_NAMESPACE \ PHONON_EXPORT \ - Q_GADGET + Q_GADGET \ + QWEBKIT_EXPORT Cpp.ignoredirectives = Q_DECLARE_HANDLE \ Q_DECLARE_INTERFACE \ Q_DECLARE_METATYPE \ diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf index 01b07b3..542c7ca 100644 --- a/tools/qdoc3/test/qt-inc.qdocconf +++ b/tools/qdoc3/test/qt-inc.qdocconf @@ -100,7 +100,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \ Q_TYPENAME \ Q_XML_EXPORT \ QDBUS_EXPORT \ - Q_GADGET + Q_GADGET \ + QWEBKIT_EXPORT Cpp.ignoredirectives = Q_DECLARE_HANDLE \ Q_DECLARE_INTERFACE \ Q_DECLARE_METATYPE \ -- cgit v0.12 From 6d71de4283c05b1b42ef26fe4c23334ad34c8a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 2 Jul 2009 10:46:37 +0200 Subject: Kill dead BSP tree code in graphics view. --- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 41 ----------------------------- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 3 --- 2 files changed, 44 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index 5858eab..7d30749 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -154,17 +154,6 @@ QList QGraphicsSceneBspTree::items(const QRectF &rect) const return tmp; } -QList QGraphicsSceneBspTree::items(const QPointF &pos) const -{ - QList tmp; - findVisitor->foundItems = &tmp; - climbTree(findVisitor, pos); - // Reset discovery bits. - for (int i = 0; i < tmp.size(); ++i) - tmp.at(i)->d_ptr->itemDiscovered = 0; - return tmp; -} - int QGraphicsSceneBspTree::leafCount() const { return leafCnt; @@ -241,36 +230,6 @@ void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth, int index) } } -void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) const -{ - if (nodes.isEmpty()) - return; - - const Node &node = nodes.at(index); - const int childIndex = firstChildIndex(index); - - switch (node.type) { - case Node::Leaf: { - visitor->visit(const_cast*>(&leaves[node.leafIndex])); - break; - } - case Node::Vertical: - if (pos.x() < node.offset) { - climbTree(visitor, pos, childIndex); - } else { - climbTree(visitor, pos, childIndex + 1); - } - break; - case Node::Horizontal: - if (pos.y() < node.offset) { - climbTree(visitor, pos, childIndex); - } else { - climbTree(visitor, pos, childIndex + 1); - } - break; - } -} - void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) const { if (nodes.isEmpty()) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index 323cf04..24b926c 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -93,7 +93,6 @@ public: void removeItems(const QSet &items); QList items(const QRectF &rect) const; - QList items(const QPointF &pos) const; int leafCount() const; inline int firstChildIndex(int index) const @@ -106,11 +105,9 @@ public: private: void initialize(const QRectF &rect, int depth, int index); - void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0) const; void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0) const; void findItems(QList *foundItems, const QRectF &rect, int index); - void findItems(QList *foundItems, const QPointF &pos, int index); QRectF rectForIndex(int index) const; QVector nodes; -- cgit v0.12 From ad84039a4cb0d0057d2fc260e90f20cdd9761f46 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Thu, 2 Jul 2009 10:54:44 +0200 Subject: Doc: adding details to qmake docs Added documentation about the create_prl and link_prl to the CONFIG variable in the qmake manual Task-number: 165165 Rev-by: Geir Vattekar Rev-by: Volker Hilsheimer --- doc/src/qmake-manual.qdoc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index d840c71..afd881f 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -1019,6 +1019,25 @@ \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 24 + When linking a library, \c qmake relies on the underlying platform to know + what other libraries this library links against. However, if linking + statically, \c qmake will not get this information unless we use the following + \c CONFIG options: + + \table 95% + \header \o Option \o Description + \row \o create_prl \o This option enables \c qmake to track these + dependencies. When this option is enabled, \c qmake will create a file + ending in \c .prl which will save meta-information about the library + (see \l{LibDepend}{Library Dependencies} for more info). + \row \o link_prl \o When this is enabled, \c qmake will process all + libraries linked to by the application and find their meta-information + (see \l{LibDepend}{Library Dependencies} for more info). + \endtable + + Please note that \c create_prl is required when \i {building} a static library, + while \c link_prl is required when \i {using} a static library. + On Windows (or if Qt is configured with \c{-debug_and_release}, adding the \c build_all option to the \c CONFIG variable makes this rule the default when building the project, and installation targets will be created for -- cgit v0.12 From 353dacb5e4c45e860ae8be228df9647c5a71093e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 2 Jul 2009 10:54:09 +0200 Subject: add license headers --- tests/auto/linguist/lconvert/tst_lconvert.cpp | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lrelease/tst_lrelease.cpp | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lupdate/testlupdate.cpp | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lupdate/testlupdate.h | 41 +++++++++++++++++++++++++++ tests/auto/linguist/lupdate/tst_lupdate.cpp | 41 +++++++++++++++++++++++++++ 5 files changed, 205 insertions(+) diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp index 3df2a19..40be55a 100644 --- a/tests/auto/linguist/lconvert/tst_lconvert.cpp +++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp index 6f65dbc..512987d 100644 --- a/tests/auto/linguist/lrelease/tst_lrelease.cpp +++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include #include diff --git a/tests/auto/linguist/lupdate/testlupdate.cpp b/tests/auto/linguist/lupdate/testlupdate.cpp index c80dd54..8abc2b0 100644 --- a/tests/auto/linguist/lupdate/testlupdate.cpp +++ b/tests/auto/linguist/lupdate/testlupdate.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "testlupdate.h" #include #include diff --git a/tests/auto/linguist/lupdate/testlupdate.h b/tests/auto/linguist/lupdate/testlupdate.h index 3fd7dcb..efe9d85 100644 --- a/tests/auto/linguist/lupdate/testlupdate.h +++ b/tests/auto/linguist/lupdate/testlupdate.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef TESTLUPDATE_H #define TESTLUPDATE_H diff --git a/tests/auto/linguist/lupdate/tst_lupdate.cpp b/tests/auto/linguist/lupdate/tst_lupdate.cpp index 1beae73..fcf8582 100644 --- a/tests/auto/linguist/lupdate/tst_lupdate.cpp +++ b/tests/auto/linguist/lupdate/tst_lupdate.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "testlupdate.h" #if CHECK_SIMTEXTH #include "../shared/simtexth.h" -- cgit v0.12 From ad637177fa62f6ac92b653735bc2f743d7af2851 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 2 Jul 2009 11:10:36 +0200 Subject: add a few QObject binding tests --- tests/auto/qscriptqobject/tst_qscriptqobject.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp index 14d3283..ee914ab 100644 --- a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp +++ b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp @@ -605,6 +605,12 @@ void tst_QScriptExtQObject::getSetStaticProperty() QVERIFY(!(mobj.propertyFlags("mySlot") & QScriptValue::Undeletable)); QVERIFY(!(mobj.propertyFlags("mySlot") & QScriptValue::SkipInEnumeration)); QVERIFY(mobj.propertyFlags("mySlot") & QScriptValue::QObjectMember); + + // signature-based property + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::ReadOnly)); + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::Undeletable)); + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::SkipInEnumeration)); + QVERIFY(mobj.propertyFlags("mySlot()") & QScriptValue::QObjectMember); } // property change in C++ should be reflected in script @@ -847,6 +853,9 @@ void tst_QScriptExtQObject::getSetStaticProperty() QVERIFY(slot.isFunction()); QScriptValue sameSlot = m_engine->evaluate("myObject.mySlot"); QVERIFY(sameSlot.strictlyEquals(slot)); + sameSlot = m_engine->evaluate("myObject['mySlot()']"); + QEXPECT_FAIL("", "Signature-based method lookup creates new function wrapper object", Continue); + QVERIFY(sameSlot.strictlyEquals(slot)); } } @@ -897,6 +906,20 @@ void tst_QScriptExtQObject::getSetChildren() QCOMPARE(m_engine->evaluate("myObject.hasOwnProperty('child')") .strictlyEquals(QScriptValue(m_engine, true)), true); + QScriptValue mobj = m_engine->evaluate("myObject"); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::ReadOnly); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::Undeletable); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::SkipInEnumeration); + QVERIFY(!(mobj.propertyFlags("child") & QScriptValue::QObjectMember)); + + { + QScriptValue scriptChild = m_engine->evaluate("myObject.child"); + QVERIFY(scriptChild.isQObject()); + QCOMPARE(scriptChild.toQObject(), (QObject*)child); + QScriptValue sameChild = m_engine->evaluate("myObject.child"); + QVERIFY(sameChild.strictlyEquals(scriptChild)); + } + // add a grandchild MyQObject *grandChild = new MyQObject(child); grandChild->setObjectName("grandChild"); -- cgit v0.12 From cd4901b1e3a545d025628e881a143b8f240d2690 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 11:37:53 +0200 Subject: doc: Corrected several qdoc warnings. --- doc/src/qnamespace.qdoc | 3 +++ src/gui/kernel/qapplication.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index 805855a..e77cc7e 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -1208,6 +1208,9 @@ handle touch events. Without this attribute set, events from a touch device will be sent as mouse events. + \value WA_TouchPadAcceptSingleTouchEvents Allows touchpad single + touch events to be sent to the widget. + \omitvalue WA_SetLayoutDirection \omitvalue WA_InputMethodTransparent \omitvalue WA_WState_CompressKeys diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 60c69cc..a7b7a0a 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5064,7 +5064,7 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) Qt takes ownership of the provided \a recognizer. - \sa Qt::AA_EnableGestures, QGestureEvent + \sa QGestureEvent */ void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) { @@ -5076,7 +5076,7 @@ void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) Removes custom gesture \a recognizer object. - \sa Qt::AA_EnableGestures, QGestureEvent + \sa QGestureEvent */ void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) { -- cgit v0.12 From 11ef1b9bae383c46f7893db0d26c99d354642609 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 20:50:32 +0200 Subject: Add a function to check if an interface is implemented by an object. Also reorganise a bit, moving the function to create the interface name from an object's class name to qdbusmisc.cpp too. Reviewed-By: Trust Me --- src/dbus/qdbusconnection_p.h | 5 ++--- src/dbus/qdbusintegrator.cpp | 8 ++----- src/dbus/qdbusmisc.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++ src/dbus/qdbusxmlgenerator.cpp | 37 --------------------------------- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 5c37509..a156a71 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -300,6 +300,8 @@ public: extern int qDBusParametersForMethod(const QMetaMethod &mm, QList& metaTypes); extern int qDBusNameToTypeId(const char *name); extern bool qDBusCheckAsyncTag(const char *tag); +extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name); +extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); // in qdbusinternalfilters.cpp extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node); @@ -310,9 +312,6 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg); -// in qdbusxmlgenerator.cpp -extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); - QT_END_NAMESPACE #endif diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 0578bf1..76179c9 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1359,12 +1359,8 @@ void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node, const QDBusMes // try the object itself: if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots)) { bool interfaceFound = true; - if (!msg.interface().isEmpty()) { - // check if the interface name matches anything in the class hierarchy - const QMetaObject *mo = node.obj->metaObject(); - for ( ; !interfaceFound && mo != &QObject::staticMetaObject; mo = mo->superClass()) - interfaceFound = msg.interface() == qDBusInterfaceFromMetaObject(mo); - } + if (!msg.interface().isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, msg.interface()); if (interfaceFound) { if (!activateCall(node.obj, node.flags, msg)) diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp index e5c1da6..1b77a9b 100644 --- a/src/dbus/qdbusmisc.cpp +++ b/src/dbus/qdbusmisc.cpp @@ -41,12 +41,14 @@ #include +#include #include #include #include "qdbusutil_p.h" #include "qdbusconnection_p.h" #include "qdbusmetatype_p.h" +#include "qdbusabstractadaptor_p.h" // for QCLASSINFO_DBUS_* QT_BEGIN_NAMESPACE @@ -73,6 +75,51 @@ int qDBusNameToTypeId(const char *name) return id; } +QString qDBusInterfaceFromMetaObject(const QMetaObject *mo) +{ + QString interface; + + int idx = mo->indexOfClassInfo(QCLASSINFO_DBUS_INTERFACE); + if (idx >= mo->classInfoOffset()) { + interface = QLatin1String(mo->classInfo(idx).value()); + } else { + interface = QLatin1String(mo->className()); + interface.replace(QLatin1String("::"), QLatin1String(".")); + + if (interface.startsWith(QLatin1String("QDBus"))) { + interface.prepend(QLatin1String("com.trolltech.QtDBus.")); + } else if (interface.startsWith(QLatin1Char('Q')) && + interface.length() >= 2 && interface.at(1).isUpper()) { + // assume it's Qt + interface.prepend(QLatin1String("com.trolltech.Qt.")); + } else if (!QCoreApplication::instance()|| + QCoreApplication::instance()->applicationName().isEmpty()) { + interface.prepend(QLatin1String("local.")); + } else { + interface.prepend(QLatin1Char('.')).prepend(QCoreApplication::instance()->applicationName()); + QStringList domainName = + QCoreApplication::instance()->organizationDomain().split(QLatin1Char('.'), + QString::SkipEmptyParts); + if (domainName.isEmpty()) + interface.prepend(QLatin1String("local.")); + else + for (int i = 0; i < domainName.count(); ++i) + interface.prepend(QLatin1Char('.')).prepend(domainName.at(i)); + } + } + + return interface; +} + +bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name) +{ + const QMetaObject *mo = obj->metaObject(); + for ( ; mo != &QObject::staticMetaObject; mo = mo->superClass()) + if (interface_name == qDBusInterfaceFromMetaObject(mo)) + return true; + return false; +} + // calculates the metatypes for the method // the slot must have the parameters in the following form: // - zero or more value or const-ref parameters of any kind diff --git a/src/dbus/qdbusxmlgenerator.cpp b/src/dbus/qdbusxmlgenerator.cpp index 82bd762..b426abd 100644 --- a/src/dbus/qdbusxmlgenerator.cpp +++ b/src/dbus/qdbusxmlgenerator.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ -#include #include #include @@ -232,42 +231,6 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method return retval; } -QString qDBusInterfaceFromMetaObject(const QMetaObject *mo) -{ - QString interface; - - int idx = mo->indexOfClassInfo(QCLASSINFO_DBUS_INTERFACE); - if (idx >= mo->classInfoOffset()) { - interface = QLatin1String(mo->classInfo(idx).value()); - } else { - interface = QLatin1String(mo->className()); - interface.replace(QLatin1String("::"), QLatin1String(".")); - - if (interface.startsWith(QLatin1String("QDBus"))) { - interface.prepend(QLatin1String("com.trolltech.QtDBus.")); - } else if (interface.startsWith(QLatin1Char('Q')) && - interface.length() >= 2 && interface.at(1).isUpper()) { - // assume it's Qt - interface.prepend(QLatin1String("com.trolltech.Qt.")); - } else if (!QCoreApplication::instance()|| - QCoreApplication::instance()->applicationName().isEmpty()) { - interface.prepend(QLatin1String("local.")); - } else { - interface.prepend(QLatin1Char('.')).prepend(QCoreApplication::instance()->applicationName()); - QStringList domainName = - QCoreApplication::instance()->organizationDomain().split(QLatin1Char('.'), - QString::SkipEmptyParts); - if (domainName.isEmpty()) - interface.prepend(QLatin1String("local.")); - else - for (int i = 0; i < domainName.count(); ++i) - interface.prepend(QLatin1Char('.')).prepend(domainName.at(i)); - } - } - - return interface; - } - QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo, const QMetaObject *base, int flags) { -- cgit v0.12 From 6bd18f891b4bbc265e5ddd18ba57095886b36e38 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 15:32:26 +0200 Subject: Add some new error codes for indicating invalid D-Bus parameters. I'm wondering if I should be adding com.trolltech.QtDBus stuff now. But since there's already one there, I don't see why not... Reviewed-By: Harald Fernengel --- src/dbus/qdbuserror.cpp | 11 ++++++++++- src/dbus/qdbuserror.h | 6 +++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp index 817356d..7509ded 100644 --- a/src/dbus/qdbuserror.cpp +++ b/src/dbus/qdbuserror.cpp @@ -91,6 +91,10 @@ org.freedesktop.DBus.Error.InvalidSignature org.freedesktop.DBus.Error.UnknownInterface com.trolltech.QtDBus.Error.InternalError org.freedesktop.DBus.Error.UnknownObject +com.trolltech.QtDBus.Error.InvalidService +com.trolltech.QtDBus.Error.InvalidObjectPath +com.trolltech.QtDBus.Error.InvalidInterface +com.trolltech.QtDBus.Error.InvalidMember */ // in the same order as KnownErrors! @@ -116,12 +120,17 @@ static const char errorMessages_string[] = "org.freedesktop.DBus.Error.UnknownInterface\0" "com.trolltech.QtDBus.Error.InternalError\0" "org.freedesktop.DBus.Error.UnknownObject\0" + "com.trolltech.QtDBus.Error.InvalidService\0" + "com.trolltech.QtDBus.Error.InvalidObjectPath\0" + "com.trolltech.QtDBus.Error.InvalidInterface\0" + "com.trolltech.QtDBus.Error.InvalidMember\0" "\0"; static const int errorMessages_indices[] = { 0, 6, 40, 76, 118, 153, 191, 231, 273, 313, 349, 384, 421, 461, 501, 540, - 581, 617, 661, 705, 746, 0 + 581, 617, 661, 705, 746, 787, 829, 874, + 918, 0 }; static const int errorMessages_count = sizeof errorMessages_indices / diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index 7b77fd5..4e348dd 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -81,10 +81,14 @@ public: UnknownInterface, InternalError, UnknownObject, + InvalidService, + InvalidObjectPath, + InvalidInterface, + InvalidMember, #ifndef Q_QDOC // don't use this one! - LastErrorType = UnknownObject + LastErrorType = InvalidMember #endif }; -- cgit v0.12 From 96152ee50dfca7adf47b81b14015355260564a22 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 17:52:33 +0200 Subject: Add central validation code to QDBusUtil. These tests are useful in QDBusMessage and QDBusAbstractInterface. It avoids having the same messages all over the place. Reviewed-By: Harald Fernengel --- src/dbus/qdbusutil_p.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h index 13031fd..5c1e4cd 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -57,6 +57,7 @@ #include #include +#include QT_BEGIN_HEADER @@ -83,6 +84,73 @@ namespace QDBusUtil QDBUS_EXPORT bool isValidSingleSignature(const QString &signature); QDBUS_EXPORT QString argumentToString(const QVariant &variant); + + enum AllowEmptyFlag { + EmptyAllowed, + EmptyNotAllowed + }; + + inline bool checkInterfaceName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidInterface, QLatin1String("Interface name cannot be empty")); + return false; + } + if (isValidInterfaceName(name)) return true; + *error = QDBusError(QDBusError::InvalidInterface, QString::fromLatin1("Invalid interface class: %1").arg(name)); + return false; + } + + inline bool checkBusName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidService, QLatin1String("Service name cannot be empty")); + return false; + } + if (isValidBusName(name)) return true; + *error = QDBusError(QDBusError::InvalidService, QString::fromLatin1("Invalid service name: %1").arg(name)); + return false; + } + + inline bool checkObjectPath(const QString &path, AllowEmptyFlag empty, QDBusError *error) + { + if (path.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty")); + return false; + } + if (isValidObjectPath(path)) return true; + *error = QDBusError(QDBusError::InvalidObjectPath, QString::fromLatin1("Invalid object path: %1").arg(path)); + return false; + } + + inline bool checkMemberName(const QString &name, AllowEmptyFlag empty, QDBusError *error, const char *nameType = 0) + { + if (!nameType) nameType = "member"; + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidMember, QLatin1String(nameType) + QLatin1String(" name cannot be empty")); + return false; + } + if (isValidMemberName(name)) return true; + *error = QDBusError(QDBusError::InvalidMember, QString::fromLatin1("Invalid %1 name: %2") + .arg(QString::fromLatin1(nameType), name)); + return false; + } + + inline bool checkErrorName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidInterface, QLatin1String("Error name cannot be empty")); + return false; + } + if (isValidErrorName(name)) return true; + *error = QDBusError(QDBusError::InvalidInterface, QString::fromLatin1("Invalid error name: %1").arg(name)); + return false; + } } QT_END_NAMESPACE -- cgit v0.12 From bda9c20a556aa6ab6ccba978f7fc1ffe02c50813 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 16:31:09 +0200 Subject: Add support for error messages in the D-Bus marshaller. Reviewed-By: Harald Fernengel --- src/dbus/qdbusargument_p.h | 3 ++- src/dbus/qdbusmarshaller.cpp | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h index b49a517..78bc683 100644 --- a/src/dbus/qdbusargument_p.h +++ b/src/dbus/qdbusargument_p.h @@ -130,7 +130,7 @@ public: QDBusMarshaller *endCommon(); void open(QDBusMarshaller &sub, int code, const char *signature); void close(); - void error(); + void error(const QString &message); bool appendVariantInternal(const QVariant &arg); bool appendRegisteredType(const QVariant &arg); @@ -140,6 +140,7 @@ public: DBusMessageIter iterator; QDBusMarshaller *parent; QByteArray *ba; + QString errorString; char closeCode; bool ok; diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index 7ada1ed..bb7fa6b 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -121,7 +121,7 @@ inline void QDBusMarshaller::append(const QDBusObjectPath &arg) { QByteArray data = arg.path().toUtf8(); if (!ba && data.isEmpty()) - error(); + error(QLatin1String("Invalid object path passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_OBJECT_PATH, &cdata); } @@ -130,7 +130,7 @@ inline void QDBusMarshaller::append(const QDBusSignature &arg) { QByteArray data = arg.signature().toUtf8(); if (!ba && data.isEmpty()) - error(); + error(QLatin1String("Invalid signature passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &cdata); } @@ -161,7 +161,7 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) QVariant::Type id = QVariant::Type(value.userType()); if (id == QVariant::Invalid) { qWarning("QDBusMarshaller: cannot add a null QDBusVariant"); - error(); + error(QLatin1String("Variant containing QVariant::Invalid passed in arguments")); return false; } @@ -180,7 +180,8 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( id ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(id)))); return false; } @@ -220,7 +221,8 @@ inline QDBusMarshaller *QDBusMarshaller::beginArray(int id) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(id) ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(id))))); return this; } @@ -234,22 +236,26 @@ inline QDBusMarshaller *QDBusMarshaller::beginMap(int kid, int vid) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(kid) ), kid); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(kid))))); return this; } if (ksignature[1] != 0 || !q_dbus_type_is_basic(*ksignature)) { qWarning("QDBusMarshaller: type '%s' (%d) cannot be used as the key type in a D-BUS map.", QVariant::typeToName( QVariant::Type(kid) ), kid); - error(); + error(QString::fromLatin1("Type %1 passed in arguments cannot be used as a key in a map") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(kid))))); return this; } const char *vsignature = QDBusMetaType::typeToSignature( QVariant::Type(vid) ); if (!vsignature) { + const char *typeName = QVariant::typeToName(QVariant::Type(vid)); qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", - QVariant::typeToName( QVariant::Type(vid) ), vid); - error(); + typeName, vid); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(typeName))); return this; } @@ -328,11 +334,13 @@ void QDBusMarshaller::close() } } -void QDBusMarshaller::error() +void QDBusMarshaller::error(const QString &msg) { ok = false; if (parent) - parent->error(); + parent->error(msg); + else + errorString = msg; } bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) @@ -340,7 +348,7 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) int id = arg.userType(); if (id == QVariant::Invalid) { qWarning("QDBusMarshaller: cannot add an invalid QVariant"); - error(); + error(QLatin1String("Variant containing QVariant::Invalid passed in arguments")); return false; } @@ -371,7 +379,8 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(id) ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(id))))); return false; } -- cgit v0.12 From 6b0b1a3eefe60dbeed3f56770fb58d487852e45b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:47:46 +0200 Subject: Adapt the message-sending code to return error messages from the marshalling code. Reviewed-By: Harald Fernengel --- src/dbus/qdbusintegrator.cpp | 89 +++++++++++++++----------- src/dbus/qdbusmessage.cpp | 48 ++++++++++---- src/dbus/qdbusmessage_p.h | 2 +- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 16 ++++- 4 files changed, 104 insertions(+), 51 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 76179c9..704d2e3 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1144,9 +1144,12 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); message.setArguments(args); - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { - qWarning("QDBusConnection: Could not emit signal %s.%s", qPrintable(interface), memberName.constData()); + qWarning("QDBusConnection: Could not emit signal %s.%s: %s", qPrintable(interface), memberName.constData(), + qPrintable(error.message())); + lastError = error; return; } @@ -1698,21 +1701,26 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message) return -1; // don't send; the reply will be retrieved by the caller // through the d_ptr->localReply link - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { if (message.type() == QDBusMessage::MethodCallMessage) - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(error.message())); else if (message.type() == QDBusMessage::SignalMessage) - qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.path()), qPrintable(message.interface()), - qPrintable(message.member())); + qPrintable(message.member()), + qPrintable(error.message())); else - qWarning("QDBusConnection: error: could not send %s message to service \"%s\"", + qWarning("QDBusConnection: error: could not send %s message to service \"%s\": %s", message.type() == QDBusMessage::ReplyMessage ? "reply" : message.type() == QDBusMessage::ErrorMessage ? "error" : - "invalid", qPrintable(message.service())); + "invalid", qPrintable(message.service()), + qPrintable(error.message())); + lastError = error; return 0; } @@ -1739,12 +1747,15 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, return sendWithReplyLocal(message); if (!QCoreApplication::instance() || sendMode == QDBus::Block) { - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError err; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &err); if (!msg) { - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); - return QDBusMessage(); + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(err.message())); + lastError = err; + return QDBusMessage::createError(err); } qDBusDebug() << QThread::currentThread() << "sending message (blocking):" << message; @@ -1754,9 +1765,8 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, q_dbus_message_unref(msg); if (!!error) { - QDBusError qe = error; - lastError = qe; - return QDBusMessage::createError(qe); + lastError = err = error; + return QDBusMessage::createError(err); } QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(reply); @@ -1766,16 +1776,17 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, return amsg; } else { // use the event loop QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout); - if (!pcall) - return QDBusMessage(); + Q_ASSERT(pcall); - pcall->watcherHelper = new QDBusPendingCallWatcherHelper; - QEventLoop loop; - loop.connect(pcall->watcherHelper, SIGNAL(reply(QDBusMessage)), SLOT(quit())); - loop.connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), SLOT(quit())); + if (pcall->replyMessage.type() != QDBusMessage::InvalidMessage) { + pcall->watcherHelper = new QDBusPendingCallWatcherHelper; + QEventLoop loop; + loop.connect(pcall->watcherHelper, SIGNAL(reply(QDBusMessage)), SLOT(quit())); + loop.connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), SLOT(quit())); - // enter the event loop and wait for a reply - loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); + // enter the event loop and wait for a reply + loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); + } QDBusMessage reply = pcall->replyMessage; lastError = reply; // set or clear error @@ -1831,20 +1842,25 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM return pcall; } - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + checkThread(); + QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; + pcall->sentMessage = message; + pcall->ref = 0; + + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); - return 0; + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(error.message())); + pcall->replyMessage = QDBusMessage::createError(error); + lastError = error; + return pcall; } - checkThread(); qDBusDebug() << QThread::currentThread() << "sending message (async):" << message; DBusPendingCall *pending = 0; - QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; - pcall->sentMessage = message; - pcall->ref = 0; QDBusDispatchLocker locker(SendWithReplyAsyncAction, this); if (q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) { @@ -1858,14 +1874,14 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM return pcall; } else { // we're probably disconnected at this point - lastError = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to server")); + lastError = error = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to server")); } } else { - lastError = QDBusError(QDBusError::NoMemory, QLatin1String("Out of memory")); + lastError = error = QDBusError(QDBusError::NoMemory, QLatin1String("Out of memory")); } q_dbus_message_unref(msg); - pcall->replyMessage = QDBusMessage::createError(lastError); + pcall->replyMessage = QDBusMessage::createError(error); return pcall; } @@ -1874,8 +1890,7 @@ int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObj int timeout) { QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout); - if (!pcall) - return 0; + Q_ASSERT(pcall); // has it already finished (dispatched locally)? if (pcall->replyMessage.type() == QDBusMessage::ReplyMessage) { diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index 9150295..eb09de9 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -94,11 +94,17 @@ QString QDBusMessage::errorMessage() const \internal Constructs a DBusMessage object from this object. The returned value must be de-referenced with q_dbus_message_unref. + + The \a error object is set to indicate the error if anything went wrong with the + marshalling. Usually, this error message will be placed in the reply, as if the call failed. + The \a error pointer must not be null. */ -DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) +DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusError *error) { - if (!qdbus_loadLibDBus()) + if (!qdbus_loadLibDBus()) { + *error = QDBusError(QDBusError::Failed, QLatin1String("Could not open lidbus-1 library")); return 0; + } DBusMessage *msg = 0; const QDBusMessagePrivate *d_ptr = message.d_ptr; @@ -108,10 +114,17 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) //qDebug() << "QDBusMessagePrivate::toDBusMessage" << "message is invalid"; break; case DBUS_MESSAGE_TYPE_METHOD_CALL: - // only interface can be empty - if (d_ptr->service.isEmpty() || d_ptr->path.isEmpty() || d_ptr->name.isEmpty()) - break; - msg = q_dbus_message_new_method_call(d_ptr->service.toUtf8(), d_ptr->path.toUtf8(), + // only service and interface can be empty -> path and name must not be empty + if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + + msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: @@ -123,8 +136,9 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) break; case DBUS_MESSAGE_TYPE_ERROR: // error name can't be empty - if (d_ptr->name.isEmpty()) - break; + if (!QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) + return 0; + msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8()); if (!d_ptr->localMessage) { @@ -134,8 +148,13 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) break; case DBUS_MESSAGE_TYPE_SIGNAL: // nothing can be empty here - if (d_ptr->path.isEmpty() || d_ptr->interface.isEmpty() || d_ptr->name.isEmpty()) - break; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); break; @@ -170,6 +189,7 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) // not ok; q_dbus_message_unref(msg); + *error = QDBusError(QDBusError::Failed, QLatin1String("Marshalling failed: ") + marshaller.errorString); return 0; } @@ -247,7 +267,13 @@ QDBusMessage QDBusMessagePrivate::makeLocal(const QDBusConnectionPrivate &conn, // yes, we are // we must marshall and demarshall again so as to create QDBusArgument // entries for the complex types - DBusMessage *message = toDBusMessage(asSent); + QDBusError error; + DBusMessage *message = toDBusMessage(asSent, &error); + if (!message) { + // failed to marshall, so it's a call error + return QDBusMessage::createError(error); + } + q_dbus_message_set_sender(message, conn.baseService.toUtf8()); QDBusMessage retval = fromDBusMessage(message); diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index 12a9500..a0a681f 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -80,7 +80,7 @@ public: mutable uint delayedReply : 1; uint localMessage : 1; - static DBusMessage *toDBusMessage(const QDBusMessage &message); + static DBusMessage *toDBusMessage(const QDBusMessage &message, QDBusError *error); static QDBusMessage fromDBusMessage(DBusMessage *dmsg); static bool isLocal(const QDBusMessage &msg); diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index e5b2ebb..3ba789a 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -793,7 +793,7 @@ void tst_QDBusMarshall::sendErrors() "signalName"); msg << qVariantFromValue(QDBusObjectPath()); - QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\""); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments"); QVERIFY(!con.send(msg)); msg.setArguments(QVariantList()); @@ -803,7 +803,19 @@ void tst_QDBusMarshall::sendErrors() path.setPath("abc"); msg << qVariantFromValue(path); - QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\""); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments"); + QVERIFY(!con.send(msg)); + + QDBusSignature sig; + msg.setArguments(QVariantList() << qVariantFromValue(sig)); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments"); + QVERIFY(!con.send(msg)); + + QTest::ignoreMessage(QtWarningMsg, "QDBusSignature: invalid signature \"a\""); + sig.setSignature("a"); + msg.setArguments(QVariantList()); + msg << qVariantFromValue(sig); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments"); QVERIFY(!con.send(msg)); } -- cgit v0.12 From 8d4657764b0c4362dc25aa79a6e2853b8c98f0ad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 15:20:33 +0200 Subject: Keep creation failure errors for QDBusAbstractInterface. In case the object creation fails, set isValid to false. This will prevent any outgoing calls to be made with invalid information. In that case, lastError will never change either. This required adding a method to QDBusPendingCall, to be able to create one such object from an existing QDBusError. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 140 ++++++++++++++++++------------------ src/dbus/qdbusabstractinterface_p.h | 4 ++ src/dbus/qdbuspendingcall.cpp | 36 ++++++++++ src/dbus/qdbuspendingcall.h | 3 + src/dbus/qdbuspendingcall_p.h | 3 + 5 files changed, 116 insertions(+), 70 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 85c3274..a4097c6 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -52,82 +52,66 @@ QT_BEGIN_NAMESPACE +static QDBusError checkIfValid(const QString &service, const QString &path, + const QString &interface, bool isDynamic) +{ + // We should be throwing exceptions here... oh well + QDBusError error; + + // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths + // non-dynamic is the opposite: service and object paths can be empty, but not the interface + if (!isDynamic) { + // use assertion here because this should never happen, at all + Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty"); + } + if (!QDBusUtil::checkBusName(service, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) + return error; + if (!QDBusUtil::checkObjectPath(path, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) + return error; + if (!QDBusUtil::checkInterfaceName(interface, QDBusUtil::EmptyAllowed, &error)) + return error; + + // no error + return QDBusError(); +} + QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection& con, bool isDynamic) - : connection(con), service(serv), path(p), interface(iface), isValid(true) + : connection(con), service(serv), path(p), interface(iface), + lastError(checkIfValid(serv, p, iface, isDynamic)), + isValid(!lastError.isValid()) { - if (isDynamic) { - // QDBusInterface: service and object path can't be empty, but interface can -#if 0 - Q_ASSERT_X(QDBusUtil::isValidBusName(service), - "QDBusInterface::QDBusInterface", "Invalid service name"); - Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), - "QDBusInterface::QDBusInterface", "Invalid object path given"); - Q_ASSERT_X(interface.isEmpty() || QDBusUtil::isValidInterfaceName(interface), - "QDBusInterface::QDBusInterface", "Invalid interface name"); -#else - if (!QDBusUtil::isValidBusName(service)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid service name")); - isValid = false; - } else if (!QDBusUtil::isValidObjectPath(path)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid object name given")); - isValid = false; - } else if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid interface name")); - isValid = false; - } -#endif - } else { - // all others: service and path can be empty here, but interface can't -#if 0 - Q_ASSERT_X(service.isEmpty() || QDBusUtil::isValidBusName(service), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid service name"); - Q_ASSERT_X(path.isEmpty() || QDBusUtil::isValidObjectPath(path), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid object path given"); - Q_ASSERT_X(QDBusUtil::isValidInterfaceName(interface), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid interface class!"); -#else - if (!service.isEmpty() && !QDBusUtil::isValidBusName(service)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid service name")); - isValid = false; - } else if (!path.isEmpty() && !QDBusUtil::isValidObjectPath(path)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid object path given")); - isValid = false; - } else if (!QDBusUtil::isValidInterfaceName(interface)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid interface class")); - isValid = false; - } -#endif - } - if (!isValid) return; if (!connection.isConnected()) { lastError = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to D-Bus server")); - isValid = false; } else if (!service.isEmpty()) { currentOwner = connectionPrivate()->getNameOwner(service); // verify the name owner if (currentOwner.isEmpty()) { - isValid = false; lastError = connectionPrivate()->lastError; } } } +bool QDBusAbstractInterfacePrivate::canMakeCalls() const +{ + // recheck only if we have a wildcard (i.e. empty) service or path + // if any are empty, set the error message according to QDBusUtil + if (service.isEmpty()) + return QDBusUtil::checkBusName(service, QDBusUtil::EmptyNotAllowed, &lastError); + if (path.isEmpty()) + return QDBusUtil::checkObjectPath(path, QDBusUtil::EmptyNotAllowed, &lastError); + return true; +} + QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const { - if (!connection.isConnected()) // not connected + if (!isValid || !canMakeCalls()) // can't make calls return QVariant(); // is this metatype registered? @@ -144,6 +128,9 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", mp.typeName(), qPrintable(interface), mp.name()); + lastError = QDBusError(QDBusError::Failed, + QString::fromLatin1("Unregistered type %1 cannot be handled") + .arg(QLatin1String(mp.typeName()))); return QVariant(); } } @@ -208,7 +195,7 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) { - if (!connection.isConnected()) // not connected + if (!isValid || !canMakeCalls()) // can't make calls return; // send the value @@ -230,7 +217,6 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner; if (name == service) { currentOwner = newOwner; - isValid = !newOwner.isEmpty(); } } @@ -261,7 +247,7 @@ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, : QObject(d, parent) { // keep track of the service owner - if (d_func()->isValid) + if (!d_func()->currentOwner.isEmpty()) QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } @@ -300,7 +286,7 @@ QDBusAbstractInterface::~QDBusAbstractInterface() */ bool QDBusAbstractInterface::isValid() const { - return d_func()->isValid; + return !d_func()->currentOwner.isEmpty(); } /*! @@ -367,6 +353,9 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode, { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return QDBusMessage::createError(d->lastError); + QString m = method; // split out the signature from the method int pos = method.indexOf(QLatin1Char('.')); @@ -425,6 +414,9 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return QDBusPendingCall::fromError(d->lastError); + QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method); msg.setArguments(args); return d->connection.asyncCall(msg); @@ -440,7 +432,8 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString This function returns true if the queueing succeeds. It does not indicate that the executed call succeeded. If it fails, - the \a errorMethod is called. + the \a errorMethod is called. If the queueing failed, this + function returns false and no slot will be called. The \a returnMethod must have as its parameters the types returned by the function call. Optionally, it may have a QDBusMessage @@ -453,22 +446,25 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString bool QDBusAbstractInterface::callWithCallback(const QString &method, const QList &args, QObject *receiver, - const char *returnMethod, + const char *returnMethod, const char *errorMethod) { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return false; + QDBusMessage msg = QDBusMessage::createMethodCall(service(), - path(), - interface(), - method); + path(), + interface(), + method); msg.setArguments(args); d->lastError = 0; return d->connection.callWithCallback(msg, - receiver, - returnMethod, - errorMethod); + receiver, + returnMethod, + errorMethod); } /*! @@ -492,7 +488,7 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, bool QDBusAbstractInterface::callWithCallback(const QString &method, const QList &args, QObject *receiver, - const char *slot) + const char *slot) { return callWithCallback(method, args, receiver, slot, 0); } @@ -503,13 +499,15 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, */ void QDBusAbstractInterface::connectNotify(const char *signal) { + // someone connecting to one of our signals + Q_D(QDBusAbstractInterface); + if (!d->isValid) + return; + // we end up recursing here, so optimise away if (qstrcmp(signal + 1, "destroyed(QObject*)") == 0) return; - // someone connecting to one of our signals - Q_D(QDBusAbstractInterface); - QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) conn->connectRelay(d->service, d->currentOwner, d->path, d->interface, @@ -524,6 +522,8 @@ void QDBusAbstractInterface::disconnectNotify(const char *signal) { // someone disconnecting from one of our signals Q_D(QDBusAbstractInterface); + if (!d->isValid) + return; QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e2ea058..e5822b3 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -75,11 +75,15 @@ public: QString path; QString interface; mutable QDBusError lastError; + + // this is set during creation and never changed + // it can't be const because QDBusInterfacePrivate has one more check bool isValid; QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection& con, bool dynamic); virtual ~QDBusAbstractInterfacePrivate() { } + bool canMakeCalls() const; // these functions do not check if the property is valid QVariant property(const QMetaProperty &mp) const; diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 1797ed0..7807543 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -409,6 +409,42 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member) } #endif +/*! + Creates a QDBusPendingCall object based on the error condition + \a error. The resulting pending call object will be in the + "finished" state and QDBusPendingReply::isError() will return true. + + \sa fromCompletedCall() +*/ +QDBusPendingCall QDBusPendingCall::fromError(const QDBusError &error) +{ + return fromCompletedCall(QDBusMessage::createError(error)); +} + +/*! + Creates a QDBusPendingCall object based on the message \a msg. + The message must be of type QDBusMessage::ErrorMessage or + QDBusMessage::ReplyMessage (that is, a message that is typical + of a completed call). + + This function is useful for code that requires simulating a pending + call, but that has already finished. + + \sa fromError() +*/ +QDBusPendingCall QDBusPendingCall::fromCompletedCall(const QDBusMessage &msg) +{ + QDBusPendingCallPrivate *d = 0; + if (msg.type() == QDBusMessage::ErrorMessage || + msg.type() == QDBusMessage::ReplyMessage) { + d = new QDBusPendingCallPrivate; + d->replyMessage = msg; + d->connection = 0; + } + + return QDBusPendingCall(d); +} + class QDBusPendingCallWatcherPrivate: public QObjectPrivate { diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h index 8881920..8dbbb3c 100644 --- a/src/dbus/qdbuspendingcall.h +++ b/src/dbus/qdbuspendingcall.h @@ -78,6 +78,9 @@ public: QDBusMessage reply() const; #endif + static QDBusPendingCall fromError(const QDBusError &error); + static QDBusPendingCall fromCompletedCall(const QDBusMessage &message); + protected: QExplicitlySharedDataPointer d; friend class QDBusPendingCallPrivate; diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h index 7136f67..5577451 100644 --- a/src/dbus/qdbuspendingcall_p.h +++ b/src/dbus/qdbuspendingcall_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE +class QDBusPendingCall; class QDBusPendingCallWatcher; class QDBusPendingCallWatcherHelper; class QDBusConnectionPrivate; @@ -94,6 +95,8 @@ public: void waitForFinished(); void setMetaTypes(int count, const int *types); void checkReceivedSignature(); + + static QDBusPendingCall fromMessage(const QDBusMessage &msg); }; class QDBusPendingCallWatcherHelper: public QObject -- cgit v0.12 From e7ca74ed8a41eb4c05f436007417d160b6cf94f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:13:47 +0200 Subject: Avoid revalidating message parameters. This is a small performance improvement when making a call: we don't need to validate what we already know to be valid because we either designed it to be so or because we've already validated. The D-Bus library unfortunately validates again and there's nothing we can do about it. But we can avoid doing it twice in our own code. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 6 ++++ src/dbus/qdbusintegrator.cpp | 3 ++ src/dbus/qdbusinternalfilters.cpp | 2 +- src/dbus/qdbusmessage.cpp | 60 +++++++++++++++++++++---------------- src/dbus/qdbusmessage.h | 6 ++-- src/dbus/qdbusmessage_p.h | 9 ++++++ 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index a4097c6..08da997 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -44,6 +44,7 @@ #include "qdbusargument.h" #include "qdbuspendingcall.h" +#include "qdbusmessage_p.h" #include "qdbusmetaobject_p.h" #include "qdbusmetatype_p.h" #include "qdbusutil_p.h" @@ -139,6 +140,7 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Get")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << interface << QString::fromUtf8(mp.name()); QDBusMessage reply = connection.call(msg, QDBus::Block); @@ -202,6 +204,7 @@ void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Set")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value)); QDBusMessage reply = connection.call(msg, QDBus::Block); @@ -386,6 +389,7 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode, // qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path(); QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), m); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); QDBusMessage reply = d->connection.call(msg, mode); @@ -418,6 +422,7 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString return QDBusPendingCall::fromError(d->lastError); QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); return d->connection.asyncCall(msg); } @@ -458,6 +463,7 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, path(), interface(), method); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); d->lastError = 0; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 704d2e3..a0903ed 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1143,6 +1143,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in QDBusReadLocker locker(RelaySignalAction, this); QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); + QDBusMessagePrivate::setParametersValidated(message, true); message.setArguments(args); QDBusError error; DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); @@ -2092,6 +2093,7 @@ QString QDBusConnectionPrivate::getNameOwner(const QString& serviceName) QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS), QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS), QLatin1String("GetNameOwner")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << serviceName; QDBusMessage reply = sendWithReply(msg, QDBus::Block); if (reply.type() == QDBusMessage::ReplyMessage) @@ -2115,6 +2117,7 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_INTROSPECTABLE), QLatin1String("Introspect")); + QDBusMessagePrivate::setParametersValidated(msg, true); QDBusMessage reply = sendWithReply(msg, QDBus::Block); diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 416144d..762a49b 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -179,7 +179,7 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node static QDBusMessage qDBusPropertyError(const QDBusMessage &msg, const QString &interface_name) { - return msg.createErrorReply(QLatin1String(DBUS_ERROR_INVALID_ARGS), + return msg.createErrorReply(QDBusError::InvalidArgs, QString::fromLatin1("Interface %1 was not found in object %2") .arg(interface_name) .arg(msg.path())); diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index eb09de9..78de6d9 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -62,7 +62,8 @@ static inline const char *data(const QByteArray &arr) QDBusMessagePrivate::QDBusMessagePrivate() : msg(0), reply(0), type(DBUS_MESSAGE_TYPE_INVALID), - timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false) + timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false), + parametersValidated(false) { } @@ -115,14 +116,16 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_METHOD_CALL: // only service and interface can be empty -> path and name must not be empty - if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) - return 0; - if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) - return 0; + if (!d_ptr->parametersValidated) { + if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + } msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); @@ -136,7 +139,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_ERROR: // error name can't be empty - if (!QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) + if (!d_ptr->parametersValidated + && !QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) return 0; msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); @@ -148,12 +152,14 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_SIGNAL: // nothing can be empty here - if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) - return 0; - if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) - return 0; + if (!d_ptr->parametersValidated) { + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + } msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); @@ -162,16 +168,11 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB Q_ASSERT(false); break; } -#if 0 - DBusError err; - q_dbus_error_init(&err); - if (q_dbus_error_is_set(&err)) { - QDBusError qe(&err); - qDebug() << "QDBusMessagePrivate::toDBusMessage" << qe; - } -#endif - if (!msg) - return 0; + + // if we got here, the parameters validated + // and since the message parameters cannot be changed once the message is created + // we can record this fact + d_ptr->parametersValidated = true; QDBusMarshaller marshaller; QVariantList::ConstIterator it = d_ptr->arguments.constBegin(); @@ -492,6 +493,13 @@ QDBusMessage QDBusMessage::createErrorReply(const QString name, const QString &m Constructs a new DBus reply message for the error type \a type using the message \a msg. Returns the DBus message. */ +QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const +{ + QDBusMessage msg = createErrorReply(QDBusError::errorString(atype), amsg); + msg.d_ptr->parametersValidated = true; + return msg; +} + /*! Constructs an empty, invalid QDBusMessage object. diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index 55f388a..34b1635 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -87,8 +87,9 @@ public: QDBusMessage createErrorReply(const QString name, const QString &msg) const; inline QDBusMessage createErrorReply(const QDBusError &err) const { return createErrorReply(err.name(), err.message()); } - inline QDBusMessage createErrorReply(QDBusError::ErrorType type, const QString &msg) const; + QDBusMessage createErrorReply(QDBusError::ErrorType type, const QString &msg) const; + // there are no setters; if this changes, see qdbusmessage_p.h QString service() const; QString path() const; QString interface() const; @@ -113,9 +114,6 @@ private: QDBusMessagePrivate *d_ptr; }; -inline QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const -{ return createErrorReply(QDBusError::errorString(atype), amsg); } - #ifndef QT_NO_DEBUG_STREAM QDBUS_EXPORT QDebug operator<<(QDebug, const QDBusMessage &); #endif diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index a0a681f..b8f23dc 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -55,6 +55,7 @@ #include #include +#include struct DBusMessage; @@ -69,7 +70,11 @@ public: ~QDBusMessagePrivate(); QList arguments; + + // the following parameters are "const": they are not changed after the constructors + // the parametersValidated member below controls whether they've been validated already QString service, path, interface, name, message, signature; + DBusMessage *msg; DBusMessage *reply; int type; @@ -79,6 +84,10 @@ public: mutable uint delayedReply : 1; uint localMessage : 1; + mutable uint parametersValidated : 1; + + static void setParametersValidated(QDBusMessage &msg, bool enable) + { msg.d_ptr->parametersValidated = enable; } static DBusMessage *toDBusMessage(const QDBusMessage &message, QDBusError *error); static QDBusMessage fromDBusMessage(DBusMessage *dmsg); -- cgit v0.12 From 485b2afb790444a0c6c2b32fbac65421e652dbe4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 18:27:11 +0200 Subject: Use an "int status" extra parameter in property reading/writing. When calling qt_metacall with the ReadProperty or WriteProperty, the data is on argv[0] like it was before, but now the QVariant itself is on argv[1] and there's an extra parameter in argv[2] which the meta code can use to indicate result. This allows QtDBus to process properties much more easily. In the case of property reading, we need to be able to modify the variant itself, because copying types when we don't have the data isn't very easy. As for setting, we need to be able to tell setProperty to return true or false depending on whether we succeeded in setting the property or not. Reviewed-By: Kent Hansen Reviewed-By: Marius Bugge Monsen --- src/corelib/kernel/qmetaobject.cpp | 23 ++++++++++++++++----- src/dbus/qdbusabstractinterface.cpp | 40 ++++++++++++++++++++++++++++++++----- src/dbus/qdbusabstractinterface.h | 18 ++++++++++++++++- src/dbus/qdbusabstractinterface_p.h | 2 +- src/dbus/qdbusinterface.cpp | 20 ------------------- 5 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 71dd5ff..34f580b 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2131,8 +2131,15 @@ QVariant QMetaProperty::read(const QObject *object) const return QVariant(); } } + + // the status variable is changed by qt_metacall to indicate what it did + // this feature is currently only used by QtDBus and should not be depended + // upon. Don't change it without looking into QDBusAbstractInterface first + // -1 (unchanged): normal qt_metacall, result stored in argv[0] + // changed: result stored directly in value + int status = -1; QVariant value; - void *argv[2] = { 0, &value }; + void *argv[] = { 0, &value, &status }; if (t == QVariant::LastType) { argv[0] = &value; } else { @@ -2142,8 +2149,8 @@ QVariant QMetaProperty::read(const QObject *object) const const_cast(object)->qt_metacall(QMetaObject::ReadProperty, idx + mobj->propertyOffset(), argv); - if (argv[1] == 0) - // "value" was changed + + if (status != -1) return value; if (t != QVariant::LastType && argv[0] != value.data()) // pointer or reference @@ -2201,13 +2208,19 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const return false; } - void *argv[2] = { 0, &v }; + // the status variable is changed by qt_metacall to indicate what it did + // this feature is currently only used by QtDBus and should not be depended + // upon. Don't change it without looking into QDBusAbstractInterface first + // -1 (unchanged): normal qt_metacall, result stored in argv[0] + // changed: result stored directly in value, return the value of status + int status = -1; + void *argv[] = { 0, &v, &status }; if (t == QVariant::LastType) argv[0] = &v; else argv[0] = v.data(); object->qt_metacall(QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv); - return true; + return status; } /*! diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 08da997..9bef2dd 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -195,10 +195,10 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const return QVariant(); } -void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) +bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) { if (!isValid || !canMakeCalls()) // can't make calls - return; + return false; // send the value QDBusMessage msg = QDBusMessage::createMethodCall(service, path, @@ -208,8 +208,11 @@ void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value)); QDBusMessage reply = connection.call(msg, QDBus::Block); - if (reply.type() != QDBusMessage::ReplyMessage) + if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; + return false; + } + return true; } void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, @@ -223,6 +226,33 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, } } +QDBusAbstractInterfaceBase::QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &d, QObject *parent) + : QObject(d, parent) +{ +} + +int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + int saved_id = _id; + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + + if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) { + QMetaProperty mp = metaObject()->property(saved_id); + int &status = *reinterpret_cast(_a[2]); + QVariant &variant = *reinterpret_cast(_a[1]); + + if (_c == QMetaObject::WriteProperty) { + status = d_func()->setProperty(mp, variant) ? 1 : 0; + } else { + variant = d_func()->property(mp); + status = variant.isValid() ? 1 : 0; + } + _id = -1; + } + return _id; +} /*! \class QDBusAbstractInterface @@ -247,7 +277,7 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, This is the constructor called from QDBusInterface::QDBusInterface. */ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent) - : QObject(d, parent) + : QDBusAbstractInterfaceBase(d, parent) { // keep track of the service owner if (!d_func()->currentOwner.isEmpty()) @@ -263,7 +293,7 @@ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path, const char *interface, const QDBusConnection &con, QObject *parent) - : QObject(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), + : QDBusAbstractInterfaceBase(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), con, false), parent) { // keep track of the service owner diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h index 6400b26..e525f77 100644 --- a/src/dbus/qdbusabstractinterface.h +++ b/src/dbus/qdbusabstractinterface.h @@ -61,7 +61,23 @@ class QDBusError; class QDBusPendingCall; class QDBusAbstractInterfacePrivate; -class QDBUS_EXPORT QDBusAbstractInterface: public QObject + +class QDBUS_EXPORT QDBusAbstractInterfaceBase: public QObject +{ +public: + int qt_metacall(QMetaObject::Call, int, void**); +protected: + QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &dd, QObject *parent); +private: + Q_DECLARE_PRIVATE(QDBusAbstractInterface) +}; + +class QDBUS_EXPORT QDBusAbstractInterface: +#ifdef Q_QDOC + public QObject +#else + public QDBusAbstractInterfaceBase +#endif { Q_OBJECT diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e5822b3..e577898 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -87,7 +87,7 @@ public: // these functions do not check if the property is valid QVariant property(const QMetaProperty &mp) const; - void setProperty(const QMetaProperty &mp, const QVariant &value); + bool setProperty(const QMetaProperty &mp, const QVariant &value); // return conn's d pointer inline QDBusConnectionPrivate *connectionPrivate() const diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index 211b717..6f61847 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -205,26 +205,6 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) // done return -1; } - } else if (c == QMetaObject::ReadProperty) { - // Qt doesn't support non-readable properties - // we have to re-check - QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); - if (!mp.isReadable()) - return -1; // don't read - - QVariant *value = reinterpret_cast(argv[1]); - argv[1] = 0; - *value = property(mp); - - return -1; // handled, error or not - } else if (c == QMetaObject::WriteProperty) { - // QMetaProperty::write has already checked that we're writable - // it has also checked that the type is right - QVariant *value = reinterpret_cast(argv[1]); - QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); - - setProperty(mp, *value); - return -1; } return id; } -- cgit v0.12 From c4fa498f447bd569ee91e16f07bdb7954b5adc76 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 20:52:35 +0200 Subject: Fix setting of complex/custom properties and error messages. Complex properties require demarshalling before passing on to QMetaProperty::write(). We can't pass on a QVariant containing an un-demarshalled QDBusArgument. So add a new function that does the decoding properly, as well as error checking. Also take the opportunity to properly check the interface name in the case of setting a property exported from the object itself (not an adaptor). Task-number: 240608 Reviewed-by: Marius Bugge Monsen --- src/dbus/qdbusinternalfilters.cpp | 167 +++++++++++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 31 deletions(-) diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 762a49b..45cbbb0 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -53,6 +53,7 @@ #include "qdbusextratypes.h" #include "qdbusmessage.h" #include "qdbusmetatype.h" +#include "qdbusmetatype_p.h" #include "qdbusmessage_p.h" #include "qdbusutil_p.h" @@ -177,14 +178,25 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node // implement the D-Bus interface org.freedesktop.DBus.Properties -static QDBusMessage qDBusPropertyError(const QDBusMessage &msg, const QString &interface_name) +static inline QDBusMessage interfaceNotFoundError(const QDBusMessage &msg, const QString &interface_name) { - return msg.createErrorReply(QDBusError::InvalidArgs, + return msg.createErrorReply(QDBusError::UnknownInterface, QString::fromLatin1("Interface %1 was not found in object %2") .arg(interface_name) .arg(msg.path())); } +static inline QDBusMessage +propertyNotFoundError(const QDBusMessage &msg, const QString &interface_name, const QByteArray &property_name) +{ + return msg.createErrorReply(QDBusError::InvalidArgs, + QString::fromLatin1("Property %1%2%3 was not found in object %4") + .arg(interface_name, + QString::fromLatin1(interface_name.isEmpty() ? "" : "."), + QString::fromLatin1(property_name), + msg.path())); +} + QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg) { @@ -198,6 +210,7 @@ QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node QDBusAdaptorConnector *connector; QVariant value; + bool interfaceFound = false; if (node.flags & QDBusConnection::ExportAdaptors && (connector = qDBusFindAdaptorConnector(node.obj))) { @@ -217,31 +230,122 @@ QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node QDBusAdaptorConnector::AdaptorMap::ConstIterator it; it = qLowerBound(connector->adaptors.constBegin(), connector->adaptors.constEnd(), interface_name); - if (it != connector->adaptors.constEnd() && interface_name == QLatin1String(it->interface)) + if (it != connector->adaptors.constEnd() && interface_name == QLatin1String(it->interface)) { + interfaceFound = true; value = it->adaptor->property(property_name); + } } } - if (!value.isValid() && node.flags & (QDBusConnection::ExportAllProperties | - QDBusConnection::ExportNonScriptableProperties)) { + if (!interfaceFound && !value.isValid() + && node.flags & (QDBusConnection::ExportAllProperties | + QDBusConnection::ExportNonScriptableProperties)) { // try the object itself - int pidx = node.obj->metaObject()->indexOfProperty(property_name); - if (pidx != -1) { - QMetaProperty mp = node.obj->metaObject()->property(pidx); - if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || - (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) - value = mp.read(node.obj); + if (!interface_name.isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, interface_name); + + if (interfaceFound) { + int pidx = node.obj->metaObject()->indexOfProperty(property_name); + if (pidx != -1) { + QMetaProperty mp = node.obj->metaObject()->property(pidx); + if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || + (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) + value = mp.read(node.obj); + } } } if (!value.isValid()) { // the property was not found - return qDBusPropertyError(msg, interface_name); + if (!interfaceFound) + return interfaceNotFoundError(msg, interface_name); + return propertyNotFoundError(msg, interface_name, property_name); } return msg.createReply(qVariantFromValue(QDBusVariant(value))); } +enum PropertyWriteResult { + PropertyWriteSuccess = 0, + PropertyNotFound, + PropertyTypeMismatch, + PropertyWriteFailed +}; + +static QDBusMessage propertyWriteReply(const QDBusMessage &msg, const QString &interface_name, + const QByteArray &property_name, int status) +{ + switch (status) { + case PropertyNotFound: + return propertyNotFoundError(msg, interface_name, property_name); + case PropertyTypeMismatch: + return msg.createErrorReply(QDBusError::InvalidArgs, + QString::fromLatin1("Invalid arguments for writing to property %1%2%3") + .arg(interface_name, + QString::fromLatin1(interface_name.isEmpty() ? "" : "."), + QString::fromLatin1(property_name))); + case PropertyWriteFailed: + return msg.createErrorReply(QDBusError::InternalError, + QString::fromLatin1("Internal error")); + + case PropertyWriteSuccess: + return msg.createReply(); + } + Q_ASSERT_X(false, "", "Should not be reached"); + return QDBusMessage(); +} + +static int writeProperty(QObject *obj, const QByteArray &property_name, QVariant value, + int propFlags = QDBusConnection::ExportAllProperties) +{ + const QMetaObject *mo = obj->metaObject(); + int pidx = mo->indexOfProperty(property_name); + if (pidx == -1) { + // this object has no property by that name + return PropertyNotFound; + } + + QMetaProperty mp = mo->property(pidx); + + // check if this property is exported + bool isScriptable = mp.isScriptable(); + if (!(propFlags & QDBusConnection::ExportScriptableProperties) && isScriptable) + return PropertyNotFound; + if (!(propFlags & QDBusConnection::ExportNonScriptableProperties) && !isScriptable) + return PropertyNotFound; + + // we found our property + // do we have the right type? + int id = mp.type(); + if (id == QVariant::UserType) { + // dynamic type + id = qDBusNameToTypeId(mp.typeName()); + if (id == -1) { + // type not registered? + qWarning("QDBusConnection: Unable to handle unregistered datatype '%s' for property '%s::%s'", + mp.typeName(), mo->className(), property_name.constData()); + return PropertyWriteFailed; + } + } + + if (id != 0xff && value.userType() == QDBusMetaTypeId::argument) { + // we have to demarshall before writing + void *null = 0; + QVariant other(id, null); + if (!QDBusMetaType::demarshall(qVariantValue(value), id, other.data())) { + qWarning("QDBusConnection: type `%s' (%d) is not registered with QtDBus. " + "Use qDBusRegisterMetaType to register it", + mp.typeName(), id); + return PropertyWriteFailed; + } + + value = other; + } + + // the property type here should match + return mp.write(obj, value) ? PropertyWriteSuccess : PropertyWriteFailed; +} + QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg) { @@ -263,38 +367,39 @@ QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node if (interface_name.isEmpty()) { for (QDBusAdaptorConnector::AdaptorMap::ConstIterator it = connector->adaptors.constBegin(), end = connector->adaptors.constEnd(); it != end; ++it) { - const QMetaObject *mo = it->adaptor->metaObject(); - int pidx = mo->indexOfProperty(property_name); - if (pidx != -1) { - mo->property(pidx).write(it->adaptor, value); - return msg.createReply(); - } + int status = writeProperty(it->adaptor, property_name, value); + if (status == PropertyNotFound) + continue; + return propertyWriteReply(msg, interface_name, property_name, status); } } else { QDBusAdaptorConnector::AdaptorMap::ConstIterator it; it = qLowerBound(connector->adaptors.constBegin(), connector->adaptors.constEnd(), interface_name); - if (it != connector->adaptors.end() && interface_name == QLatin1String(it->interface)) - if (it->adaptor->setProperty(property_name, value)) - return msg.createReply(); + if (it != connector->adaptors.end() && interface_name == QLatin1String(it->interface)) { + return propertyWriteReply(msg, interface_name, property_name, + writeProperty(it->adaptor, property_name, value)); + } } } if (node.flags & (QDBusConnection::ExportScriptableProperties | QDBusConnection::ExportNonScriptableProperties)) { // try the object itself - int pidx = node.obj->metaObject()->indexOfProperty(property_name); - if (pidx != -1) { - QMetaProperty mp = node.obj->metaObject()->property(pidx); - if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || - (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) - if (mp.write(node.obj, value)) - return msg.createReply(); + bool interfaceFound = true; + if (!interface_name.isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, interface_name); + + if (interfaceFound) { + return propertyWriteReply(msg, interface_name, property_name, + writeProperty(node.obj, property_name, value, node.flags)); } } - // the property was not found or not written to - return qDBusPropertyError(msg, interface_name); + // the property was not found + if (!interface_name.isEmpty()) + return interfaceNotFoundError(msg, interface_name); + return propertyWriteReply(msg, interface_name, property_name, PropertyNotFound); } // unite two QVariantMaps, but don't generate duplicate keys @@ -385,7 +490,7 @@ QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &n if (!interfaceFound && !interface_name.isEmpty()) { // the interface was not found - return qDBusPropertyError(msg, interface_name); + return interfaceNotFoundError(msg, interface_name); } return msg.createReply(qVariantFromValue(result)); -- cgit v0.12 From a80d8f015f68cb2b6d5f4cc8b2893543122c5d2b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 16:16:57 +0200 Subject: Autotest: make sure we create the QDBusInterface after the object exists. The current code allows making calls to QDBusInterface objects that failed to introspect. It's technically a valid condition. You won't be able to connect to signals, get or set properties, but making calls was possible. I don't know if I want to keep this change in behaviour. --- .../tst_qdbusabstractadaptor.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp index c70c619..5d08c63 100644 --- a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp +++ b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp @@ -609,19 +609,22 @@ void tst_QDBusAbstractAdaptor::methodCalls() QVERIFY(con.isConnected()); //QDBusInterface emptycon.baseService(), "/", QString()); - QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); - QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); - QDBusInterface if3(con.baseService(), "/", "local.Interface3", con); - QDBusInterface if4(con.baseService(), "/", "local.Interface4", con); - // must fail: no object - //QCOMPARE(empty->call("method").type(), QDBusMessage::ErrorMessage); - QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + { + // must fail: no object + QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); + QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + } QFETCH(int, nInterfaces); MyObject obj(nInterfaces); con.registerObject("/", &obj); + QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); + QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); + QDBusInterface if3(con.baseService(), "/", "local.Interface3", con); + QDBusInterface if4(con.baseService(), "/", "local.Interface4", con); + // must fail: no such method QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); if (!nInterfaces--) @@ -670,11 +673,11 @@ void tst_QDBusAbstractAdaptor::methodCallScriptable() QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); - MyObject obj(2); con.registerObject("/", &obj); + QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); + QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage); QCOMPARE(slotSpy, "void Interface2::scriptableMethod()"); } -- cgit v0.12 From d675a1f752f6acb57c66082b9b25e1b8aa337f8a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:15:22 +0200 Subject: Autotest: add tests for method call errors --- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 105 ++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index 3ba789a..e304712 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -84,12 +84,17 @@ private slots: void sendArgument_data(); void sendArgument(); - void sendErrors(); + void sendSignalErrors(); + void sendCallErrors_data(); + void sendCallErrors(); private: QProcess proc; }; +struct UnregisteredType { }; +Q_DECLARE_METATYPE(UnregisteredType) + class WaitForQPong: public QObject { Q_OBJECT @@ -784,7 +789,7 @@ void tst_QDBusMarshall::sendArgument() QCOMPARE(extracted, value); } -void tst_QDBusMarshall::sendErrors() +void tst_QDBusMarshall::sendSignalErrors() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -819,5 +824,101 @@ void tst_QDBusMarshall::sendErrors() QVERIFY(!con.send(msg)); } +void tst_QDBusMarshall::sendCallErrors_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + QTest::addColumn("interface"); + QTest::addColumn("method"); + QTest::addColumn("arguments"); + QTest::addColumn("errorName"); + QTest::addColumn("errorMsg"); + QTest::addColumn("ignoreMsg"); + + // this error comes from the bus server + QTest::newRow("empty-service") << "" << objectPath << interfaceName << "ping" << QVariantList() + << "org.freedesktop.DBus.Error.UnknownMethod" + << "Method \"ping\" with signature \"\" on interface \"com.trolltech.autotests.qpong\" doesn't exist\n" << (const char*)0; + + QTest::newRow("invalid-service") << "this isn't valid" << objectPath << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidService" + << "Invalid service name: this isn't valid" << ""; + + QTest::newRow("empty-path") << serviceName << "" << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "Object path cannot be empty" << ""; + QTest::newRow("invalid-path") << serviceName << "//" << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "Invalid object path: //" << ""; + + // empty interfaces are valid + QTest::newRow("invalid-interface") << serviceName << objectPath << "this isn't valid" << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidInterface" + << "Invalid interface class: this isn't valid" << ""; + + QTest::newRow("empty-method") << serviceName << objectPath << interfaceName << "" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidMember" + << "method name cannot be empty" << ""; + QTest::newRow("invalid-method") << serviceName << objectPath << interfaceName << "this isn't valid" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidMember" + << "Invalid method name: this isn't valid" << ""; + + QTest::newRow("invalid-variant1") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << QVariant()) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Variant containing QVariant::Invalid passed in arguments" + << "QDBusMarshaller: cannot add an invalid QVariant"; + QTest::newRow("invalid-variant1") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusVariant())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Variant containing QVariant::Invalid passed in arguments" + << "QDBusMarshaller: cannot add a null QDBusVariant"; + + QTest::newRow("builtin-unregistered") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << QLocale::c()) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Unregistered type QLocale passed in arguments" + << "QDBusMarshaller: type `QLocale' (18) is not registered with D-BUS. Use qDBusRegisterMetaType to register it"; + + // this type is known to the meta type system, but not registered with D-Bus + qRegisterMetaType(); + QTest::newRow("extra-unregistered") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(UnregisteredType())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Unregistered type UnregisteredType passed in arguments" + << QString("QDBusMarshaller: type `UnregisteredType' (%1) is not registered with D-BUS. Use qDBusRegisterMetaType to register it") + .arg(qMetaTypeId()); +} + +void tst_QDBusMarshall::sendCallErrors() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QFETCH(QString, service); + QFETCH(QString, path); + QFETCH(QString, interface); + QFETCH(QString, method); + QFETCH(QVariantList, arguments); + QFETCH(QString, errorMsg); + + QFETCH(QString, ignoreMsg); + if (!ignoreMsg.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, ignoreMsg.toLatin1()); + if (!ignoreMsg.isNull()) + QTest::ignoreMessage(QtWarningMsg, + QString("QDBusConnection: error: could not send message to service \"%1\" path \"%2\" interface \"%3\" member \"%4\": %5") + .arg(service, path, interface, method, errorMsg) + .toLatin1()); + + QDBusMessage msg = QDBusMessage::createMethodCall(service, path, interface, method); + msg.setArguments(arguments); + + QDBusMessage reply = con.call(msg, QDBus::Block); + QCOMPARE(reply.type(), QDBusMessage::ErrorMessage); + QTEST(reply.errorName(), "errorName"); + QCOMPARE(reply.errorMessage(), errorMsg); +} + QTEST_MAIN(tst_QDBusMarshall) #include "tst_qdbusmarshall.moc" -- cgit v0.12 From 202167643206bbfb50cce605fdfbd4cfef843bad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 16:21:44 +0200 Subject: Autotest: Add testing of QDBusAbstractInterface --- tests/auto/auto.pro | 1 + .../com.trolltech.QtDBus.Pinger.xml | 29 ++ tests/auto/qdbusabstractinterface/interface.cpp | 48 ++ tests/auto/qdbusabstractinterface/interface.h | 109 +++++ tests/auto/qdbusabstractinterface/pinger.cpp | 67 +++ tests/auto/qdbusabstractinterface/pinger.h | 139 ++++++ .../qdbusabstractinterface.pro | 15 + .../tst_qdbusabstractinterface.cpp | 529 +++++++++++++++++++++ 8 files changed, 937 insertions(+) create mode 100644 tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml create mode 100644 tests/auto/qdbusabstractinterface/interface.cpp create mode 100644 tests/auto/qdbusabstractinterface/interface.h create mode 100644 tests/auto/qdbusabstractinterface/pinger.cpp create mode 100644 tests/auto/qdbusabstractinterface/pinger.h create mode 100644 tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro create mode 100644 tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index fd887fd..8bc2ed9 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -419,6 +419,7 @@ xmlpatternsxslts.depends = xmlpatternsxqts unix:!embedded:contains(QT_CONFIG, dbus):SUBDIRS += \ qdbusabstractadaptor \ + qdbusabstractinterface \ qdbusconnection \ qdbusinterface \ qdbuslocalcalls \ diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml new file mode 100644 index 0000000..8909675 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/qdbusabstractinterface/interface.cpp b/tests/auto/qdbusabstractinterface/interface.cpp new file mode 100644 index 0000000..1c391ce --- /dev/null +++ b/tests/auto/qdbusabstractinterface/interface.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "interface.h" + +Interface::Interface() +{ +} + +#include "moc_interface.cpp" diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h new file mode 100644 index 0000000..86e0dc4 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/interface.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INTERFACE_H +#define INTERFACE_H + +#include +#include + +struct RegisteredType +{ + inline RegisteredType(const QString &str = QString()) : s(str) {} + inline bool operator==(const RegisteredType &other) const { return s == other.s; } + QString s; +}; +Q_DECLARE_METATYPE(RegisteredType) + +inline QDBusArgument &operator<<(QDBusArgument &s, const RegisteredType &data) +{ + s.beginStructure(); + s << data.s; + s.endStructure(); + return s; +} + +inline const QDBusArgument &operator>>(const QDBusArgument &s, RegisteredType &data) +{ + s.beginStructure(); + s >> data.s; + s.endStructure(); + return s; +} + +struct UnregisteredType +{ + QString s; +}; +Q_DECLARE_METATYPE(UnregisteredType) + +class Interface: public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.Pinger") + Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp SCRIPTABLE true) + Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) + + friend class tst_QDBusAbstractInterface; + QString m_stringProp; + RegisteredType m_complexProp; + +public: + Interface(); + + QString stringProp() const { return m_stringProp; } + void setStringProp(const QString &s) { m_stringProp = s; } + RegisteredType complexProp() const { return m_complexProp; } + void setComplexProp(const RegisteredType &r) { m_complexProp = r; } + +public slots: + Q_SCRIPTABLE void voidMethod() {} + Q_SCRIPTABLE QString stringMethod() { return "Hello, world"; } + Q_SCRIPTABLE RegisteredType complexMethod() { return RegisteredType("Hello, world"); } + Q_SCRIPTABLE QString multiOutMethod(int &value) { value = 42; return "Hello, world"; } + +signals: + Q_SCRIPTABLE void voidSignal(); + Q_SCRIPTABLE void stringSignal(const QString &); + Q_SCRIPTABLE void complexSignal(RegisteredType); +}; + +#endif // INTERFACE_H diff --git a/tests/auto/qdbusabstractinterface/pinger.cpp b/tests/auto/qdbusabstractinterface/pinger.cpp new file mode 100644 index 0000000..4fcb89a --- /dev/null +++ b/tests/auto/qdbusabstractinterface/pinger.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "pinger.h" + +/* + * Implementation of interface class ComTrolltechQtDBusPingerInterface + */ + +ComTrolltechQtDBusPingerInterface::ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +ComTrolltechQtDBusPingerInterface::~ComTrolltechQtDBusPingerInterface() +{ +} + diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h new file mode 100644 index 0000000..3ff218c --- /dev/null +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef PINGER_H_1246371899 +#define PINGER_H_1246371899 + +#include +#include +#include +#include +#include +#include +#include +#include +#include "interface.h" + +/* + * Proxy class for interface com.trolltech.QtDBus.Pinger + */ +class ComTrolltechQtDBusPingerInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.trolltech.QtDBus.Pinger"; } + +public: + ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~ComTrolltechQtDBusPingerInterface(); + + Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp) + inline RegisteredType complexProp() const + { return qvariant_cast< RegisteredType >(internalPropGet("complexProp")); } + inline void setComplexProp(RegisteredType value) + { internalPropSet("complexProp", qVariantFromValue(value)); } + + Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp) + inline QString stringProp() const + { return qvariant_cast< QString >(internalPropGet("stringProp")); } + inline void setStringProp(const QString &value) + { internalPropSet("stringProp", qVariantFromValue(value)); } + +public Q_SLOTS: // METHODS + inline QDBusPendingReply complexMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("complexMethod"), argumentList); + } + + inline QDBusPendingReply multiOutMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("multiOutMethod"), argumentList); + } + inline QDBusReply multiOutMethod(int &out1) + { + QList argumentList; + QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("multiOutMethod"), argumentList); + if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) { + out1 = qdbus_cast(reply.arguments().at(1)); + } + return reply; + } + + inline QDBusPendingReply stringMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("stringMethod"), argumentList); + } + + inline QDBusPendingReply<> voidMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("voidMethod"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void complexSignal(RegisteredType in0); + void stringSignal(const QString &in0); + void voidSignal(); +}; + +namespace com { + namespace trolltech { + namespace QtDBus { + typedef ::ComTrolltechQtDBusPingerInterface Pinger; + } + } +} +#endif diff --git a/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro new file mode 100644 index 0000000..a4853b8 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro @@ -0,0 +1,15 @@ +load(qttest_p4) +QT = core +contains(QT_CONFIG,dbus): { + SOURCES += tst_qdbusabstractinterface.cpp interface.cpp + HEADERS += interface.h + QT += dbus + + # These are generated sources + # To regenerate, see the command-line at the top of the files + SOURCES += pinger.cpp + HEADERS += pinger.h +} +else:SOURCES += ../qdbusmarshall/dummy.cpp + +OTHER_FILES += com.trolltech.QtDBus.Pinger.xml diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp new file mode 100644 index 0000000..4aee089 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -0,0 +1,529 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include + +#include + +#include + +#include "interface.h" +#include "pinger.h" + +typedef QSharedPointer Pinger; + +class tst_QDBusAbstractInterface: public QObject +{ + Q_OBJECT + Interface targetObj; + + Pinger getPinger(QString service = "", const QString &path = "/") + { + QDBusConnection con = QDBusConnection::sessionBus(); + if (!con.isConnected()) + return Pinger(); + if (service.isEmpty() && !service.isNull()) + service = con.baseService(); + return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con)); + } + +public: + tst_QDBusAbstractInterface(); + +private slots: + void initTestCase(); + + void makeVoidCall(); + void makeStringCall(); + void makeComplexCall(); + void makeMultiOutCall(); + + void makeAsyncVoidCall(); + void makeAsyncStringCall(); + void makeAsyncComplexCall(); + void makeAsyncMultiOutCall(); + + void stringPropRead(); + void stringPropWrite(); + void complexPropRead(); + void complexPropWrite(); + + void stringPropDirectRead(); + void stringPropDirectWrite(); + void complexPropDirectRead(); + void complexPropDirectWrite(); + + void getVoidSignal_data(); + void getVoidSignal(); + void getStringSignal_data(); + void getStringSignal(); + void getComplexSignal_data(); + void getComplexSignal(); + + void createErrors_data(); + void createErrors(); + + void callErrors_data(); + void callErrors(); + void asyncCallErrors_data(); + void asyncCallErrors(); + + void propertyReadErrors_data(); + void propertyReadErrors(); + void propertyWriteErrors_data(); + void propertyWriteErrors(); + void directPropertyReadErrors_data(); + void directPropertyReadErrors(); + void directPropertyWriteErrors_data(); + void directPropertyWriteErrors(); +}; + +tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() +{ + // register the meta types + qDBusRegisterMetaType(); + qRegisterMetaType(); +} + +void tst_QDBusAbstractInterface::initTestCase() +{ + // register the object + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + con.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents); +} + +void tst_QDBusAbstractInterface::makeVoidCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->voidMethod(); + QVERIFY(r.isValid()); +} + +void tst_QDBusAbstractInterface::makeStringCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->stringMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeComplexCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->complexMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeMultiOutCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + int value; + QDBusReply r = p->multiOutMethod(value); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(value, expectedValue); +} + +void tst_QDBusAbstractInterface::makeAsyncVoidCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->voidMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); +} + +void tst_QDBusAbstractInterface::makeAsyncStringCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->stringMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncComplexCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->complexMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncMultiOutCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->multiOutMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(r.argumentAt<1>(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = targetObj.m_stringProp = "This is a test"; + QVariant v = p->property("stringProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = "This is a value"; + QVERIFY(p->setProperty("stringProp", expectedValue)); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); + QVariant v = p->property("complexProp"); + QVERIFY(v.userType() == qMetaTypeId()); + QCOMPARE(v.value(), targetObj.m_complexProp); +} + +void tst_QDBusAbstractInterface::complexPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = RegisteredType("This is a value"); + QVERIFY(p->setProperty("complexProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = targetObj.m_stringProp = "This is a test"; + QCOMPARE(p->stringProp(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = "This is a value"; + p->setStringProp(expectedValue); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); + QCOMPARE(p->complexProp(), targetObj.m_complexProp); +} + +void tst_QDBusAbstractInterface::complexPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = RegisteredType("This is a value"); + p->setComplexProp(expectedValue); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + +void tst_QDBusAbstractInterface::getVoidSignal_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + + QTest::newRow("specific") << QDBusConnection::sessionBus().baseService() << "/"; + QTest::newRow("service-wildcard") << QString() << "/"; + QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString(); + QTest::newRow("full-wildcard") << QString() << QString(); +} + +void tst_QDBusAbstractInterface::getVoidSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(voidSignal())); + + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s.at(0).size() == 0); +} + +void tst_QDBusAbstractInterface::getStringSignal_data() +{ + getVoidSignal_data(); +} + +void tst_QDBusAbstractInterface::getStringSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(stringSignal(QString)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(stringSignal(QString))); + + QString expectedValue = "Good morning"; + emit targetObj.stringSignal(expectedValue); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), int(QVariant::String)); + QCOMPARE(s[0][0].toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::getComplexSignal_data() +{ + getVoidSignal_data(); +} + +void tst_QDBusAbstractInterface::getComplexSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(complexSignal(RegisteredType)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(complexSignal(RegisteredType))); + + RegisteredType expectedValue("Good evening"); + emit targetObj.complexSignal(expectedValue); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), qMetaTypeId()); + QCOMPARE(s[0][0].value(), expectedValue); +} + +void tst_QDBusAbstractInterface::createErrors_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + QTest::addColumn("errorName"); + + QTest::newRow("invalid-service") << "this isn't valid" << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("invalid-path") << QDBusConnection::sessionBus().baseService() << "this isn't valid" + << "com.trolltech.QtDBus.Error.InvalidObjectPath"; +} + +void tst_QDBusAbstractInterface::createErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + QVERIFY(!p->isValid()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::callErrors_data() +{ + createErrors_data(); + QTest::newRow("service-wildcard") << QString() << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString() + << "com.trolltech.QtDBus.Error.InvalidObjectPath"; + QTest::newRow("full-wildcard") << QString() << QString() << "com.trolltech.QtDBus.Error.InvalidService"; +} + +void tst_QDBusAbstractInterface::callErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusReply r = p->stringMethod(); + QVERIFY(!r.isValid()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + +void tst_QDBusAbstractInterface::asyncCallErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::asyncCallErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusPendingReply r = p->stringMethod(); + QVERIFY(r.isError()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + +void tst_QDBusAbstractInterface::propertyReadErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::propertyReadErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QVariant v = p->property("stringProp"); + QVERIFY(v.isNull()); + QVERIFY(!v.isValid()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::propertyWriteErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::propertyWriteErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + QVERIFY(!p->setProperty("stringProp", "")); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QString v = p->stringProp(); + QVERIFY(v.isNull()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + // but there's no direct way of verifying that the setting failed + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + p->setStringProp(""); + QTEST(p->lastError().name(), "errorName"); +} + +QTEST_MAIN(tst_QDBusAbstractInterface) +#include "tst_qdbusabstractinterface.moc" -- cgit v0.12 From 826c03c1c010a9d612007aa85ce3a5188edb0cb8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 19:27:16 +0200 Subject: Autotest: Add property-setting and getting tests to QDBusInterface --- tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 102 ++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index c4d4b08..718ba18 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -60,6 +60,9 @@ class MyObject: public QObject Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" @@ -75,6 +78,9 @@ class MyObject: public QObject " \n" " \n" "") + Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) + Q_PROPERTY(QList complexProp READ complexProp WRITE setComplexProp) + public: static int callCount; static QVariantList callArgs; @@ -84,6 +90,30 @@ public: subObject->setObjectName("subObject"); } + int m_prop1; + int prop1() const + { + ++callCount; + return m_prop1; + } + void setProp1(int value) + { + ++callCount; + m_prop1 = value; + } + + QList m_complexProp; + QList complexProp() const + { + ++callCount; + return m_complexProp; + } + void setComplexProp(const QList &value) + { + ++callCount; + m_complexProp = value; + } + public slots: void ping(QDBusMessage msg) @@ -146,6 +176,11 @@ private slots: void invokeMethod(); void signal(); + + void propertyRead(); + void propertyWrite(); + void complexPropertyRead(); + void complexPropertyWrite(); }; void tst_QDBusInterface::initTestCase() @@ -154,7 +189,7 @@ void tst_QDBusInterface::initTestCase() QVERIFY(con.isConnected()); QTest::qWait(500); - con.registerObject("/", &obj, QDBusConnection::ExportAdaptors + con.registerObject("/", &obj, QDBusConnection::ExportAllProperties | QDBusConnection::ExportAllSlots | QDBusConnection::ExportChildObjects); } @@ -231,8 +266,9 @@ void tst_QDBusInterface::introspect() QCOMPARE(mo->methodCount() - mo->methodOffset(), 3); QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1); - QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 1); + QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2); QVERIFY(mo->indexOfProperty("prop1") != -1); + QVERIFY(mo->indexOfProperty("complexProp") != -1); } void tst_QDBusInterface::callMethod() @@ -322,6 +358,68 @@ void tst_QDBusInterface::signal() } } +void tst_QDBusInterface::propertyRead() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + int arg = obj.m_prop1 = 42; + MyObject::callCount = 0; + + QVariant v = iface.property("prop1"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), int(QVariant::Int)); + QCOMPARE(v.toInt(), arg); + QCOMPARE(MyObject::callCount, 1); +} + +void tst_QDBusInterface::propertyWrite() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + int arg = 42; + obj.m_prop1 = 0; + MyObject::callCount = 0; + + QVERIFY(iface.setProperty("prop1", arg)); + QCOMPARE(MyObject::callCount, 1); + QCOMPARE(obj.m_prop1, arg); +} + +void tst_QDBusInterface::complexPropertyRead() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + QList arg = obj.m_complexProp = QList() << 42 << -47; + MyObject::callCount = 0; + + QVariant v = iface.property("complexProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), qMetaTypeId >()); + QCOMPARE(v.value >(), arg); + QCOMPARE(MyObject::callCount, 1); +} + +void tst_QDBusInterface::complexPropertyWrite() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + QList arg = QList() << -47 << 42; + obj.m_complexProp.clear(); + MyObject::callCount = 0; + + QVERIFY(iface.setProperty("complexProp", qVariantFromValue(arg))); + QCOMPARE(MyObject::callCount, 1); + QCOMPARE(obj.m_complexProp, arg); +} + QTEST_MAIN(tst_QDBusInterface) #include "tst_qdbusinterface.moc" -- cgit v0.12 From 962b7fde5194a08a83609b9b4367425e52f76614 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:44:56 +0200 Subject: Improve the code a bit more by using the variant that QMetaProperty creates. This works for the case of complex types that have to be demarshalled. We don't need to instantiate a new type because QMetaProperty has already done that for us. Also, fix the handling of properties of type variant. I have verified as well that the sending of those properties on the wire use a double-variant encoding (i.e., a variant containing a variant containing some data, the same that Qt 4.5 uses). It's a bit pedantic and it's hard to use when reading stuff, because you get a QVariant containing a QDBusVariant which contains data, but I can't change this anymore. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 70 +++++++++++++++---------------------- src/dbus/qdbusabstractinterface_p.h | 2 +- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 9bef2dd..7c520df 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -110,21 +110,17 @@ bool QDBusAbstractInterfacePrivate::canMakeCalls() const return true; } -QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const +void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const { - if (!isValid || !canMakeCalls()) // can't make calls - return QVariant(); + if (!isValid || !canMakeCalls()) { // can't make calls + where.clear(); + return; + } // is this metatype registered? - int mid; - const char *expectedSignature; - if (mp.type() == QVariant::LastType) { - // We're asking to read a QVariant - mid = qMetaTypeId(); - expectedSignature = "v"; - } else { - mid = QMetaType::type(mp.typeName()); - expectedSignature = QDBusMetaType::typeToSignature(mid); + const char *expectedSignature = ""; + if (mp.type() != 0xff) { + expectedSignature = QDBusMetaType::typeToSignature(where.userType()); if (expectedSignature == 0) { qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", @@ -132,7 +128,8 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const lastError = QDBusError(QDBusError::Failed, QString::fromLatin1("Unregistered type %1 cannot be handled") .arg(QLatin1String(mp.typeName()))); - return QVariant(); + where.clear(); + return; } } @@ -146,21 +143,27 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; - return QVariant(); + where.clear(); + return; } if (reply.signature() != QLatin1String("v")) { QString errmsg = QLatin1String("Invalid signature `%1' in return from call to " DBUS_INTERFACE_PROPERTIES); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature())); - return QVariant(); + where.clear(); + return; } QByteArray foundSignature; const char *foundType = 0; QVariant value = qvariant_cast(reply.arguments().at(0)).variant(); - if (value.userType() == mid) - return value; // simple match + if (value.userType() == where.userType() || mp.type() == 0xff + || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) { + // simple match + where = value; + return; + } if (value.userType() == qMetaTypeId()) { QDBusArgument arg = qvariant_cast(value); @@ -168,14 +171,9 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const foundType = "user type"; foundSignature = arg.currentSignature().toLatin1(); if (foundSignature == expectedSignature) { - void *null = 0; - QVariant result(mid, null); - QDBusMetaType::demarshall(arg, mid, result.data()); - - if (mp.type() == QVariant::LastType) - // special case: QVariant - return qvariant_cast(result).variant(); - return result; + // signatures match, we can demarshall + QDBusMetaType::demarshall(arg, where.userType(), where.data()); + return; } } else { foundType = value.typeName(); @@ -192,7 +190,8 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const QString::fromUtf8(mp.name()), QString::fromLatin1(mp.typeName()), QString::fromLatin1(expectedSignature))); - return QVariant(); + where.clear(); + return; } bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) @@ -246,7 +245,7 @@ int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void if (_c == QMetaObject::WriteProperty) { status = d_func()->setProperty(mp, variant) ? 1 : 0; } else { - variant = d_func()->property(mp); + d_func()->property(mp, variant); status = variant.isValid() ? 1 : 0; } _id = -1; @@ -576,11 +575,7 @@ QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const // assume this property exists and is readable // we're only called from generated code anyways - int idx = metaObject()->indexOfProperty(propname); - if (idx != -1) - return d_func()->property(metaObject()->property(idx)); - qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname); - return QVariant(); // error + return property(propname); } /*! @@ -589,16 +584,7 @@ QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const */ void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value) { - Q_D(QDBusAbstractInterface); - - // assume this property exists and is writeable - // we're only called from generated code anyways - - int idx = metaObject()->indexOfProperty(propname); - if (idx != -1) - d->setProperty(metaObject()->property(idx), value); - else - qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname); + setProperty(propname, value); } /*! diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e577898..65df902 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -86,7 +86,7 @@ public: bool canMakeCalls() const; // these functions do not check if the property is valid - QVariant property(const QMetaProperty &mp) const; + void property(const QMetaProperty &mp, QVariant &where) const; bool setProperty(const QMetaProperty &mp, const QVariant &value); // return conn's d pointer -- cgit v0.12 From 43a760280edd49382d01eb1e23ae2a08933b6bf7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:45:17 +0200 Subject: Autotest: add tests for checking variant properties --- .../com.trolltech.QtDBus.Pinger.xml | 1 + tests/auto/qdbusabstractinterface/interface.h | 4 ++ tests/auto/qdbusabstractinterface/pinger.h | 10 ++++- .../tst_qdbusabstractinterface.cpp | 47 ++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml index 8909675..fb2aab8 100644 --- a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml +++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml @@ -2,6 +2,7 @@ + diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h index 86e0dc4..f6d34a7 100644 --- a/tests/auto/qdbusabstractinterface/interface.h +++ b/tests/auto/qdbusabstractinterface/interface.h @@ -80,10 +80,12 @@ class Interface: public QObject Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.Pinger") Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp SCRIPTABLE true) + Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp SCRIPTABLE true) Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) friend class tst_QDBusAbstractInterface; QString m_stringProp; + QDBusVariant m_variantProp; RegisteredType m_complexProp; public: @@ -91,6 +93,8 @@ public: QString stringProp() const { return m_stringProp; } void setStringProp(const QString &s) { m_stringProp = s; } + QDBusVariant variantProp() const { return m_variantProp; } + void setVariantProp(const QDBusVariant &v) { m_variantProp = v; } RegisteredType complexProp() const { return m_complexProp; } void setComplexProp(const RegisteredType &r) { m_complexProp = r; } diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h index 3ff218c..6e92e65 100644 --- a/tests/auto/qdbusabstractinterface/pinger.h +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -49,8 +49,8 @@ * Do not edit! All changes made to it will be lost. */ -#ifndef PINGER_H_1246371899 -#define PINGER_H_1246371899 +#ifndef PINGER_H_1246460303 +#define PINGER_H_1246460303 #include #include @@ -89,6 +89,12 @@ public: inline void setStringProp(const QString &value) { internalPropSet("stringProp", qVariantFromValue(value)); } + Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp) + inline QDBusVariant variantProp() const + { return qvariant_cast< QDBusVariant >(internalPropGet("variantProp")); } + inline void setVariantProp(const QDBusVariant &value) + { internalPropSet("variantProp", qVariantFromValue(value)); } + public Q_SLOTS: // METHODS inline QDBusPendingReply complexMethod() { diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 4aee089..fa5e332 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -84,11 +84,15 @@ private slots: void stringPropRead(); void stringPropWrite(); + void variantPropRead(); + void variantPropWrite(); void complexPropRead(); void complexPropWrite(); void stringPropDirectRead(); void stringPropDirectWrite(); + void variantPropDirectRead(); + void variantPropDirectWrite(); void complexPropDirectRead(); void complexPropDirectWrite(); @@ -242,6 +246,29 @@ void tst_QDBusAbstractInterface::stringPropWrite() QCOMPARE(targetObj.m_stringProp, expectedValue); } +void tst_QDBusAbstractInterface::variantPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(QVariant(42)); + QVariant v = p->property("variantProp"); + QVERIFY(v.isValid()); + QDBusVariant value = v.value(); + QCOMPARE(value.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(value.variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + QVERIFY(p->setProperty("variantProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + void tst_QDBusAbstractInterface::complexPropRead() { Pinger p = getPinger(); @@ -282,6 +309,26 @@ void tst_QDBusAbstractInterface::stringPropDirectWrite() QCOMPARE(targetObj.m_stringProp, expectedValue); } +void tst_QDBusAbstractInterface::variantPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(42); + QCOMPARE(p->variantProp().variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + p->setVariantProp(expectedValue); + QCOMPARE(targetObj.m_variantProp.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + void tst_QDBusAbstractInterface::complexPropDirectRead() { Pinger p = getPinger(); -- cgit v0.12 From 232f7af78d152518ccdcaaf1f42f89abb048ae5f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:52:48 +0200 Subject: Replace internalPropGet and internalPropSet with the QObject versions in QDBusAbstractInterface. They're now good enough and as fast. Reviewed-By: Marius Bugge Monsen --- tests/auto/qdbusabstractinterface/pinger.h | 16 ++++++++-------- tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp | 11 ++++------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h index 6e92e65..fb8adda 100644 --- a/tests/auto/qdbusabstractinterface/pinger.h +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -49,8 +49,8 @@ * Do not edit! All changes made to it will be lost. */ -#ifndef PINGER_H_1246460303 -#define PINGER_H_1246460303 +#ifndef PINGER_H_1246463415 +#define PINGER_H_1246463415 #include #include @@ -79,21 +79,21 @@ public: Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp) inline RegisteredType complexProp() const - { return qvariant_cast< RegisteredType >(internalPropGet("complexProp")); } + { return qvariant_cast< RegisteredType >(property("complexProp")); } inline void setComplexProp(RegisteredType value) - { internalPropSet("complexProp", qVariantFromValue(value)); } + { setProperty("complexProp", qVariantFromValue(value)); } Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp) inline QString stringProp() const - { return qvariant_cast< QString >(internalPropGet("stringProp")); } + { return qvariant_cast< QString >(property("stringProp")); } inline void setStringProp(const QString &value) - { internalPropSet("stringProp", qVariantFromValue(value)); } + { setProperty("stringProp", qVariantFromValue(value)); } Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp) inline QDBusVariant variantProp() const - { return qvariant_cast< QDBusVariant >(internalPropGet("variantProp")); } + { return qvariant_cast< QDBusVariant >(property("variantProp")); } inline void setVariantProp(const QDBusVariant &value) - { internalPropSet("variantProp", qVariantFromValue(value)); } + { setProperty("variantProp", qVariantFromValue(value)); } public Q_SLOTS: // METHODS inline QDBusPendingReply complexMethod() diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp index 5d1ac32..b8b9338 100644 --- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -613,18 +613,15 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf // getter: if (property.access != QDBusIntrospection::Property::Write) { - hs << " inline " << type << " " << getter << "() const" << endl; - if (type != "QVariant") - hs << " { return qvariant_cast< " << type << " >(internalPropGet(\"" - << property.name << "\")); }" << endl; - else - hs << " { return internalPropGet(\"" << property.name << "\"); }" << endl; + hs << " inline " << type << " " << getter << "() const" << endl + << " { return qvariant_cast< " << type << " >(property(\"" + << property.name << "\")); }" << endl; } // setter: if (property.access != QDBusIntrospection::Property::Read) { hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl - << " { internalPropSet(\"" << property.name + << " { setProperty(\"" << property.name << "\", qVariantFromValue(value)); }" << endl; } -- cgit v0.12 From 200286b8e83918e785b61e4695443a3b77ebeaea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 18:24:56 +0200 Subject: Implement a support for getting return arguments out of invokeMethod with QDBusInterface. The problem was that I didn't know how to implement the operator= for all types. But it turns out that this was possible all along: the only types I have to implement the operator= for are the basic types, which are already demarshalled. The complex types are left in QDBusArgument semi-demarshalling, but we have QDBusMetaType::demarshall, which takes a void* to an already-constructed type and demarshalls into it. That's exactly what the doctor ordered. Task-number: 206765 Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusinterface.cpp | 126 +++++++++++++++++++++-- tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 92 ++++++++++++++++- 2 files changed, 209 insertions(+), 9 deletions(-) diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index 6f61847..5f6df0a 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -51,6 +51,102 @@ QT_BEGIN_NAMESPACE +static void copyArgument(void *to, int id, const QVariant &arg) +{ + if (id == arg.userType()) { + switch (id) { + case QVariant::Bool: + *reinterpret_cast(to) = arg.toBool(); + return; + + case QMetaType::UChar: + *reinterpret_cast(to) = arg.value(); + return; + + case QMetaType::Short: + *reinterpret_cast(to) = arg.value(); + return; + + case QMetaType::UShort: + *reinterpret_cast(to) = arg.value(); + return; + + case QVariant::Int: + *reinterpret_cast(to) = arg.toInt(); + return; + + case QVariant::UInt: + *reinterpret_cast(to) = arg.toUInt(); + return; + + case QVariant::LongLong: + *reinterpret_cast(to) = arg.toLongLong(); + return; + + case QVariant::ULongLong: + *reinterpret_cast(to) = arg.toULongLong(); + return; + + case QVariant::Double: + *reinterpret_cast(to) = arg.toDouble(); + return; + + case QVariant::String: + *reinterpret_cast(to) = arg.toString(); + return; + + case QVariant::ByteArray: + *reinterpret_cast(to) = arg.toByteArray(); + return; + + case QVariant::StringList: + *reinterpret_cast(to) = arg.toStringList(); + return; + } + + if (id == QDBusMetaTypeId::variant) { + *reinterpret_cast(to) = arg.value(); + return; + } else if (id == QDBusMetaTypeId::objectpath) { + *reinterpret_cast(to) = arg.value(); + return; + } else if (id == QDBusMetaTypeId::signature) { + *reinterpret_cast(to) = arg.value(); + return; + } + + // those above are the only types possible + // the demarshaller code doesn't demarshall anything else + qFatal("Found a decoded basic type in a D-Bus reply that shouldn't be there"); + } + + // if we got here, it's either an un-dermarshalled type or a mismatch + if (arg.userType() != QDBusMetaTypeId::argument) { + // it's a mismatch + //qWarning? + return; + } + + // is this type registered? + const char *userSignature = QDBusMetaType::typeToSignature(id); + if (!userSignature || !*userSignature) { + // type not registered + //qWarning? + return; + } + + // is it the same signature? + QDBusArgument dbarg = arg.value(); + if (dbarg.currentSignature() != QLatin1String(userSignature)) { + // not the same signature, another mismatch + //qWarning? + return; + } + + // we can demarshall + QDBusMetaType::demarshall(dbarg, id, to); +} + QDBusInterfacePrivate::QDBusInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection &con) : QDBusAbstractInterfacePrivate(serv, p, iface, con, true), metaObject(0) @@ -186,23 +282,37 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) // we will assume that the input arguments were passed correctly QVariantList args; - for (int i = 1; i <= inputTypesCount; ++i) + int i = 1; + for ( ; i <= inputTypesCount; ++i) args << QVariant(inputTypes[i], argv[i]); // make the call - QPointer qq = q; QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args); - args.clear(); - // we ignore return values + if (reply.type() == QDBusMessage::ReplyMessage) { + // attempt to demarshall the return values + args = reply.arguments(); + QVariantList::ConstIterator it = args.constBegin(); + const int *outputTypes = metaObject->outputTypesForMethod(id); + int outputTypesCount = *outputTypes++; + + if (*mm.typeName()) { + // this method has a return type + if (argv[0] && it != args.constEnd()) + copyArgument(argv[0], *outputTypes++, *it); - // access to "this" or to "q" below this point must check for "qq" - // we may have been deleted! + // skip this argument even if we didn't copy it + --outputTypesCount; + ++it; + } - if (!qq.isNull()) - lastError = reply; + for (int j = 0; j < outputTypesCount && it != args.constEnd(); ++i, ++j, ++it) { + copyArgument(argv[i], outputTypes[j], *it); + } + } // done + lastError = reply; return -1; } } diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index 718ba18..60afe4e 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -76,6 +76,12 @@ class MyObject: public QObject " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "") Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) @@ -174,6 +180,9 @@ private slots: void introspect(); void callMethod(); void invokeMethod(); + void invokeMethodWithReturn(); + void invokeMethodWithMultiReturn(); + void invokeMethodWithComplexReturn(); void signal(); @@ -263,7 +272,7 @@ void tst_QDBusInterface::introspect() const QMetaObject *mo = iface.metaObject(); - QCOMPARE(mo->methodCount() - mo->methodOffset(), 3); + QCOMPARE(mo->methodCount() - mo->methodOffset(), 4); QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1); QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2); @@ -317,6 +326,87 @@ void tst_QDBusInterface::invokeMethod() QCOMPARE(dv.variant().toString(), QString("foo")); } +void tst_QDBusInterface::invokeMethodWithReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QDBusVariant arg("foo"); + QDBusVariant retArg; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 1); + QVariant v = MyObject::callArgs.at(0); + QDBusVariant dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + // verify that we got the reply as expected + QCOMPARE(retArg.variant(), arg.variant()); +} + +void tst_QDBusInterface::invokeMethodWithMultiReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QDBusVariant arg("foo"), arg2("bar"); + QDBusVariant retArg, retArg2; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", + Q_RETURN_ARG(QDBusVariant, retArg), + Q_ARG(QDBusVariant, arg), + Q_ARG(QDBusVariant, arg2), + Q_ARG(QDBusVariant&, retArg2))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 2); + QVariant v = MyObject::callArgs.at(0); + QDBusVariant dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + v = MyObject::callArgs.at(1); + dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg2.variant().toString()); + + // verify that we got the replies as expected + QCOMPARE(retArg.variant(), arg.variant()); + QCOMPARE(retArg2.variant(), arg2.variant()); +} + +void tst_QDBusInterface::invokeMethodWithComplexReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QList arg = QList() << 42 << -47; + QList retArg; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList, retArg), Q_ARG(QList, arg))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 1); + QVariant v = MyObject::callArgs.at(0); + QCOMPARE(v.userType(), qMetaTypeId()); + QCOMPARE(qdbus_cast >(v), arg); + + // verify that we got the reply as expected + QCOMPARE(retArg, arg); +} + void tst_QDBusInterface::signal() { QDBusConnection con = QDBusConnection::sessionBus(); -- cgit v0.12 From 9a90dab23bd1bd37bd4a7aace588896d2ae7e9d9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 1 Jul 2009 10:53:23 +0200 Subject: add support for attaching meta data to translatable messages Requirement: QT-457 --- .../snippets/code/src_corelib_kernel_qobject.cpp | 9 ++++++ src/corelib/kernel/qobject.cpp | 28 +++++++++++++++++ .../lupdate/testdata/good/parsecpp/main.cpp | 19 ++++++++++++ .../testdata/good/parsecpp/project.ts.result | 21 +++++++++++++ tools/linguist/lupdate/cpp.cpp | 35 ++++++++++++++++++---- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp index 5a7c5a7..5c0f80c 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp @@ -376,6 +376,15 @@ hostNameLabel->setText(tr("Name:")); QString example = tr("Example"); //! [40] +//! [meta data] +//: This is a comment for the translator. +//= qtn_foo_bar +//~ loc-layout_id foo_dialog +//~ loc-blank False +//~ magic-stuff This might mean something magic. +QString text = MyMagicClass::tr("Sim sala bim."); +//! [meta data] + //! [explicit tr context] QString text = QScrollBar::tr("Page up"); //! [explicit tr context] diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 9dc25c7..9e87b3b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2086,6 +2086,34 @@ void QObject::deleteLater() \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17 + \section1 Meta Data + + Additional data can be attached to each translatable message. + The syntax: + + \tt{//= } + + can be used to give the message a unique identifier to support tools + which need it. + The syntax: + + \tt{//~ } + + can be used to attach meta data to the message. The field name should consist + of a domain prefix (possibly the conventional file extension of the file format + the field is inspired by), a hyphen and the actual field name in + underscore-delimited notation. For storage in TS files, the field name together + with the prefix "extra-" will form an XML element name. The field contents will + be XML-escaped, but otherwise appear verbatim as the element's contents. + Any number of unique fields can be added to each message. + + Example: + + \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp meta data + + Meta data appearing right in front of a magic TRANSLATOR comment applies to the + whole TS file. + \section1 Character Encodings You can set the encoding for \a sourceText by calling QTextCodec::setCodecForTr(). diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index df75baf..9fb43fe 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -156,3 +156,22 @@ QT_TRANSLATE_NOOP3_UTF8("scope", "string", "comment") // 4.4 doesn't see this QT_TRANSLATE_NOOP("scope", "string " // this is an interleaved comment "continuation on next line") + + +class TestingTake17 : QObject { + Q_OBJECT + + int function(void) + { + //: random comment + //= this_is_an_id + //~ loc-layout_id fooish_bar + //~ po-ignore_me totally foo-barred nonsense + tr("something cool"); + + tr("less cool"); + + //= another_id + tr("even more cool"); + } +}; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 9386c19..5bd7525 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -239,6 +239,27 @@ + TestingTake17 + + + something cool + random comment + + totally foo-barred nonsense + fooish_bar + + + + less cool + + + + + even more cool + + + + scope diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 09148e7..b1d2d01 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -180,7 +180,8 @@ private: QString transcode(const QString &str, bool utf8); void recordMessage( int line, const QString &context, const QString &text, const QString &comment, - const QString &extracomment, bool utf8, bool plural); + const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, + bool utf8, bool plural); void processInclude(const QString &file, ConversionData &cd, QSet &inclusions); @@ -1299,13 +1300,16 @@ QString CppParser::transcode(const QString &str, bool utf8) void CppParser::recordMessage( int line, const QString &context, const QString &text, const QString &comment, - const QString &extracomment, bool utf8, bool plural) + const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, + bool utf8, bool plural) { TranslatorMessage msg( transcode(context, utf8), transcode(text, utf8), transcode(comment, utf8), QString(), yyFileName, line, QStringList(), TranslatorMessage::Unfinished, plural); msg.setExtraComment(transcode(extracomment.simplified(), utf8)); + msg.setId(msgid); + msg.setExtras(extra); if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit()) msg.setUtf8(true); results->tor->append(msg); @@ -1332,6 +1336,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) QString text; QString comment; QString extracomment; + QString msgid; + TranslatorMessage::ExtraData extra; QString prefix; #ifdef DIAGNOSE_RETRANSLATABILITY QString functionName; @@ -1604,9 +1610,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) prefix.clear(); } - recordMessage(line, context, text, comment, extracomment, utf8, plural); + recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural); } extracomment.clear(); + msgid.clear(); + extra.clear(); break; case Tok_translateUtf8: case Tok_translate: @@ -1655,9 +1663,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; } } - recordMessage(line, context, text, comment, extracomment, utf8, plural); + recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural); } extracomment.clear(); + msgid.clear(); + extra.clear(); break; case Tok_Q_DECLARE_TR_FUNCTIONS: case Tok_Q_OBJECT: @@ -1679,6 +1689,15 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) if (yyComment.startsWith(QLatin1Char(':'))) { yyComment.remove(0, 1); extracomment.append(yyComment); + } else if (yyComment.startsWith(QLatin1Char('='))) { + yyComment.remove(0, 1); + msgid = yyComment.simplified(); + } else if (yyComment.startsWith(QLatin1Char('~'))) { + yyComment.remove(0, 1); + yyComment = yyComment.trimmed(); + int k = yyComment.indexOf(QLatin1Char(' ')); + if (k > -1) + extra.insert(yyComment.left(k), yyComment.mid(k + 1).trimmed()); } else { comment = yyComment.simplified(); if (comment.startsWith(QLatin1String(MagicComment))) { @@ -1689,7 +1708,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } else { context = comment.left(k); comment.remove(0, k + 1); - recordMessage(yyLineNo, context, QString(), comment, extracomment, false, false); + recordMessage(yyLineNo, context, QString(), comment, extracomment, + QString(), TranslatorMessage::ExtraData(), false, false); + extracomment.clear(); + results->tor->setExtras(extra); + extra.clear(); } } } @@ -1739,6 +1762,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) prospectiveContext.clear(); prefix.clear(); extracomment.clear(); + msgid.clear(); + extra.clear(); yyTokColonSeen = false; yyTok = getToken(); break; -- cgit v0.12 From ebfdbff7712e230c19fc2a990632038e3fc79ef2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 13:27:21 +0200 Subject: Doc: indicate that these methods are added in 4.6 --- src/dbus/qdbuspendingcall.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 7807543..0ec1a26 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -410,6 +410,7 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member) #endif /*! + \since 4.6 Creates a QDBusPendingCall object based on the error condition \a error. The resulting pending call object will be in the "finished" state and QDBusPendingReply::isError() will return true. @@ -422,6 +423,7 @@ QDBusPendingCall QDBusPendingCall::fromError(const QDBusError &error) } /*! + \since 4.6 Creates a QDBusPendingCall object based on the message \a msg. The message must be of type QDBusMessage::ErrorMessage or QDBusMessage::ReplyMessage (that is, a message that is typical -- cgit v0.12 From bd3c9e428af5a804fd4631c941fb642c99f6430b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 13:28:17 +0200 Subject: Add a note about this method not being safe in multithreaded contexts --- src/dbus/qdbusconnection.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 6777aa5..14cadd9 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -973,8 +973,15 @@ QDBusConnection QDBusConnection::systemBus() } /*! + \nonreentrant + Returns the connection that sent the signal, if called in a slot activated by QDBus; otherwise it returns 0. + + \note Please avoid this function. This function is not thread-safe, so if + there's any other thread delivering a D-Bus call, this function may return + the wrong connection. In new code, please use QDBusContext::connection() + (see that class for a description on how to use it). */ QDBusConnection QDBusConnection::sender() { -- cgit v0.12 From c5f83fbd89d6bb950fb012c285879f6c88b5bdf3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 16:47:12 +0200 Subject: Add qcore_unix_p.h containing mostly safe versions of Unix functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of these functions are from unistd.h and need to have a loop around the actual call because the calls can be interrupted by a signal delivery. Some special calls (open, dup2, pipe) require an extra flag to support thread-safe execution: the file descriptor must be created from the operating system with the FD_CLOEXEC flag already set. The O_CLOEXEC flag is specified in POSIX.1-2008, but the rest is Linux-specific. Reviewed-By: João Abecasis --- src/corelib/kernel/kernel.pri | 1 + src/corelib/kernel/qcore_unix_p.h | 246 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 src/corelib/kernel/qcore_unix_p.h diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index ecef555..6f28029 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -92,6 +92,7 @@ unix { kernel/qsharedmemory_unix.cpp \ kernel/qsystemsemaphore_unix.cpp HEADERS += \ + kernel/qcore_unix_p.h \ kernel/qcrashhandler_p.h contains(QT_CONFIG, glib) { diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h new file mode 100644 index 0000000..4e3158a --- /dev/null +++ b/src/corelib/kernel/qcore_unix_p.h @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCORE_UNIX_P_H +#define QCORE_UNIX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt code on Unix. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qplatformdefs.h" + +#ifndef Q_OS_UNIX +# error "qcore_unix_p.h included on a non-Unix system" +#endif + +#include +#include +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0209 +# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 +#else +# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0 +#endif + +#define EINTR_LOOP(var, cmd) \ + do { \ + var = cmd; \ + } while (var == -1 && errno == EINTR) + + +// don't call QT_OPEN or ::open +// call qt_safe_open +static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777) +{ +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + register int fd; + EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode)); + + // unknown flags are ignored, so we have no way of verifying if + // O_CLOEXEC was accepted + if (fd != -1) + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + return fd; +} +#undef QT_OPEN +#define QT_OPEN qt_safe_open + +// don't call ::pipe +// call qt_safe_pipe +static inline int qt_safe_pipe(int pipefd[2], int flags = 0) +{ +#ifdef O_CLOEXEC + Q_ASSERT((flags & ~(O_CLOEXEC | O_NONBLOCK)) == 0); +#else + Q_ASSERT((flags & ~O_NONBLOCK) == 0); +#endif + + register int ret; +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC + // use pipe2 + flags |= O_CLOEXEC; + ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR + if (ret == 0 || errno != ENOSYS) + return ret; +#endif + + ret = ::pipe(pipefd); + if (ret == -1) + return -1; + + ::fcntl(pipefd[0], F_SETFD, FD_CLOEXEC); + ::fcntl(pipefd[1], F_SETFD, FD_CLOEXEC); + + // set non-block too? + if (flags & O_NONBLOCK) { + ::fcntl(pipefd[0], F_SETFL, ::fcntl(pipefd[0], F_GETFL) | O_NONBLOCK); + ::fcntl(pipefd[1], F_SETFL, ::fcntl(pipefd[1], F_GETFL) | O_NONBLOCK); + } + + return 0; +} + +// don't call dup or fcntl(F_DUPFD) +static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC) +{ + Q_ASSERT(flags == FD_CLOEXEC || flags == 0); + + register int ret; +#ifdef F_DUPFD_CLOEXEC + // use this fcntl + if (flags & FD_CLOEXEC) { + ret = ::fcntl(oldfd, F_DUPFD_CLOEXEC, atleast); + if (ret != -1 || errno != EINVAL) + return ret; + } +#endif + + // use F_DUPFD + ret = ::fcntl(oldfd, F_DUPFD, atleast); + + if (flags && ret != -1) + ::fcntl(ret, F_SETFD, flags); + return ret; +} + +// don't call dup2 +// call qt_safe_dup2 +static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) +{ + Q_ASSERT(flags == FD_CLOEXEC || flags == 0); + + register int ret; +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC + // use dup3 + if (flags & FD_CLOEXEC) { + EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC)); + if (ret == 0 || errno != ENOSYS) + return ret; + } +#endif + EINTR_LOOP(ret, ::dup2(oldfd, newfd)); + if (ret == -1) + return -1; + + if (flags) + ::fcntl(newfd, F_SETFD, flags); + return 0; +} + +static inline qint64 qt_safe_read(int fd, char *data, qint64 maxlen) +{ + qint64 ret = 0; + EINTR_LOOP(ret, QT_READ(fd, data, maxlen)); + return ret; +} +#undef QT_READ +#define QT_READ qt_safe_read + +static inline qint64 qt_safe_write(int fd, const char *data, qint64 len) +{ + qint64 ret = 0; + EINTR_LOOP(ret, QT_WRITE(fd, data, len)); + return ret; +} +#undef QT_WRITE +#define QT_WRITE qt_safe_write + +static inline int qt_safe_close(int fd) +{ + register int ret; + EINTR_LOOP(ret, QT_CLOSE(fd)); + return ret; +} +#undef QT_CLOSE +#define QT_CLOSE qt_safe_close + +static inline int qt_safe_execve(const char *filename, char *const argv[], + char *const envp[]) +{ + register int ret; + EINTR_LOOP(ret, ::execve(filename, argv, envp)); + return ret; +} + +static inline int qt_safe_execv(const char *path, char *const argv[]) +{ + register int ret; + EINTR_LOOP(ret, ::execv(path, argv)); + return ret; +} + +static inline int qt_safe_execvp(const char *file, char *const argv[]) +{ + register int ret; + EINTR_LOOP(ret, ::execvp(file, argv)); + return ret; +} + +static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) +{ + register int ret; + EINTR_LOOP(ret, ::waitpid(pid, status, options)); + return ret; +} + +Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timeval *tv); + +QT_END_NAMESPACE + +#endif -- cgit v0.12 From 29302d2429ed81f4396155383b602e7bde4edd3b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 17:30:51 +0200 Subject: Port most uses of ::open and QT_OPEN to the safe version. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures that we're calling the open64 version of this function as well as handling the O_CLOEXEC flag and EINTR errors. Reviewed-By: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 5 +++-- src/corelib/io/qfsfileengine_unix.cpp | 18 +++++++----------- src/corelib/io/qresource.cpp | 4 ++++ src/corelib/io/qtemporaryfile.cpp | 17 ++++++----------- src/corelib/kernel/qsharedmemory_unix.cpp | 4 +++- src/corelib/kernel/qtranslator.cpp | 1 + 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index ed42c34..721f52c 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -43,6 +43,7 @@ #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_kqueue_p.h" +#include "qcore_unix_p.h" #include #include @@ -124,9 +125,9 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths, QString path = it.next(); int fd; #if defined(O_EVTONLY) - fd = ::open(QFile::encodeName(path), O_EVTONLY); + fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY); #else - fd = ::open(QFile::encodeName(path), O_RDONLY); + fd = qt_safe_open(QFile::encodeName(path), O_RDONLY); #endif if (fd == -1) { perror("QKqueueFileSystemWatcherEngine::addPaths: open"); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 4743a47..5708e9f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -42,6 +42,7 @@ #include "qplatformdefs.h" #include "qabstractfileengine.h" #include "private/qfsfileengine_p.h" +#include "private/qcore_unix_p.h" #ifndef QT_NO_FSFILEENGINE @@ -90,6 +91,12 @@ static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString & if (flags & QIODevice::ReadOnly) mode += '+'; } + +#if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0207 + // must be glibc >= 2.7 + mode += 'e'; +#endif + return mode; } @@ -118,12 +125,6 @@ static int openModeToOpenFlags(QIODevice::OpenMode mode) oflags |= QT_OPEN_TRUNC; } -#ifdef O_CLOEXEC - // supported on Linux >= 2.6.23; avoids one extra system call - // and avoids a race condition: if another thread forks, we could - // end up leaking a file descriptor... - oflags |= O_CLOEXEC; -#endif return oflags; } @@ -177,11 +178,6 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) } } -#ifndef O_CLOEXEC - // not needed on Linux >= 2.6.23 - setCloseOnExec(fd); // ignore failure -#endif - // Seek to the end when in Append mode. if (flags & QFile::Append) { int ret; diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index fe8764d..a70b92f 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -56,6 +56,10 @@ #include #include "private/qabstractfileengine_p.h" +#ifdef Q_OS_UNIX +# include "private/qcore_unix_p.h" +#endif + //#define DEBUG_RESOURCE_MATCH QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 62ab0c4..2ae4611 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -60,6 +60,10 @@ #include #include +#if defined(Q_OS_UNIX) +# include "private/qcore_unix_p.h" +#endif + #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) # include # if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -72,7 +76,6 @@ # include "qfunctions_wince.h" #endif - QT_BEGIN_NAMESPACE /* @@ -208,8 +211,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) if ((*doopen = QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR # else // CE + // this is Unix if ((*doopen = - open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR + qt_safe_open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR # endif # ifdef QT_LARGEFILE_SUPPORT |QT_OPEN_LARGEFILE @@ -219,18 +223,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) # elif defined(Q_OS_WIN) |O_BINARY # endif -# ifdef O_CLOEXEC - // supported on Linux >= 2.6.23; avoids one extra system call - // and avoids a race condition: if another thread forks, we could - // end up leaking a file descriptor... - |O_CLOEXEC -# endif , 0600)) >= 0) #endif // WIN && !CE { -#if defined(Q_OS_UNIX) && !defined(O_CLOEXEC) - fcntl(*doopen, F_SETFD, FD_CLOEXEC); -#endif return 1; } if (errno != EEXIST) diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index 5299972..04739ff 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -59,6 +59,8 @@ #include #include +#include "private/qcore_unix_p.h" + QT_BEGIN_NAMESPACE QSharedMemoryPrivate::QSharedMemoryPrivate() @@ -153,7 +155,7 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName) if (QFile::exists(fileName)) return 0; - int fd = open(QFile::encodeName(fileName).constData(), + int fd = qt_safe_open(QFile::encodeName(fileName).constData(), O_EXCL | O_CREAT | O_RDWR, 0640); if (-1 == fd) { if (errno == EEXIST) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 64cf16e..4aed2b2 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -58,6 +58,7 @@ #if defined(Q_OS_UNIX) #define QT_USE_MMAP +#include "private/qcore_unix_p.h" #endif // most of the headers below are already included in qplatformdefs.h -- cgit v0.12 From 557258e8f944f0003e9b71e5fe11fcb458db71d8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 18:01:05 +0200 Subject: Make the inotify_init call also use FD_CLOEXEC-safe version of the system call Reviewed-By: ossi --- src/corelib/io/qfilesystemwatcher_inotify.cpp | 40 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 401e545..9d08228 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -44,6 +44,8 @@ #ifndef QT_NO_FILESYSTEMWATCHER +#include "private/qcore_unix_p.h" + #include #include #include @@ -62,62 +64,80 @@ # define __NR_inotify_init 291 # define __NR_inotify_add_watch 292 # define __NR_inotify_rm_watch 293 +# define __NR_inotify_init1 332 #elif defined(__x86_64__) # define __NR_inotify_init 253 # define __NR_inotify_add_watch 254 # define __NR_inotify_rm_watch 255 +# define __NR_inotify_init1 294 #elif defined(__powerpc__) || defined(__powerpc64__) # define __NR_inotify_init 275 # define __NR_inotify_add_watch 276 # define __NR_inotify_rm_watch 277 +# define __NR_inotify_init1 318 #elif defined (__ia64__) # define __NR_inotify_init 1277 # define __NR_inotify_add_watch 1278 # define __NR_inotify_rm_watch 1279 +# define __NR_inotify_init1 1318 #elif defined (__s390__) || defined (__s390x__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 324 #elif defined (__alpha__) # define __NR_inotify_init 444 # define __NR_inotify_add_watch 445 # define __NR_inotify_rm_watch 446 +// no inotify_init1 for the Alpha #elif defined (__sparc__) || defined (__sparc64__) # define __NR_inotify_init 151 # define __NR_inotify_add_watch 152 # define __NR_inotify_rm_watch 156 +# define __NR_inotify_init1 322 #elif defined (__arm__) # define __NR_inotify_init 316 # define __NR_inotify_add_watch 317 # define __NR_inotify_rm_watch 318 +# define __NR_inotify_init1 360 #elif defined (__sh__) # define __NR_inotify_init 290 # define __NR_inotify_add_watch 291 # define __NR_inotify_rm_watch 292 +# define __NR_inotify_init1 332 #elif defined (__sh64__) # define __NR_inotify_init 318 # define __NR_inotify_add_watch 319 # define __NR_inotify_rm_watch 320 +# define __NR_inotify_init1 360 #elif defined (__mips__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 329 #elif defined (__hppa__) # define __NR_inotify_init 269 # define __NR_inotify_add_watch 270 # define __NR_inotify_rm_watch 271 +# define __NR_inotify_init1 314 #elif defined (__avr32__) # define __NR_inotify_init 240 # define __NR_inotify_add_watch 241 # define __NR_inotify_rm_watch 242 +// no inotify_init1 for AVR32 #elif defined (__mc68000__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 328 #else # error "This architecture is not supported. Please talk to qt-bugs@trolltech.com" #endif +#if !defined(IN_CLOEXEC) && defined(O_CLOEXEC) && defined(__NR_inotify_init1) +# define IN_CLOEXEC O_CLOEXEC +#endif + QT_BEGIN_NAMESPACE #ifdef QT_LINUXBASE @@ -140,6 +160,13 @@ static inline int inotify_rm_watch(int fd, __u32 wd) return syscall(__NR_inotify_rm_watch, fd, wd); } +#ifdef IN_CLOEXEC +static inline int inotify_init1(int flags) +{ + return syscall(__NR_inotify_init1, flags); +} +#endif + // the following struct and values are documented in linux/inotify.h extern "C" { @@ -185,9 +212,16 @@ QT_BEGIN_NAMESPACE QInotifyFileSystemWatcherEngine *QInotifyFileSystemWatcherEngine::create() { - int fd = inotify_init(); - if (fd <= 0) - return 0; + register int fd = -1; +#ifdef IN_CLOEXEC + fd = inotify_init1(IN_CLOEXEC); +#endif + if (fd == -1) { + fd = inotify_init(); + if (fd == -1) + return 0; + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + } return new QInotifyFileSystemWatcherEngine(fd); } -- cgit v0.12 From 1d965e189dfd5c9977565ca0c20224806aa7473d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 19:02:32 +0200 Subject: Use the safe versions in these system calls I've just introduced. Reviewed-By: ossi --- src/corelib/io/qfilesystemwatcher_dnotify.cpp | 20 ++++++++++---------- src/corelib/io/qfsfileengine.cpp | 3 +++ src/corelib/io/qfsfileengine_unix.cpp | 2 +- src/corelib/kernel/qeventdispatcher_unix.cpp | 12 +++++++----- src/gui/painting/qpdf.cpp | 20 ++++++++++++-------- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_dnotify.cpp b/src/corelib/io/qfilesystemwatcher_dnotify.cpp index c68af85..6df3746 100644 --- a/src/corelib/io/qfilesystemwatcher_dnotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_dnotify.cpp @@ -59,6 +59,8 @@ #include #include +#include "private/qcore_unix_p.h" + #ifdef QT_LINUXBASE /* LSB doesn't standardize these */ @@ -80,7 +82,7 @@ static void (*qfswd_old_sigio_handler)(int) = 0; static void (*qfswd_old_sigio_action)(int, siginfo_t *, void *) = 0; static void qfswd_sigio_monitor(int signum, siginfo_t *i, void *v) { - ::write(qfswd_fileChanged_pipe[1], &i->si_fd, sizeof(int)); + qt_safe_write(qfswd_fileChanged_pipe[1], reinterpret_cast(&i->si_fd), sizeof(int)); if (qfswd_old_sigio_handler && qfswd_old_sigio_handler != SIG_IGN) qfswd_old_sigio_handler(signum); @@ -121,9 +123,7 @@ QDnotifySignalThread::QDnotifySignalThread() { moveToThread(this); - ::pipe(qfswd_fileChanged_pipe); - ::fcntl(qfswd_fileChanged_pipe[0], F_SETFL, - ::fcntl(qfswd_fileChanged_pipe[0], F_GETFL) | O_NONBLOCK); + qt_safe_pipe(qfswd_fileChanged_pipe, O_NONBLOCK); struct sigaction oldAction; struct sigaction action; @@ -181,7 +181,7 @@ void QDnotifySignalThread::run() void QDnotifySignalThread::readFromDnotify() { int fd; - int readrv = ::read(qfswd_fileChanged_pipe[0], &fd,sizeof(int)); + int readrv = qt_safe_read(qfswd_fileChanged_pipe[0], reinterpret_cast(&fd), sizeof(int)); // Only expect EAGAIN or EINTR. Other errors are assumed to be impossible. if(readrv != -1) { Q_ASSERT(readrv == sizeof(int)); @@ -207,9 +207,9 @@ QDnotifyFileSystemWatcherEngine::~QDnotifyFileSystemWatcherEngine() for(QHash::ConstIterator iter = fdToDirectory.constBegin(); iter != fdToDirectory.constEnd(); ++iter) { - ::close(iter->fd); + qt_safe_close(iter->fd); if(iter->parentFd) - ::close(iter->parentFd); + qt_safe_close(iter->parentFd); } } @@ -353,7 +353,7 @@ QStringList QDnotifyFileSystemWatcherEngine::removePaths(const QStringList &path if(!directory.isMonitored && directory.files.isEmpty()) { // No longer needed - ::close(directory.fd); + qt_safe_close(directory.fd); pathToFD.remove(directory.path); fdToDirectory.remove(fd); } @@ -419,9 +419,9 @@ void QDnotifyFileSystemWatcherEngine::refresh(int fd) } if(!directory.isMonitored && directory.files.isEmpty()) { - ::close(directory.fd); + qt_safe_close(directory.fd); if(directory.parentFd) { - ::close(directory.parentFd); + qt_safe_close(directory.parentFd); parentToFD.remove(directory.parentFd); } fdToDirectory.erase(iter); diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index e32b818..beafe72 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -50,6 +50,9 @@ #if !defined(Q_OS_WINCE) #include #endif +#if defined(Q_OS_UNIX) +#include "private/qcore_unix_p.h" +#endif #include QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 5708e9f..47e3db0 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -458,7 +458,7 @@ bool QFSFileEngine::caseSensitive() const bool QFSFileEngine::setCurrentPath(const QString &path) { int r; - r = ::chdir(QFile::encodeName(path)); + r = QT_CHDIR(QFile::encodeName(path)); return r >= 0; } diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 161398e..0eeea04 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -49,6 +49,7 @@ #include "qeventdispatcher_unix_p.h" #include #include +#include #include #include @@ -76,6 +77,7 @@ static void signalHandler(int sig) } +#ifdef Q_OS_INTEGRITY static void initThreadPipeFD(int fd) { int ret = fcntl(fd, F_SETFD, FD_CLOEXEC); @@ -90,7 +92,7 @@ static void initThreadPipeFD(int fd) if (ret == -1) perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe"); } - +#endif QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() { @@ -102,13 +104,13 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair"); -#else - if (pipe(thread_pipe) == -1) - perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); -#endif initThreadPipeFD(thread_pipe[0]); initThreadPipeFD(thread_pipe[1]); +#else + if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) + perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); +#endif sn_highest = -1; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index a6ecd4e..178d519 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -48,6 +48,10 @@ #include "qprinterinfo.h" #include +#ifdef Q_OS_UNIX +#include "private/qcore_unix_p.h" // overrides QT_OPEN +#endif + QT_BEGIN_NAMESPACE extern int qt_defaultDpi(); @@ -1647,7 +1651,7 @@ static void closeAllOpenFds() #endif // leave stdin/out/err untouched while(--i > 2) - ::close(i); + QT_CLOSE(i); } #endif @@ -1681,7 +1685,7 @@ bool QPdfBaseEnginePrivate::openPrintDevice() if (!printerName.isEmpty()) pr = printerName; int fds[2]; - if (pipe(fds) != 0) { + if (qt_safe_pipe(fds) != 0) { qWarning("QPdfPrinter: Could not open pipe to print"); return false; } @@ -1700,9 +1704,9 @@ bool QPdfBaseEnginePrivate::openPrintDevice() (void)execlp("true", "true", (char *)0); (void)execl("/bin/true", "true", (char *)0); (void)execl("/usr/bin/true", "true", (char *)0); - ::exit(0); + ::_exit(0); } - dup2(fds[0], 0); + qt_safe_dup2(fds[0], 0, 0); closeAllOpenFds(); @@ -1769,14 +1773,14 @@ bool QPdfBaseEnginePrivate::openPrintDevice() // wait for a second so the parent process (the // child of the GUI process) has exited. then // exit. - ::close(0); + QT_CLOSE(0); (void)::sleep(1); - ::exit(0); + ::_exit(0); } // parent process - ::close(fds[0]); + QT_CLOSE(fds[0]); fd = fds[1]; - (void)::waitpid(pid, 0, 0); + (void)qt_safe_waitpid(pid, 0, 0); if (fd < 0) return false; -- cgit v0.12 From de05f9a40e41deb79daf5c4935b2645d70d7f322 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 19:04:32 +0200 Subject: Port QProcess to use the EINTR-safe and thread-safe functions Reviewed-By: ossi --- src/corelib/io/qprocess_unix.cpp | 213 ++++++++++++--------------------------- 1 file changed, 65 insertions(+), 148 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 49869a4..c81da44 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -84,6 +84,7 @@ QT_END_NAMESPACE #include "qprocess.h" #include "qprocess_p.h" +#include "private/qcore_unix_p.h" #ifdef Q_OS_MAC #include @@ -114,78 +115,11 @@ static inline char *strdup(const char *data) } #endif -static qint64 qt_native_read(int fd, char *data, qint64 maxlen) -{ - qint64 ret = 0; - do { - ret = ::read(fd, data, maxlen); - } while (ret == -1 && errno == EINTR); - return ret; -} - -static qint64 qt_native_write(int fd, const char *data, qint64 len) -{ - qint64 ret = 0; - do { - ret = ::write(fd, data, len); - } while (ret == -1 && errno == EINTR); - return ret; -} - -static void qt_native_close(int fd) -{ - int ret; - do { - ret = ::close(fd); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_dup2(int oldfd, int newfd) -{ - int ret; - do { - ret = ::dup2(oldfd, newfd); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_chdir(const char *path) -{ - int ret; - do { - ret = ::chdir(path); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execve(const char *filename, char *const argv[], - char *const envp[]) -{ - int ret; - do { - ret = ::execve(filename, argv, envp); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execv(const char *path, char *const argv[]) -{ - int ret; - do { - ret = ::execv(path, argv); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execvp(const char *file, char *const argv[]) -{ - int ret; - do { - ret = ::execvp(file, argv); - } while (ret == -1 && errno == EINTR); -} - static int qt_qprocess_deadChild_pipe[2]; static void (*qt_sa_old_sigchld_handler)(int) = 0; static void qt_sa_sigchld_handler(int signum) { - qt_native_write(qt_qprocess_deadChild_pipe[1], "", 1); + qt_safe_write(qt_qprocess_deadChild_pipe[1], "", 1); #if defined (QPROCESS_DEBUG) fprintf(stderr, "*** SIGCHLD\n"); #endif @@ -231,13 +165,7 @@ QProcessManager::QProcessManager() // initialize the dead child pipe and make it non-blocking. in the // extremely unlikely event that the pipe fills up, we do not under any // circumstances want to block. - ::pipe(qt_qprocess_deadChild_pipe); - ::fcntl(qt_qprocess_deadChild_pipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(qt_qprocess_deadChild_pipe[1], F_SETFD, FD_CLOEXEC); - ::fcntl(qt_qprocess_deadChild_pipe[0], F_SETFL, - ::fcntl(qt_qprocess_deadChild_pipe[0], F_GETFL) | O_NONBLOCK); - ::fcntl(qt_qprocess_deadChild_pipe[1], F_SETFL, - ::fcntl(qt_qprocess_deadChild_pipe[1], F_GETFL) | O_NONBLOCK); + qt_safe_pipe(qt_qprocess_deadChild_pipe, O_NONBLOCK); // set up the SIGCHLD handler, which writes a single byte to the dead // child pipe every time a child dies. @@ -254,13 +182,13 @@ QProcessManager::QProcessManager() QProcessManager::~QProcessManager() { // notify the thread that we're shutting down. - qt_native_write(qt_qprocess_deadChild_pipe[1], "@", 1); - qt_native_close(qt_qprocess_deadChild_pipe[1]); + qt_safe_write(qt_qprocess_deadChild_pipe[1], "@", 1); + qt_safe_close(qt_qprocess_deadChild_pipe[1]); wait(); // on certain unixes, closing the reading end of the pipe will cause // select in run() to block forever, rather than return with EBADF. - qt_native_close(qt_qprocess_deadChild_pipe[0]); + qt_safe_close(qt_qprocess_deadChild_pipe[0]); qt_qprocess_deadChild_pipe[0] = -1; qt_qprocess_deadChild_pipe[1] = -1; @@ -304,7 +232,7 @@ void QProcessManager::run() // signals may have been delivered in the meantime, to avoid race // conditions. char c; - if (qt_native_read(qt_qprocess_deadChild_pipe[0], &c, 1) < 0 || c == '@') + if (qt_safe_read(qt_qprocess_deadChild_pipe[0], &c, 1) < 0 || c == '@') break; // catch any and all children that we can. @@ -323,7 +251,7 @@ void QProcessManager::catchDeadChildren() // notify all children that they may have died. they need to run // waitpid() in their own thread. QProcessInfo *info = it.value(); - qt_native_write(info->deathPipe, "", 1); + qt_safe_write(info->deathPipe, "", 1); #if defined (QPROCESS_DEBUG) qDebug() << "QProcessManager::run() sending death notice to" << info->process; @@ -382,25 +310,23 @@ void QProcessManager::unlock() static void qt_create_pipe(int *pipe) { if (pipe[0] != -1) - qt_native_close(pipe[0]); + qt_safe_close(pipe[0]); if (pipe[1] != -1) - qt_native_close(pipe[1]); - if (::pipe(pipe) != 0) { + qt_safe_close(pipe[1]); + if (qt_safe_pipe(pipe) != 0) { qWarning("QProcessPrivate::createPipe: Cannot create pipe %p: %s", pipe, qPrintable(qt_error_string(errno))); } - ::fcntl(pipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(pipe[1], F_SETFD, FD_CLOEXEC); } void QProcessPrivate::destroyPipe(int *pipe) { if (pipe[1] != -1) { - qt_native_close(pipe[1]); + qt_safe_close(pipe[1]); pipe[1] = -1; } if (pipe[0] != -1) { - qt_native_close(pipe[0]); + qt_safe_close(pipe[0]); pipe[0] = -1; } } @@ -453,7 +379,7 @@ bool QProcessPrivate::createChannel(Channel &channel) if (&channel == &stdinChannel) { // try to open in read-only mode channel.pipe[1] = -1; - if ( (channel.pipe[0] = QT_OPEN(fname, O_RDONLY)) != -1) + if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1) return true; // success q->setErrorString(QProcess::tr("Could not open input redirection for reading")); @@ -465,7 +391,7 @@ bool QProcessPrivate::createChannel(Channel &channel) mode |= O_TRUNC; channel.pipe[0] = -1; - if ( (channel.pipe[1] = QT_OPEN(fname, mode, 0666)) != -1) + if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1) return true; // success q->setErrorString(QProcess::tr("Could not open output redirection for writing")); @@ -586,8 +512,6 @@ void QProcessPrivate::startProcess() return; qt_create_pipe(childStartedPipe); qt_create_pipe(deathPipe); - ::fcntl(deathPipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(deathPipe[1], F_SETFD, FD_CLOEXEC); if (threadData->eventDispatcher) { startupSocketNotifier = new QSocketNotifier(childStartedPipe[0], @@ -728,11 +652,11 @@ void QProcessPrivate::startProcess() // parent // close the ends we don't use and make all pipes non-blocking ::fcntl(deathPipe[0], F_SETFL, ::fcntl(deathPipe[0], F_GETFL) | O_NONBLOCK); - qt_native_close(childStartedPipe[1]); + qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; if (stdinChannel.pipe[0] != -1) { - qt_native_close(stdinChannel.pipe[0]); + qt_safe_close(stdinChannel.pipe[0]); stdinChannel.pipe[0] = -1; } @@ -740,7 +664,7 @@ void QProcessPrivate::startProcess() ::fcntl(stdinChannel.pipe[1], F_SETFL, ::fcntl(stdinChannel.pipe[1], F_GETFL) | O_NONBLOCK); if (stdoutChannel.pipe[1] != -1) { - qt_native_close(stdoutChannel.pipe[1]); + qt_safe_close(stdoutChannel.pipe[1]); stdoutChannel.pipe[1] = -1; } @@ -748,7 +672,7 @@ void QProcessPrivate::startProcess() ::fcntl(stdoutChannel.pipe[0], F_SETFL, ::fcntl(stdoutChannel.pipe[0], F_GETFL) | O_NONBLOCK); if (stderrChannel.pipe[1] != -1) { - qt_native_close(stderrChannel.pipe[1]); + qt_safe_close(stderrChannel.pipe[1]); stderrChannel.pipe[1] = -1; } if (stderrChannel.pipe[0] != -1) @@ -761,35 +685,34 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv Q_Q(QProcess); - // copy the stdin socket - qt_native_dup2(stdinChannel.pipe[0], fileno(stdin)); + // copy the stdin socket (without closing on exec) + qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0); // copy the stdout and stderr if asked to if (processChannelMode != QProcess::ForwardedChannels) { - qt_native_dup2(stdoutChannel.pipe[1], fileno(stdout)); + qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0); // merge stdout and stderr if asked to if (processChannelMode == QProcess::MergedChannels) { - qt_native_dup2(fileno(stdout), fileno(stderr)); + qt_safe_dup2(fileno(stdout), fileno(stderr), 0); } else { - qt_native_dup2(stderrChannel.pipe[1], fileno(stderr)); + qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0); } } // make sure this fd is closed if execvp() succeeds - qt_native_close(childStartedPipe[0]); - ::fcntl(childStartedPipe[1], F_SETFD, FD_CLOEXEC); + qt_safe_close(childStartedPipe[0]); // enter the working directory if (workingDir) - qt_native_chdir(workingDir); + QT_CHDIR(workingDir); // this is a virtual call, and it base behavior is to do nothing. q->setupChildProcess(); // execute the process if (!envp) { - qt_native_execvp(argv[0], argv); + qt_safe_execvp(argv[0], argv); } else { if (path) { char **arg = path; @@ -798,14 +721,14 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() searching / starting %s\n", argv[0]); #endif - qt_native_execve(argv[0], argv, envp); + qt_safe_execve(argv[0], argv, envp); ++arg; } } else { #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() starting %s\n", argv[0]); #endif - qt_native_execve(argv[0], argv, envp); + qt_safe_execve(argv[0], argv, envp); } } @@ -813,21 +736,21 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() failed, notifying parent process\n"); #endif - qt_native_write(childStartedPipe[1], "", 1); - qt_native_close(childStartedPipe[1]); + qt_safe_write(childStartedPipe[1], "", 1); + qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; } bool QProcessPrivate::processStarted() { char c; - int i = qt_native_read(childStartedPipe[0], &c, 1); + int i = qt_safe_read(childStartedPipe[0], &c, 1); if (startupSocketNotifier) { startupSocketNotifier->setEnabled(false); startupSocketNotifier->deleteLater(); startupSocketNotifier = 0; } - qt_native_close(childStartedPipe[0]); + qt_safe_close(childStartedPipe[0]); childStartedPipe[0] = -1; #if defined (QPROCESS_DEBUG) @@ -862,7 +785,7 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) { - qint64 bytesRead = qt_native_read(stdoutChannel.pipe[0], data, maxlen); + qint64 bytesRead = qt_safe_read(stdoutChannel.pipe[0], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::readFromStdout(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); @@ -872,7 +795,7 @@ qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen) { - qint64 bytesRead = qt_native_read(stderrChannel.pipe[0], data, maxlen); + qint64 bytesRead = qt_safe_read(stderrChannel.pipe[0], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::readFromStderr(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); @@ -896,7 +819,7 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) { qt_ignore_sigpipe(); - qint64 written = qt_native_write(stdinChannel.pipe[1], data, maxlen); + qint64 written = qt_safe_write(stdinChannel.pipe[1], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written); @@ -922,7 +845,7 @@ void QProcessPrivate::killProcess() ::kill(pid_t(pid), SIGKILL); } -static int qt_native_select(fd_set *fdread, fd_set *fdwrite, int timeout) +static int qt_safe_select(fd_set *fdread, fd_set *fdwrite, int timeout) { struct timeval tv; tv.tv_sec = timeout / 1000; @@ -962,7 +885,7 @@ bool QProcessPrivate::waitForStarted(int msecs) FD_SET(childStartedPipe[0], &fds); int ret; do { - ret = qt_native_select(&fds, 0, msecs); + ret = qt_safe_select(&fds, 0, msecs); } while (ret < 0 && errno == EINTR); if (ret == 0) { processError = QProcess::Timedout; @@ -1011,7 +934,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1084,7 +1007,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1152,7 +1075,7 @@ bool QProcessPrivate::waitForFinished(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1193,7 +1116,7 @@ bool QProcessPrivate::waitForWrite(int msecs) int ret; do { - ret = qt_native_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; + ret = qt_safe_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } while (ret < 0 && errno == EINTR); return ret == 1; } @@ -1210,15 +1133,11 @@ bool QProcessPrivate::waitForDeadChild() // read a byte from the death pipe char c; - qt_native_read(deathPipe[0], &c, 1); + qt_safe_read(deathPipe[0], &c, 1); // check if our process is dead int exitStatus; - pid_t waitResult = 0; - do { - waitResult = waitpid(pid_t(pid), &exitStatus, WNOHANG); - } while ((waitResult == -1 && errno == EINTR)); - if (waitResult > 0) { + if (qt_safe_waitpid(pid_t(pid), &exitStatus, WNOHANG) > 0) { processManager()->remove(q); crashed = !WIFEXITED(exitStatus); exitCode = WEXITSTATUS(exitStatus); @@ -1262,16 +1181,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a ::setsid(); - qt_native_close(startedPipe[0]); - qt_native_close(pidPipe[0]); + qt_safe_close(startedPipe[0]); + qt_safe_close(pidPipe[0]); pid_t doubleForkPid = qt_fork(); if (doubleForkPid == 0) { - ::fcntl(startedPipe[1], F_SETFD, FD_CLOEXEC); - qt_native_close(pidPipe[1]); + qt_safe_close(pidPipe[1]); if (!encodedWorkingDirectory.isEmpty()) - qt_native_chdir(encodedWorkingDirectory.constData()); + QT_CHDIR(encodedWorkingDirectory.constData()); char **argv = new char *[arguments.size() + 2]; for (int i = 0; i < arguments.size(); ++i) { @@ -1292,13 +1210,13 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a if (!tmp.endsWith('/')) tmp += '/'; tmp += QFile::encodeName(program); argv[0] = tmp.data(); - qt_native_execv(argv[0], argv); + qt_safe_execv(argv[0], argv); } } } else { QByteArray tmp = QFile::encodeName(program); argv[0] = tmp.data(); - qt_native_execv(argv[0], argv); + qt_safe_execv(argv[0], argv); } struct sigaction noaction; @@ -1308,8 +1226,8 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a // '\1' means execv failed char c = '\1'; - qt_native_write(startedPipe[1], &c, 1); - qt_native_close(startedPipe[1]); + qt_safe_write(startedPipe[1], &c, 1); + qt_safe_close(startedPipe[1]); ::_exit(1); } else if (doubleForkPid == -1) { struct sigaction noaction; @@ -1319,40 +1237,39 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a // '\2' means internal error char c = '\2'; - qt_native_write(startedPipe[1], &c, 1); + qt_safe_write(startedPipe[1], &c, 1); } - qt_native_close(startedPipe[1]); - qt_native_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t)); - qt_native_chdir("/"); + qt_safe_close(startedPipe[1]); + qt_safe_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t)); + QT_CHDIR("/"); ::_exit(1); } - qt_native_close(startedPipe[1]); - qt_native_close(pidPipe[1]); + qt_safe_close(startedPipe[1]); + qt_safe_close(pidPipe[1]); if (childPid == -1) { - qt_native_close(startedPipe[0]); - qt_native_close(pidPipe[0]); + qt_safe_close(startedPipe[0]); + qt_safe_close(pidPipe[0]); return false; } char reply = '\0'; - int startResult = qt_native_read(startedPipe[0], &reply, 1); + int startResult = qt_safe_read(startedPipe[0], &reply, 1); int result; - qt_native_close(startedPipe[0]); - while (::waitpid(childPid, &result, 0) == -1 && errno == EINTR) - { } + qt_safe_close(startedPipe[0]); + qt_safe_waitpid(childPid, &result, 0); bool success = (startResult != -1 && reply == '\0'); if (success && pid) { pid_t actualPid = 0; - if (qt_native_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) { + if (qt_safe_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) { *pid = actualPid; } else { *pid = 0; } } - qt_native_close(pidPipe[0]); + qt_safe_close(pidPipe[0]); return success; } -- cgit v0.12 From 27fc6ef5dfb7d58af778de162298fdc4da34459f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 20:54:17 +0200 Subject: Add a properly-safe version of select(2). Do the timeout handling the right and cross-platform way. The code that was in QProcess worked only on Linux, where the kernel sets the remainder in the returned timeval structure. Reviewed-By: ossi --- src/corelib/io/qprocess_unix.cpp | 80 ++++++++-------- src/corelib/kernel/kernel.pri | 1 + src/corelib/kernel/qcore_unix.cpp | 121 ++++++++++++++++++++++++ src/network/socket/qnativesocketengine_unix.cpp | 53 ++--------- 4 files changed, 165 insertions(+), 90 deletions(-) create mode 100644 src/corelib/kernel/qcore_unix.cpp diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index c81da44..fafce07 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -128,6 +128,13 @@ static void qt_sa_sigchld_handler(int signum) qt_sa_old_sigchld_handler(signum); } +static inline void add_fd(int &nfds, int fd, fd_set *fdset) +{ + FD_SET(fd, fdset); + if ((fd) > nfds) + nfds = fd; +} + struct QProcessInfo { QProcess *process; int deathPipe; @@ -845,17 +852,15 @@ void QProcessPrivate::killProcess() ::kill(pid_t(pid), SIGKILL); } -static int qt_safe_select(fd_set *fdread, fd_set *fdwrite, int timeout) +static int select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) { + if (timeout < 0) + return qt_safe_select(nfds, fdread, fdwrite, 0, 0); + struct timeval tv; tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - - int ret; - do { - ret = select(FD_SETSIZE, fdread, fdwrite, 0, timeout < 0 ? 0 : &tv); - } while (ret < 0 && (errno == EINTR)); - return ret; + return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); } /* @@ -883,11 +888,7 @@ bool QProcessPrivate::waitForStarted(int msecs) fd_set fds; FD_ZERO(&fds); FD_SET(childStartedPipe[0], &fds); - int ret; - do { - ret = qt_safe_select(&fds, 0, msecs); - } while (ret < 0 && errno == EINTR); - if (ret == 0) { + if (select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { processError = QProcess::Timedout; q->setErrorString(QProcess::tr("Process operation timed out")); #if defined (QPROCESS_DEBUG) @@ -920,24 +921,23 @@ bool QProcessPrivate::waitForReadyRead(int msecs) FD_ZERO(&fdread); FD_ZERO(&fdwrite); + int nfds = deathPipe[0]; + FD_SET(deathPipe[0], &fdread); + if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); - - FD_SET(deathPipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } if (ret == 0) { @@ -993,24 +993,24 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) FD_ZERO(&fdread); FD_ZERO(&fdwrite); + int nfds = deathPipe[0]; + FD_SET(deathPipe[0], &fdread); + if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); - FD_SET(deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } @@ -1056,29 +1056,28 @@ bool QProcessPrivate::waitForFinished(int msecs) forever { fd_set fdread; fd_set fdwrite; + int nfds = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); if (processState == QProcess::Running) - FD_SET(deathPipe[0], &fdread); + add_fd(nfds, deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } if (ret == 0) { @@ -1113,12 +1112,7 @@ bool QProcessPrivate::waitForWrite(int msecs) fd_set fdwrite; FD_ZERO(&fdwrite); FD_SET(stdinChannel.pipe[1], &fdwrite); - - int ret; - do { - ret = qt_safe_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; - } while (ret < 0 && errno == EINTR); - return ret == 1; + return select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } void QProcessPrivate::findExitCode() diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 6f28029..8759578 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -88,6 +88,7 @@ mac { unix { SOURCES += \ + kernel/qcore_unix.cpp \ kernel/qcrashhandler.cpp \ kernel/qsharedmemory_unix.cpp \ kernel/qsystemsemaphore_unix.cpp diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp new file mode 100644 index 0000000..ffaf958 --- /dev/null +++ b/src/corelib/kernel/qcore_unix.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcore_unix_p.h" + +#include +#include +#include + +#include "qeventdispatcher_unix_p.h" // for the timeval operators + +#if !defined(QT_NO_CLOCK_MONOTONIC) +# if defined(QT_BOOTSTRAPPED) +# define QT_NO_CLOCK_MONOTONIC +# endif +#endif + +QT_BEGIN_NAMESPACE + +static inline timeval gettime() +{ + timeval tv; +#ifndef QT_NO_CLOCK_MONOTONIC + // use the monotonic clock + static volatile bool monotonicClockDisabled = false; + struct timespec ts; + if (!monotonicClockDisabled) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) { + monotonicClockDisabled = true; + } else { + tv.tv_sec = ts.tv_sec; + tv.tv_usec = ts.tv_nsec / 1000; + return tv; + } + } +#endif + // use gettimeofday + ::gettimeofday(&tv, 0); + return tv; +} + +static inline bool time_update(struct timeval *tv, const struct timeval &start, + const struct timeval &timeout) +{ + struct timeval now = gettime(); + if (now < start) { + // clock reset, give up + return false; + } + + *tv = timeout + start - now; + return true; +} + +int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timeval *orig_timeout) +{ + if (!orig_timeout) { + // no timeout -> block forever + register int ret; + EINTR_LOOP(ret, select(nfds, fdread, fdwrite, fdexcept, 0)); + return ret; + } + + timeval start = gettime(); + timeval timeout = *orig_timeout; + + // loop and recalculate the timeout as needed + int ret; + forever { + ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeout); + if (ret != -1 || errno != EINTR) + return ret; + + // recalculate the timeout + if (!time_update(&timeout, start, *orig_timeout)) { + // clock reset, fake timeout error + return 0; + } + } +} + +QT_END_NAMESPACE diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index b130a9b..6eafe05 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -42,6 +42,7 @@ //#define QNATIVESOCKETENGINE_DEBUG #include "qnativesocketengine_p.h" +#include "private/qcore_unix_p.h" #include "qiodevice.h" #include "qhostaddress.h" #include "qvarlengtharray.h" @@ -833,33 +834,11 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) co tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - QTime timer; - timer.start(); - int retval; - do { - if (selectForRead) - retval = select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); - else - retval = select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); - - if (retval != -1 || errno != EINTR) - break; - - if (timeout > 0) { - // recalculate the timeout - int t = timeout - timer.elapsed(); - if (t < 0) { - // oops, timeout turned negative? - retval = -1; - break; - } - - tv.tv_sec = t / 1000; - tv.tv_usec = (t % 1000) * 1000; - } - } while (true); - + if (selectForRead) + retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); + else + retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); return retval; } @@ -880,28 +859,8 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - QTime timer; - timer.start(); - int ret; - do { - ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); - if (ret != -1 || errno != EINTR) - break; - - if (timeout > 0) { - // recalculate the timeout - int t = timeout - timer.elapsed(); - if (t < 0) { - // oops, timeout turned negative? - ret = -1; - break; - } - - tv.tv_sec = t / 1000; - tv.tv_usec = (t % 1000) * 1000; - } - } while (true); + ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); if (ret <= 0) return ret; -- cgit v0.12 From cad1bf4c902899ec1a8277d46272afa23fc2b34b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Apr 2009 11:55:02 +0200 Subject: Port gui/embedded to the EINTR-safe functions. I think I found two file descriptor that aren't closed. One seems like a genuine leak, the other seems intentional. Reviewed-By: ossi --- src/gui/embedded/qkbdlinuxinput_qws.cpp | 1 + src/gui/embedded/qkbdsl5000_qws.cpp | 6 +++-- src/gui/embedded/qkbdtty_qws.cpp | 4 ++++ src/gui/embedded/qkbdvfb_qws.cpp | 9 ++++---- src/gui/embedded/qkbdvr41xx_qws.cpp | 7 +++--- src/gui/embedded/qkbdyopy_qws.cpp | 10 +++++---- src/gui/embedded/qlock.cpp | 6 +++-- src/gui/embedded/qmousebus_qws.cpp | 11 +++++----- src/gui/embedded/qmouselinuxtp_qws.cpp | 7 +++--- src/gui/embedded/qmousepc_qws.cpp | 39 +++++++++++++++++---------------- src/gui/embedded/qmousevfb_qws.cpp | 9 ++++---- src/gui/embedded/qmousevr41xx_qws.cpp | 11 +++++----- src/gui/embedded/qmouseyopy_qws.cpp | 7 +++--- src/gui/embedded/qscreenlinuxfb_qws.cpp | 20 ++++++++++------- src/gui/embedded/qsoundqss_qws.cpp | 9 ++++---- src/gui/embedded/qtransportauth_qws.cpp | 7 +++--- src/gui/embedded/qunixsocket.cpp | 18 ++++++++++----- src/gui/text/qfontdatabase_qws.cpp | 5 +++-- src/gui/text/qfontengine_qpf.cpp | 11 +++++----- src/gui/text/qfontengine_qws.cpp | 5 +++-- 20 files changed, 118 insertions(+), 84 deletions(-) diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp index d5720f7..e552731 100644 --- a/src/gui/embedded/qkbdlinuxinput_qws.cpp +++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp @@ -47,6 +47,7 @@ #include #include +#include // overrides QT_OPEN #include #include diff --git a/src/gui/embedded/qkbdsl5000_qws.cpp b/src/gui/embedded/qkbdsl5000_qws.cpp index 36cb903..cf82c10 100644 --- a/src/gui/embedded/qkbdsl5000_qws.cpp +++ b/src/gui/embedded/qkbdsl5000_qws.cpp @@ -51,6 +51,8 @@ #include "qnamespace.h" #include "qtimer.h" +#include // overrides QT_OPEN + #include #include #include @@ -207,14 +209,14 @@ QWSSL5000KeyboardHandler::QWSSL5000KeyboardHandler(const QString &device) numLock = false; sharp_kbdctl_modifstat st; - int dev = ::open(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR); + int dev = QT_OPEN(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR); if (dev >= 0) { memset(&st, 0, sizeof(st)); st.which = 3; int ret = ioctl(dev, SHARP_KBDCTL_GETMODIFSTAT, (char*)&st); if(!ret) numLock = (bool)st.stat; - ::close(dev); + QT_CLOSE(dev); } } diff --git a/src/gui/embedded/qkbdtty_qws.cpp b/src/gui/embedded/qkbdtty_qws.cpp index 33777eb..8c1e79b 100644 --- a/src/gui/embedded/qkbdtty_qws.cpp +++ b/src/gui/embedded/qkbdtty_qws.cpp @@ -47,6 +47,7 @@ #include #include +#include // overrides QT_OPEN #include #include @@ -213,6 +214,9 @@ QWSTtyKbPrivate::~QWSTtyKbPrivate() ::ioctl(m_tty_fd, KDSKBMODE, m_originalKbdMode); #endif tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr); + + // we're leaking m_tty_fd here? + //QT_CLOSE(m_tty_fd); } } diff --git a/src/gui/embedded/qkbdvfb_qws.cpp b/src/gui/embedded/qkbdvfb_qws.cpp index 082aac1..a44183b 100644 --- a/src/gui/embedded/qkbdvfb_qws.cpp +++ b/src/gui/embedded/qkbdvfb_qws.cpp @@ -55,6 +55,7 @@ #include #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -69,13 +70,13 @@ QVFbKeyboardHandler::QVFbKeyboardHandler(const QString &device) kbdBufferLen = sizeof(QVFbKeyData) * 5; kbdBuffer = new unsigned char [kbdBufferLen]; - if ((kbdFD = open(terminalName.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { + if ((kbdFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { qWarning("Cannot open %s (%s)", terminalName.toLatin1().constData(), strerror(errno)); } else { // Clear pending input char buf[2]; - while (read(kbdFD, buf, 1) > 0) { } + while (QT_READ(kbdFD, buf, 1) > 0) { } notifier = new QSocketNotifier(kbdFD, QSocketNotifier::Read, this); connect(notifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData())); @@ -85,7 +86,7 @@ QVFbKeyboardHandler::QVFbKeyboardHandler(const QString &device) QVFbKeyboardHandler::~QVFbKeyboardHandler() { if (kbdFD >= 0) - close(kbdFD); + QT_CLOSE(kbdFD); delete [] kbdBuffer; } @@ -94,7 +95,7 @@ void QVFbKeyboardHandler::readKeyboardData() { int n; do { - n = read(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); + n = QT_READ(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); if (n > 0) kbdIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qkbdvr41xx_qws.cpp b/src/gui/embedded/qkbdvr41xx_qws.cpp index 03c2a67..6d8299b 100644 --- a/src/gui/embedded/qkbdvr41xx_qws.cpp +++ b/src/gui/embedded/qkbdvr41xx_qws.cpp @@ -52,6 +52,7 @@ #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -95,7 +96,7 @@ QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QStrin buttonFD = -1; notifier = 0; - buttonFD = open(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);; + buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);; if (buttonFD < 0) { qWarning("Cannot open %s\n", qPrintable(terminalName)); return; @@ -115,7 +116,7 @@ QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QStrin QWSVr41xxKbPrivate::~QWSVr41xxKbPrivate() { if (buttonFD > 0) { - ::close(buttonFD); + QT_CLOSE(buttonFD); buttonFD = -1; } delete notifier; @@ -127,7 +128,7 @@ void QWSVr41xxKbPrivate::readKeyboardData() { int n = 0; do { - n = read(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); + n = QT_READ(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); if (n > 0) kbdIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qkbdyopy_qws.cpp b/src/gui/embedded/qkbdyopy_qws.cpp index 5c9d28d..edb732c 100644 --- a/src/gui/embedded/qkbdyopy_qws.cpp +++ b/src/gui/embedded/qkbdyopy_qws.cpp @@ -60,6 +60,8 @@ #include #include +#include // overrides QT_OPEN + extern "C" { int getpgid(int); } @@ -105,7 +107,7 @@ QWSYopyKbPrivate::QWSYopyKbPrivate(QWSYopyKeyboardHandler *h, const QString &dev buttonFD = -1; notifier = 0; - buttonFD = ::open(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0); + buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0); if (buttonFD < 0) { qWarning("Cannot open %s\n", qPrintable(terminalName)); return; @@ -177,10 +179,10 @@ void QWSYopyKbPrivate::readKeyboardData() case 40: k=Qt::Key_Up; break; // prev case 45: k=Qt::Key_Down; break; // next case 35: if(!press) { - fd = open("/proc/sys/pm/sleep",O_RDWR,0); + fd = QT_OPEN("/proc/sys/pm/sleep",O_RDWR,0); if(fd >= 0) { - write(fd,&c,sizeof(c)); - close(fd); + QT_WRITE(fd,&c,sizeof(c)); + QT_CLOSE(fd); // // Updates all widgets. // diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index c23608f..305832c 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlo